본문 바로가기

Programing/JVM(Java, Kotlin)

후벼파는 스프링 - AbstractApplicationContext.refresh 과정

애플리케이션 컨텍스트의 초기화 과정중에 항상 거치는 메소드가 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