bean销毁(找到销毁的bean)
在bean的声明周期中,存在一个记录bean销毁方法的阶段,以备于spring关闭的时候可以执行bean的销毁方法(单例bean)
v1.0 registerDisposableBeanIfNecessary
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
//当rootBeanDefinition不是原型bean,并且requiresDestruction方法返回true代表当前bean是需要销毁的
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
//最终通过适配器模式将销毁方法存入disposableBeans这个Map中
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
else {
// A bean with a custom 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));
}
}
}
v1.1 requiresDestruction
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
//首先bean不能为NULLBEAN,然后(实现了DisposableBean接口或实现了AutoCloseable) 或者有销毁的方法
return (bean.getClass() != NullBean.class && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) ||
(hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(
bean, getBeanPostProcessorCache().destructionAware))));
}
v1.2 hasDestroyMethod
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
//如果实现了DisposableBean接口或实现了AutoCloseable,直接返回true
if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
return true;
}
return inferDestroyMethodIfNecessary(bean, beanDefinition) != null;
}
private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
//从缓存中获取当前RootBeanDefinition的结束方法
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
if (destroyMethodName == null) {
//如果缓存中没有,则尝试直接获取销毁方法名称
destroyMethodName = beanDefinition.getDestroyMethodName(); //
//判断bean销毁的名字是否等于(inferred)或者实现了AutoCloseable接口
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
destroyMethodName = null;
//进入这一阶段,spring会自己去寻找销毁方法
if (!(bean instanceof DisposableBean)) {
try {
//获取类中的close方法
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex) {
try {
//获取类中的SHUTDOWN_METHOD_NAME方法
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
}
//将销毁方法名字缓存到resolvedDestroyMethodName字段中
beanDefinition.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : "");
}
return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
}
v1.3 hasDestructionAwareBeanPostProcessors
//判断destructionAware缓存是否为空
protected boolean hasDestructionAwareBeanPostProcessors() {
return !getBeanPostProcessorCache().destructionAware.isEmpty();
}
BeanPostProcessorCache getBeanPostProcessorCache() {
//先从缓存中拿取 BeanPostProcessorCache ,如果没获取到,说明还没有对beanPostProcessors进行分类
BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
if (bpCache == null) {
bpCache = new BeanPostProcessorCache();
//对所有的beanPostProcessors进行循环分类
for (BeanPostProcessor bp : this.beanPostProcessors) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
}
}
if (bp instanceof DestructionAwareBeanPostProcessor) {
bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
}
if (bp instanceof MergedBeanDefinitionPostProcessor) {
bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
}
}
this.beanPostProcessorCache = bpCache;
}
return bpCache;
}
v1.4 DisposableBeanAdahasApplicableProcessorspter.
public static boolean hasApplicableProcessors(Object bean, List<DestructionAwareBeanPostProcessor> postProcessors) {
if (!CollectionUtils.isEmpty(postProcessors)) {
for (DestructionAwareBeanPostProcessor processor : postProcessors) {
if (processor.requiresDestruction(bean)) {
return true;
}
}
}
return false;
}
public boolean requiresDestruction(Object bean) {
return findLifecycleMetadata(bean.getClass()).hasDestroyMethods();
}
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
if (this.lifecycleMetadataCache == null) {
// Happens after deserialization, during destruction...
return buildLifecycleMetadata(clazz);
}
// Quick check on the concurrent map first, with minimal locking.
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
synchronized (this.lifecycleMetadataCache) {
metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
metadata = buildLifecycleMetadata(clazz);
this.lifecycleMetadataCache.put(clazz, metadata);
}
return metadata;
}
}
return metadata;
}
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
//此处使用了双层循环处理
//该集合定义了所有的初始化方法
List<LifecycleElement> initMethods = new ArrayList<>();
//该集合中定义了所有的销毁方法
List<LifecycleElement> destroyMethods = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<LifecycleElement> currInitMethods = new ArrayList<>();
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//判断方法是否实现了@PostConstruct注解
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
//判断方法是否实现了@PreDestroy注解
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
currDestroyMethods.add(new LifecycleElement(method));
if (logger.isTraceEnabled()) {
logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
});
//将父类的初始化方法放在最前面
initMethods.addAll(0, currInitMethods);
//将父类的销毁方法放在最后面
destroyMethods.addAll(currDestroyMethods);
//获取父类
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
执行bean销毁
v1.1 destroySingletons
//销毁单例bean
public void destroySingletons() {
if (logger.isTraceEnabled()) {
logger.trace("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
//获取所有有销毁方法的bean的名字
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
//遍历销毁所有的方法
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
clearSingletonCache();
}
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
// 先从单例池中移除掉
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
}
v1.1 destroyBean
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// dependentBeanMap表示某bean被哪些bean依赖了
// 所以现在要销毁某个bean时,如果这个Bean还被其他Bean依赖了,那么也得销毁其他Bean
// Trigger destruction of dependent beans first...
Set<String> dependencies;
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
dependencies = this.dependentBeanMap.remove(beanName);
}
if (dependencies != null) {
if (logger.isTraceEnabled()) {
logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
if (logger.isWarnEnabled()) {
logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
}
}
}
// Trigger destruction of contained beans...
Set<String> containedBeans;
synchronized (this.containedBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
containedBeans = this.containedBeanMap.remove(beanName);
}
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies.
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
}