登记需要执行销毁方法的bean
在bean装配里面提过,bean初始化完成之后,会注册成为添加到disposableBeans,这个disposableBeans就是在关闭的时候,调用其destroy方法来销毁bean
AbstractBeanFactory#registerDisposableBeanIfNecessary
重点是requiresDestruction方法,用来判断是否需要手动调用销毁方法,进去后发现有2个判断条件,满足任意一个即可:
- 是否有销毁方法:
- 通过destroy-method指定的destroy方法
- 实现了DisposableBean接口
- 销毁方法名为(inferred)情况下, 有close或者shutdown方法
- 有DestructionAwareBeanPostProcessor实现类,并且DestructionAwareBeanPostProcessor#requiresDestruction判断满足条件(可通过实现DestructionAwareBeanPostProcessor接口来扩展)
- 实现了ApplicationListener
- scheduledTasks定时任务里面存在
- 实现了Servlet
- 有方法加上了@PreDestroy注解
如果满足条件,创建DisposableBeanAdapter进行注册(添加到disposableBeans)
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
...
}
}
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean != null &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}
第二个判断条件一下看上去有点看不懂,实际上它是提供一个可扩展的方式来决定是否需要手动执行销毁动作,我们来看下他目前的实现类,
另外3个都是比较简单的一个判断,
我们来主要看下CommonAnnotationBeanPostProcessor,发现他实现了InstantiationAwareBeanPostProcessor接口,对的,就是bean构建过程中会进行调用,下面来看做了啥
首先,初始化的时候,设置了setDestroyAnnotationType(PreDestroy.class)
在对象构建完后,调用其postProcessMergedBeanDefinition方法时,会遍历对象的方法找出用于销毁的方法存到destroyMethods(根据setDestroyAnnotationType设置的类型),最后就可以用来判断该对象是否需要销毁动作以及具体销毁的动作的执行
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
...
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
...
// 父类方法
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
if (beanType != null) {
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}
...
public boolean requiresDestruction(Object bean) {
return findLifecycleMetadata(bean.getClass()).hasDestroyMethods();
}
// 父类方法
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
if (this.lifecycleMetadataCache == null)</