애플리케이션 컨텍스트의 초기화 과정중에 항상 거치는 메소드가 refresh이다.
org.springframework.context.support.AbstractApplicationContext의 코드를 옮겨보면 다음과 같다. (4.1.
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 멤버 필드인 active를 true로 설정한다. (active의 플래그로 refresh가 되었는지를 판단)
prepareRefresh();
// 내부에서 쓰이는 BeanFactory를 refresh
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// beanFactory를 사용 가능한 상태로 준비 합니다.
// 이 메소드에서는 beanFactory에 PropertyEditor, ClassLoader, BeanPostProcessor 등이 등록
prepareBeanFactory(beanFactory);
try {
// 템플릿 메소드. 자식 클래스의 재정의에 따라 행동이 변합니다.
// ApplicationContext에서는 아무 작업을 하지 않음
// WebApplicationContext 에서는 Web Scope가 등록됨
postProcessBeanFactory(beanFactory);
// 등록된 bean들 중에 BeanFactoryPostProcessor인 것을 찾아 생성하고 실행
// 생성 순서는 XML에 정의된 순서이지만,
// 메소드 호출은 PriorityOrdered, Ordered, Non-Ordered 순으로 수행됨
invokeBeanFactoryPostProcessors(beanFactory);
// 먼저 BeanPostProcessorChecker를 생성하여 beanFactory에 등록
// BeanPostProcessorChecker의 역할은 bean 생성시 로그 메세지를 출력
// 이후 등록된 bean들 중에 BeanPostProcessor인 것을 찾아 생성한 후, beanFactory에 등록
// (등록 순서는 PriorityOrdered > Ordered > Non-Ordered)
registerBeanPostProcessors(beanFactory);
// 등록된 bean들 중에 id가 messageSource인 것을 찾아 생성
// MessageSource로 캐스팅 하여 내부 프로퍼티인 messageSource에 할당함
// 만약 발견되지 않는다면 DelegatingMessageSource를 생성하여 할당
initMessageSource();
// 등록된 bean들 중에 id가 applicationEventMulticaster인 것을 찾아 생성
// ApplicationEventMulticaster로 캐스팅하여 applicationEventMulticaster프로퍼티 할당
// 만약 발견되지 않는다면 SimpleApplicationEventMulticaster를 생성하여 할당
initApplicationEventMulticaster();
// 템플릿 메소드입니다.
// 자식 클래스의 재정의에 따라 행동이 변함
// ApplicationContext : 아무 작업을 하지 않음
// WebApplicationContext : themeSource를 설정
onRefresh();
// 등록된 bean들 중에 타입이 ApplicationListener인 것을 찾아 생성한 후 리스너로 등록
registerListeners();
// 일반적인 bean(Singleton, non-lazy-init)을 생성/의존성이 삽입
// 생성 과정에서 LifeCycle 인터페이스를 구현했다면 해당 메소드가 호출되고 등록된 BeanPostProcessor를 거치게 됩니다.
// Spring에는 기본적으로 ApplicationContextAwareProcessor가 등록되어 있으므로 이곳도 거치게 됩니다.
finishBeanFactoryInitialization(beanFactory);
// 모든 과정이 끝남(ContextRefreshedEvent 전파)
// 마지막으로 위 과정에서 등록된 ApplicationListener들에게 초기화가 끝났다는 신호 전파
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
참고: http://www.oraclejavanew.kr/bbs/board.php?bo_table=C15&wr_id=252 / http://jjaeko.tistory.com/19
'Programing > JVM(Java, Kotlin)' 카테고리의 다른 글
[후펴파는 스프링] 스프링 컨테이너 계층 정리 (1) | 2015.02.10 |
---|---|
후벼파는 자바 - 어노테이션의 내부 원리 (0) | 2015.02.05 |
후벼파는 스프링 - ApplicationContext의 디폴트 (0) | 2015.02.02 |
후벼파는 스프링 - @RequestMapping의 원리 (0) | 2015.02.02 |
[면접 문제] 1로 설정된 비트의 수를 반환하는 함수 작성 (0) | 2015.01.22 |