Bean이 Destory되는 과정을 한번 찾아가보자
SpringApplicationShutdownHook.class
@Override
public void run() {
...
contexts.forEach(this::closeAndWait);
closedContexts.forEach(this::closeAndWait);
...
}
private void closeAndWait(ConfigurableApplicationContext context) {
if (!context.isActive()) {
return;
}
context.close();
...
}
AbstractApplicationContext.class
@Override
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
...
}
}
protected void doClose() {
...
destroyBeans();
...
}
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
DefaultSingletonBeanRegistry.class
public void destroySingletons() {
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
}
public void destroySingleton(String beanName) {
...
destroyBean(beanName, disposableBean);
}
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
...
if (bean != null) {
try {
bean.destroy();
}
}
...
}
SpringApplicationShutdownHook Thread가 시작하게되면 위와같은 과정을 거쳐 bean이 destory하게 된다
@Override
public void onApplicationEvent(ContextClosedEvent event) {
synchronized (SpringApplicationShutdownHook.class) {
ApplicationContext applicationContext = event.getApplicationContext();
SpringApplicationShutdownHook.this.contexts.remove(applicationContext);
SpringApplicationShutdownHook.this.closedContexts.add((ConfigurableApplicationContext) applicationContext);
}
}
ContextClosedEvent가 발생하게 되면 해당 Context를 ShutdownHook에 추가한다
SpringBoot가 run될때 EventListener로 등록되는것도 볼 수 있다정확하진 않지만 추측상 해당 Listener는 EventMulticaster에 의해 Async로 실행되는거 같다