registerDisposableBeanIfNecessary
registerDisposableBeanIfNecessary
注册销毁bean时的回调
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
//判断 bean 不是原型 并且 有销毁方法
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
// 如果是单例 bean 在bean工厂中注册销毁回调
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
//注册执行所有销毁的DisposableBean实现
//为给定bean工作:DestructionAwareBeanPostProcessors,
//DisposableBean接口,自定义销毁方法。
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
else {
// A bean with a custom scope...
// 如果不是单例的 注册回调到他们的各自的 scope
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
}
}
DisposableBeanAdapter
适配器模式,为销毁的bean创建一个适配器
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<DestructionAwareBeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
// 对destroyMethodName进行推断
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
// 1、推断结果不为空
// 2、invokeDisposableBean为false,或者destroyMethodName = destroy
// 3、保存的回调方法名不存在 destroyMethodName
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
// 通过destroyMethodName获取到对应的method
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
if (destroyMethod.getParameterCount() > 0) {
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
// 销毁方法参数个数不能多于1个
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
// 销毁方法的唯一参数只能是boolean类型
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
this.destroyMethod = destroyMethod;
}
// 从postProcessors查找到所有适用于bean的销毁processors
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
Initializing与 Disposable 执行顺序
关于在Spring 容器 初始化和销毁 bean 前所做的操作有三种方式定义:
-
通过@PostConstruct 和 @PreDestroy 方法 实现初始化后和销毁bean之前进行的操作
-
通过bean实现InitializingBean和 DisposableBean接口
-
通过 在xml中配置init-method 和 destory-method方法,或者 配置@Bean(initMethod = “initMethod”, destroyMethod = “destroyMethod”) 注解
-
@PostConstruct -> InitializingBean -> 配置initMethod -> @PreDestroy -> DisposableBean -> 配置destroyMethod