When closing the applicationContext, those Lifecycle
beans are stopped earlier than normal beans.
// AbstractApplicationContext.doClose
protected void doClose() {
publishEvent(new ContextClosedEvent(this));
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
}catch (Throwable ex) {}
}
destroyBeans();
closeBeanFactory();
onClose();
resetCommonCaches();
}
And the default lifecycle processor only close those beans which are Lifecycle
// DefaultLifecycleProcessor
private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
final CountDownLatch latch, final Set<String> countDownBeanNames) {
Lifecycle bean = lifecycleBeans.remove(beanName);
if (bean != null) {
String[] dependentBeans = getBeanFactory().getDependentBeans(beanName);
for (String dependentBean : dependentBeans) {
// so if the dependentBean is not LifeCycle type, it will be skipped to stop
doStop(lifecycleBeans, dependentBean, latch, countDownBeanNames);
}
// codes which are doing the cleanup
// ...
}
}
If normal beans which depend on Lifecycle
beans may not work properly during the closing period, because their depending Lifecycle
beans are stopped earlier.
Comment From: sdeleuze
Could you please share a reproducer (attached archive or link to a repository) that shows a concrete use-case where that causes a problem?
Comment From: bringyou
@sdeleuze sure, I've upload a demo project please pay attention on this file on it's destroy method we will prove that it's dependent lifecycle bean is closed earlier.
Comment From: sdeleuze
Unless I miss something, I think the behavior you see is the expected one.
Destroying bean via DisposableBean#destroy
happens after closing them via Lifecycle#stop
, that's expected and not considered as equivalent even if both are related.
Also your LifecycleBean
is never started or stopped, as it implements Lifecycle
not SmartLifecycle
.