On application close, each singleton bean is destroyed by DefaultListableBeanFactory.destroySingletons(). If the bean has a public void no-arg method called shutdown, then it will be invoked. I have some 3rd party beans, all of which implement a certain interface, let's call it DoNotDestroy, that I do not want Spring to destroy.
I can specify a blank string destroy method on each bean, like so:
@Bean(destroyMethod = "")
public MyBean myBean() {
return new MyBean();
}
However, I would prefer to somehow configure Spring to not destroy any beans that implement DoNotDestroy. Is there a good way to do this?
Rather than blanking out the destroy method in each @Bean method, I can implement a BeanFactoryPostProcessor to do the same thing:
@Component
public class DoNotDestroyPostProcessor implements BeanFactoryPostProcessor {
private final Logger log = LoggerFactory.getLogger(DoNotDestroyPostProcessor.class);
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] doNotDestroys = beanFactory.getBeanNamesForType(DoNotDestroy.class);
for (String doNotDestroy : doNotDestroys) {
BeanDefinition bean = beanFactory.getBeanDefinition(doNotDestroy);
log.info("Don't destroy bean {} {}", bean.getFactoryMethodName(), bean.getDestroyMethodName());
bean.setDestroyMethodName("");
}
}
}
This avoids the problem of someone adding a bean and forgetting to blank out the destroy method.