<ref/>
요소를 사용하여 이루어짐.depends-on
으로 특정 빈이 초기화되기 전에 다른 빈이 먼저 초기화되도록 강제가 가능함.DB 드라이버 등록처럼 클래스의 정적 이니셜라이저를 트리거해야하는 경우도 있음
- 이라는 것은
- 정적 이니셜라이저(Static Initializer)
- 클래스가 처음 메모리에 로드되는 경우 자동으로 실행되는 특별한 코드 블록
- 주로 클래스가 사용되기 전에 필요한 설정이나 초기화를 수행함.
- 다른 데이터베이스 관련 빈들은 DB 드라이버가 먼저 등록되어야 정상 동작하는 경우가 있습니다. 그래서 static block 에서..
public class MyDBDriver { static { // DB 드라이버 등록 코드 DriverManager.registerDriver(new MyDBDriver()); System.out.println("DB 드라이버가 등록되었습니다."); } }
- 이런식으로 다른 빈들이 등록되기 전에 (메모리에 로드될 때) 등록을 해주기도하는데
- 스프링의 경우 빈을 초기화하는 순서는
- 위상 정렬을 통해 순서를 결정합니다.
- 간단하게
- 일단 모든 빈들을 별도의 빈 정렬 트리에 넣습니다
- 예를 들어
- 의존관계는 다음과 같이 구성되어 있다고 생각해봅시다
DatabaseInitializer ↓ DataSource ↓ UserRepository ↓ UserService ↑ CacheInitializer
- 단계별로 위상 정렬 과정을 수행하는데
- 진입 차수를 계산합니다
각 빈이 몇 개의 빈에 의존하는지 계산한다고 합니다.
빈 이름 진입차수 DatabaseInitializer 0 CacheInitializer 0 DataSource 1 UserRepository 1 UserService 2 - 진입 차수가 0 인 노드를 선택한다
- 초기 단계에서 진입차수가 0인 빈들을 먼저 초기화한다고 합니다
- 0인 노드들은 어떤 다른 빈들도 의존하지 않는 빈입니다.
- 빈 초기화 - 연결 해제 단계
DatabaseInitializer
를 초기화하고DataSource
의 진입차수가 1 → 0 으로 감소합니다.CacheInitializer
를 초기화하고UserService
의 진입차수를 2 → 1로 감소시킵니다.- 다시 진입차수가 0인 노드를 선택합니다.
DataSource
- 빈 초기화 및 연결 해제 단계
DataSource
를 초기화하고
UserRepository
의 진입차수를 1 → 0으로 감소시킵니다.- 계속적으로 모든 빈들의 진입차수가 0이 될때까지 반복합니다.
- 이런 방식으로 빈을 초기화한다면 완벽하게 모든 빈들을 순서에 맞게 초기화할 수 있습니다
- 물론 A 가 B를 의존 B가 A를 의존하는 등의 순환참조가 발생하지 않도록 조심해야겠져
@Configuration
public class AppConfig {
@Bean
public ManagerBean manager() {
return new ManagerBean();
}
@Bean
public AccountDao accountDao() {
return new JdbcAccountDao();
}
@Bean
@DependsOn({"manager", "accountDao"}) //manager accountDao가 초기화되고 나서 초기화되어야 합니다.
//manager 와 accountDao 의 초기진입 차수는 0 beanOne 은 1이 되겠죠
public ExampleBean beanOne() {
ExampleBean exampleBean = new ExampleBean();
exampleBean.setManager(manager());
return exampleBean;
}
}