from Dictionary - Refresh Context
Refresh Context
class SpringApplication {
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
shutdownHook.registerApplicationContext(context);
}
refresh(context);
}
protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}
}
class SpringApplicationShutdownHook {
void registerApplicationContext(ConfigurableApplicationContext context) {
addRuntimeShutdownHookIfNecessary();
synchronized (SpringApplicationShutdownHook.class) {
assertNotInProgress();
context.addApplicationListener(this.contextCloseListener);
this.contexts.add(context);
}
}
}
interface ConfigurableApplicationContext {
void refresh() throws BeansException, IllegalStateException;
}
-
Shutdown Hook 등록 -> Shutdown 후 후처리 작업에 대해서 명시 (연결 종료, 자원 반납,
@PreDestroy, Bean의DestroyMethod를 실행) -
refresh 실행 ServletWebServerApplicationContext 기준으로
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); // 1. refresh 준비 단계 // applicationContext 상태를 active로 변경 (BeanFactory에서 bean을 꺼내기 위한 필수 작업) prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 2. BeanFactory 준비 단계 (BeanFactory 동작 전에 필요한 작업 수행) prepareBeanFactory(beanFactory); // 클래스 로더를 세팅하고 // spEL Resolver // PropertyEditory를 빈으로 추가한다. // 의존성 주입을 무시할 인터페이스(~Aware)를 등록하고 // BeanFactory와 ApplicationContext 같은 특별한 타입들을 빈으로 등록 try { // 3. BeanFactory의 후처리 진행 // beanFactory 후처리한다. postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); // 4. BeanFactoryPostProcessor 실행 // BeanFactory 후처리와는 엄연히 다르다. // 빈을 탐색하거나 빈 팩토리가 준비된 후에 해야하는 후처리기들을 실행한다. // 예를 들어 싱글톤 객체로 인스턴스화할 빈을 탐색하는 작업 // // 정리하면 BeanFactory를 준비하고 빈을 인스턴스화 하기 전의 중간 단계로 // 빈 목록을 불러오고, 빈의 메타 정보를 조작하기 위한 // BeanFactoryPostProcessor를 객체로 만들어 실행 invokeBeanFactoryPostProcessors(beanFactory); // 5. BeanPostProcessor 등록 // 빈 생성되고 나서 빈의 내용이나 빈 자체를 변경하기 위한 빈 후처리기인 // BeanPostProcessor를 등록 // @Value, @PostConstruct, @Autowired 등이 BeanPostProcessor에 의해 처리되며 이를 위한 BeanPostProcessor 구현체들이 등록된다. registerBeanPostProcessors(beanFactory); beanPostProcess.end(); // 6. MessageSource 및 Event Multicaster 초기화 // 다국어 처리를 위한 MessageSource와 ApplicationListener에 event를 publish 하기 위한 EventMulticaster를 초기화 initMessageSource(); initApplicationEventMulticaster(); // 7. onRefresh // TemplateMethod 패턴으로 필요한 내장 웹서버를 실행 // ApplicationConfigServletWebServerApplicationContext -> Tomcat // ApplicationConfigReactiveWebServerApplicationContext -> ReactorNetty onRefresh(); // 8. ApplicationListener 조회 및 등 록 // ApplicationListener의 구현체들을 찾아서 EventMultiCaster에 등록해주고 있다. registerListeners(); // 9. 빈들의 인스턴스화 및 후처리 // BeanDefinition기준으로 객체 생성 // BeanPostProcessor를 적용해 @Value, @PostConstruct, @Autowired 등을 처리해주고 객체의 생성을 마무리 finishBeanFactoryInitialization(beanFactory); // 10. refresh 마무리 단계 // 웹서버 실행 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); contextRefresh.end(); } } }