๐ JAVA 05 - Spring์ ๊ฐ์ฒด๋ฅผ ์ด๋ป๊ฒ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋๊ฐ
Spring Bean Lifecycle Deep Dive
ํ์ต ๋ชฉํ
์ด๋ฒ ์ฃผ์ ์ ํต์ฌ์ ๋จ์ํ:
โSpring์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋คโ
์์ค์ด ์๋๋ค.
์ค๋ฌด์์๋ ๋ฐ๋์ ์๋๋ฅผ ์ค๋ช ํ ์ ์์ด์ผ ํ๋ค.
Spring Container๋ ์ ํํ ๋ฌด์์ธ๊ฐ?
Bean์ ์ด๋ป๊ฒ ์์ฑ๋๋๊ฐ?
DI๋ ์ธ์ ์ํ๋๋๊ฐ?
@PostConstruct๋ ์ ํ์ํ๊ฐ?
Proxy๋ ์ธ์ ์์ฑ๋๋๊ฐ?
@Transactional์ ์ด๋ป๊ฒ ๋์ํ๋๊ฐ?
Singleton Bean์ ์ ์ํํ ์ ์๋๊ฐ?
Spring Boot startup์ด ์ ๋๋ ค์ง๋๊ฐ?
์ฆ:
Spring์ด ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌํ๋ ์ ์ฒด ํ๋ฆ
์ ์ดํดํ๋ ๊ฒ์ด ํต์ฌ์ด๋ค.
๋จผ์ ๊ฐ์ฅ ์ค์ํ ๊ฐ๋
Spring ํต์ฌ ์ฒ ํ์:
โ๊ฐ์ฒด ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ด๋ฆฌํ์ง ์๋๋คโ
์ด๋ค.
์ผ๋ฐ Java์์๋:
1
2
UserService service =
new UserService();
์ง์ ์์ฑํ๋ค.
ํ์ง๋ง Spring์์๋:
1
2
3
@Service
public class UserService {
}
๋ง ์์ฑํ๋ฉด:
๊ฐ์ฒด ์์ฑ
์์กด์ฑ ์ฐ๊ฒฐ
์ด๊ธฐํ
Proxy ์์ฑ
์ข ๋ฃ ๊ด๋ฆฌ
๋ฅผ Spring์ด ๋์ ์ํํ๋ค.
Spring Container๋?
Spring Container๋:
Bean ๊ฐ์ฒด๋ค์ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ณต๊ฐ
์ด๋ค.
์ฝ๊ฒ ๋งํ๋ฉด:
1
๊ฐ์ฒด ๊ด๋ฆฌ์
๋ค.
ํ๋ฆ์ผ๋ก ๋ณด๋ฉด
graph TD
A[Spring Boot Start]
--> B[Component Scan]
B --> C[Bean Definition ๋ฑ๋ก]
C --> D[๊ฐ์ฒด ์์ฑ]
D --> E[DI ์ํ]
E --> F[Proxy ์์ฑ]
F --> G[์ด๊ธฐํ]
G --> H[Application Ready]
์ ์ด๋ฐ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์์๊น?
ํต์ฌ ์ด์ ๋:
๊ฐ์ฒด ์์ฑ ๊ด๋ฆฌ ์๋ํ
์์กด์ฑ ๊ด๋ฆฌ ์๋ํ
๊ณตํต ๊ธฐ๋ฅ ๋ถ๋ฆฌ
์ ์ง๋ณด์ ํฅ์
์ด๋ค.
Bean์ด๋?
Spring์ด ๊ด๋ฆฌํ๋ ๊ฐ์ฒด.
์:
1
2
3
@Service
public class UserService {
}
์ด ๊ฐ์ฒด๋:
1
new UserService()
๋ฅผ ๊ฐ๋ฐ์๊ฐ ์ง์ ํ์ง ์๋๋ค.
Spring์ด ๋์ ์์ฑํ๋ค.
Bean ์์ฑ ์ ์ฒด ํ๋ฆ
graph TD
A[Bean Definition]
--> B[Reflection ๊ฐ์ฒด ์์ฑ]
B --> C[์์กด์ฑ ์ฃผ์
]
C --> D[์ด๊ธฐํ]
D --> E[Proxy ์ ์ฉ ๊ฐ๋ฅ]
E --> F[Bean ์ฌ์ฉ]
1. Component Scan
Spring Boot ์์ ์:
1
@SpringBootApplication
๊ธฐ์ค์ผ๋ก ํจํค์ง ์ค์บ ์ํ.
์ฐพ๋ ๋์
๋ํ์ ์ผ๋ก:
@Component
@Service
@Repository
@Controller
@Configuration
์ scanํ๋๊ฐ?
๊ฐ๋ฐ์๊ฐ ๊ฐ์ฒด ๋ฑ๋ก์ ์ผ์ผ์ด ์ ํด๋ ๋๊ฒ ํ๋ ค๊ณ .
์ฆ:
1
์๋ ๊ฐ์ฒด ๋ฑ๋ก
์ด๋ค.
2. Bean Definition ์์ฑ
์ฌ๊ธฐ์ ์ค์ํ ๊ฑด:
์์ง ๊ฐ์ฒด ์์ฑ์ด ์๋๋ค.
Bean Definition์:
1
๊ฐ์ฒด ์์ฑ ์ค๊ณ๋
๋ค.
ํฌํจ ์ ๋ณด:
ํด๋์ค ํ์
์์ฑ์ ์ ๋ณด
Scope
์์กด์ฑ ์ ๋ณด
๋น์ ํ๋ฉด
1
2
Bean Definition = ๊ฑด์ถ ์ค๊ณ๋
Bean Instance = ์ค์ ๊ฑด๋ฌผ
์ด๋ค.
3. ๊ฐ์ฒด ์์ฑ (Instantiate)
Spring์ Reflection ๊ธฐ๋ฐ์ผ๋ก ๊ฐ์ฒด ์์ฑํ๋ค.
์:
1
new UserService();
๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์ํ.
์ Reflection์ ์ฌ์ฉํ ๊น?
Spring์ ๋ฐํ์์:
Annotation ๋ถ์
๋์ ์์ฑ
Proxy ์์ฑ
ํด์ผ ํ๋ค.
์ฆ:
๋ฐํ์ ์ ์ฐ์ฑ ํ๋ณด
๋ฅผ ์ํด Reflection ์ฌ์ฉ.
Reflection์ด ๋๋ฆฌ๋ค๋ ๋ง์?
์ผ๋ฐ ํธ์ถ๋ณด๋ค ๋๋ฆฐ ๊ฑด ๋ง๋ค.
ํ์ง๋ง ๋๋ถ๋ถ startup ๊ตฌ๊ฐ์์ ์ฌ์ฉ๋๋ค.
์ค์ ์ด์ ๋ณ๋ชฉ์ ๋ณดํต:
DB
Network
๋ค.
4. DI (Dependency Injection)
์์กด ๊ฐ์ฒด ์ฃผ์ ๋จ๊ณ.
์:
1
2
3
4
5
6
7
8
9
10
11
@Service
public class OrderService {
private final UserService userService;
public OrderService(
UserService userService
) {
this.userService = userService;
}
}
๋ด๋ถ ํ๋ฆ
graph TD
A[OrderService ์์ฑ ์์ฒญ]
--> B[UserService Bean ์กฐํ]
B --> C[์์ฑ์ ์ฃผ์
]
์ DI๋ฅผ ์ฌ์ฉํ๋๊ฐ?
ํต์ฌ:
๊ฐ์ฒด ๊ฐ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ธฐ ์ํด
๋ค.
์ง์ ์์ฑ ๋ฌธ์
1
2
UserService userService =
new UserService();
๋ฌธ์ :
ํ ์คํธ ์ด๋ ค์
๊ต์ฒด ์ด๋ ค์
๊ฐํ ๊ฒฐํฉ
DI ์ฅ์
ํ ์คํธ ์ฌ์
Mock ๊ฐ๋ฅ
์ ์ง๋ณด์ ํฅ์
์ ์ฐ์ฑ ์ฆ๊ฐ
5. BeanPostProcessor
์์ฒญ ์ค์ํ๋ค.
Spring ํต์ฌ ํ์ฅ ํฌ์ธํธ๋ค.
์ฌ๊ธฐ์ ํ๋ ์ผ
๋ํ์ ์ผ๋ก:
Proxy ์์ฑ
AOP ์ ์ฉ
@Transactional ์ฒ๋ฆฌ
Validation ์ฒ๋ฆฌ
ํ๋ฆ
graph TD
A[Bean ์์ฑ ์๋ฃ]
--> B[BeanPostProcessor]
B --> C[Proxy ์์ฑ ๊ฐ๋ฅ]
Proxy๋?
์ฝ๊ฒ ๋งํ๋ฉด:
์ค๊ฐ์์ ๋์ ํธ์ถํ๋ ๊ฐ์ฒด
๋ค.
์๋ ํธ์ถ ๊ตฌ์กฐ
graph TD
A[Client]
--> B[Service]
Proxy ์ ์ฉ ํ
graph TD
A[Client]
--> B[Proxy]
--> C[Real Service]
์ Proxy๋ฅผ ์ฐ๋๊ฐ?
๋น์ฆ๋์ค ๋ก์ง ์์ ์์ด:
๋ก๊ทธ
ํธ๋์ญ์
๋ณด์
์บ์
๊ฐ์ ๊ณตํต ๊ธฐ๋ฅ ์ถ๊ฐ ๊ฐ๋ฅ.
@Transactional ์ค์ ๊ตฌ์กฐ
1
2
3
@Transactional
public void order() {
}
์ค์ ๋ก :
sequenceDiagram
Client->>Transaction Proxy: order()
Transaction Proxy->>Transaction Manager: begin()
Transaction Proxy->>Real Service: order()
Transaction Proxy->>Transaction Manager: commit()
ํต์ฌ
ํธ๋์ญ์ ๋ก์ง์ ์๋น์ค ์ฝ๋์ ์ ๋ฃ๊ณ Proxy๊ฐ ์ฒ๋ฆฌ
ํ๋ค.
6. @PostConstruct
์ด๊ธฐํ ๋ก์ง ์ํ ์์ .
1
2
3
@PostConstruct
public void init() {
}
์ธ์ ํธ์ถ๋๋?
DI ์๋ฃ ์ดํ.
์ฆ:
1
์์กด ๊ฐ์ฒด ์ฌ์ฉ ๊ฐ๋ฅํ ์ํ
์์ ํธ์ถ๋๋ค.
์ค๋ฌด ์ฌ์ฉ ์ฌ๋ก
๋ํ์ ์ผ๋ก:
Cache preload
์ด๊ธฐ ๋ฐ์ดํฐ ๋ก๋ฉ
์ค์ ๊ฒ์ฆ
์ธ๋ถ ์ฐ๊ฒฐ ํ์ธ
์ํํ ์ค์
@PostConstruct ๋ด๋ถ์์:
๋๋ DB ์กฐํ
์ธ๋ถ API ํธ์ถ
ํ๋ฉด startup ๋๋ ค์ง ์ ์๋ค.
์ค์ ์ด์ ์ฅ์ ์ฌ๋ก
1
MSA ์๋น์ค startup 3๋ถ ์ด์
์์ธ:
1
@PostConstruct ๋ด๋ถ ๋ฌด๊ฑฐ์ด ์์
7. Bean ์ฌ์ฉ
์ดํ ์ค์ ์๋น์ค ์ฒ๋ฆฌ ์ํ.
8. Bean ์ข ๋ฃ
Spring ์ข ๋ฃ ์:
1
2
3
@PreDestroy
public void destroy() {
}
ํธ์ถ.
์ ์ค์ํ๋?
์ ๋ฆฌ ์ ํ๋ฉด:
DB Connection Leak
Thread Leak
Resource Leak
๊ฐ๋ฅ.
Singleton Bean
Spring ๊ธฐ๋ณธ Scope๋ Singleton์ด๋ค.
์ฆ:
1
Application ์ ์ฒด์์ ๊ฐ์ฒด 1๊ฐ
์ฌ์ฉ.
์ Singleton ์ฌ์ฉํ๋๊ฐ?
์ฅ์ :
๋ฉ๋ชจ๋ฆฌ ์ ์ฝ
์์ฑ ๋น์ฉ ๊ฐ์
๊ด๋ฆฌ ํจ์จ
์ํํ ์ด์
Singleton Bean ๋ด๋ถ mutable ์ํ ์ ์ฅ ์:
1
private int count;
๋ฉํฐ Thread ํ๊ฒฝ ๋ฌธ์ ๋ฐ์ ๊ฐ๋ฅ.
์ค๋ฌด ๋จ๊ณจ ์ฅ์
1
2
3
๋์ ์์ฒญ
โ count ๊ผฌ์
โ race condition
Spring Boot startup์ด ๋๋ฆฐ ์ด์
๋ํ ์์ธ:
Reflection
Classpath Scan
Proxy ์์ฑ
Annotation ๋ถ์
Bean ์ด๊ธฐํ
Startup ์ ์ฒด ํ๋ฆ
graph TD
A[Classpath Scan]
--> B[Bean Definition]
B --> C[Reflection ๊ฐ์ฒด ์์ฑ]
C --> D[DI ์ํ]
D --> E[Proxy ์์ฑ]
E --> F[์ด๊ธฐํ]
F --> G[Application Ready]
Trade-off
์ฅ์
๊ฐ์ฒด ๊ด๋ฆฌ ์๋ํ
์์ฐ์ฑ ํฅ์
AOP ๊ฐ๋ฅ
ํ์ฅ์ฑ ์ฐ์
๋จ์
startup ๋น์ฉ ์ฆ๊ฐ
๋ด๋ถ ๊ตฌ์กฐ ๋ณต์ก
๋๋ฒ๊น ์ด๋ ค์
reflection overhead
์์ฃผ ๋ฐ์ํ๋ ์ค์
1. Singleton Bean ์ํ ์ ์ฅ
๋ฉํฐ Thread ๋ฌธ์ ๋ฐ์.
2. @PostConstruct ๋ฌด๊ฑฐ์ด ์์
startup latency ์ฆ๊ฐ.
3. self invocation
@Transactional ๋ด๋ถ ํธ์ถ ๋ฌธ์ .
4. ์ํ ์ฐธ์กฐ
์ค๊ณ ๋ฌธ์ ๊ฐ๋ฅ์ฑ ๋์.
๋ฉด์ ๊ผฌ๋ฆฌ ์ง๋ฌธ
Q1. Spring Bean Lifecycle ํ๋ฆ์ ์ค๋ช ํด๋ณด์ธ์.
ํต์ฌ:
scan
definition
instantiate
DI
proxy
init
destroy
Q2. Proxy๋ ์ธ์ ์์ฑ๋๋์?
ํต์ฌ:
- BeanPostProcessor ๋จ๊ณ
Q3. Spring์ด Reflection์ ์ฌ์ฉํ๋ ์ด์ ๋?
ํต์ฌ:
- ๋ฐํ์ ์ ์ฐ์ฑ ํ๋ณด
Q4. Singleton Bean์ด ์ ์ํํ ์ ์๋์?
ํต์ฌ:
mutable state
race condition
Q5. Spring Boot startup์ด ๋๋ฆฐ ์ด์ ๋?
ํต์ฌ:
scan
reflection
proxy ์์ฑ
์ข์ ๋ต๋ณ ์์
Spring์ Bean Lifecycle์ ํตํด ๊ฐ์ฒด ์์ฑ๋ถํฐ ์์กด์ฑ ์ฃผ์ , ์ด๊ธฐํ, Proxy ์์ฑ, ์ข ๋ฃ๊น์ง ๊ด๋ฆฌํฉ๋๋ค.
Spring์ Reflection ๊ธฐ๋ฐ์ผ๋ก ๋ฐํ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉฐ BeanPostProcessor ๋จ๊ณ์์ AOP์ Transaction Proxy ๊ฐ์ ๊ธฐ๋ฅ์ ์ ์ฉํฉ๋๋ค.
๋ํ Singleton Bean ๊ธฐ๋ฐ์ด๊ธฐ ๋๋ฌธ์ mutable ์ํ ๊ด๋ฆฌ์ ์ฃผ์ํด์ผ ํ๋ฉฐ startup ๊ณผ์ ์์ scan๊ณผ proxy ์์ฑ ๋น์ฉ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
๊ด๋ จ CS ๊ฐ๋ ์ฐ๊ฒฐ
Dependency Injection
Inversion of Control
Reflection
Proxy Pattern
Singleton Pattern
Runtime Dynamic Loading
Lifecycle Management
ํ์ ์์ ํนํ ์ค์ํ ํฌ์ธํธ
1. Spring์ Proxy ๊ธฐ๋ฐ Framework๋ค
@Transactional ์ดํด ํต์ฌ.
2. startup latency ์ค์
MSA ํ๊ฒฝ์์ ๋งค์ฐ ์ค์.
3. Singleton ์ํ ๊ด๋ฆฌ ์ค์
์ค๋ฌด ์ฅ์ ์์ธ ์์ฃผ ๋จ.
4. BeanPostProcessor ์ดํด ์ค์
Spring ๋ด๋ถ ๊ตฌ์กฐ ํต์ฌ.
ํต์ฌ ์์ฝ
Spring์ ๊ฐ์ฒด ์๋ช ์ฃผ๊ธฐ๋ฅผ Container๊ฐ ๊ด๋ฆฌํ๋ค
Bean Definition โ ์์ฑ โ DI โ Proxy โ ์ด๊ธฐํ ํ๋ฆ์ผ๋ก ๋์ํ๋ค
Spring ๋ด๋ถ๋ Reflection ๊ธฐ๋ฐ์ด๋ค
Proxy๋ฅผ ํตํด Transaction/AOP๋ฅผ ๊ตฌํํ๋ค
Singleton Bean ์ํ ๊ด๋ฆฌ๋ ๋งค์ฐ ์ค์ํ๋ค
startup latency๋ ์ค์ ์ด์ ์ด์๋ค
Bean Lifecycle ์ดํด๋ Spring ๋ด๋ถ ๊ตฌ์กฐ ์ดํด์ ํต์ฌ์ด๋ค