Spring-bean销毁

avatar
作者
筋斗云
阅读量:0

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); 	} 

    广告一刻

    为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!