spring:bean的销毁

登记需要执行销毁方法的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()))));
}

第二个判断条件一下看上去有点看不懂,实际上它是提供一个可扩展的方式来决定是否需要手动执行销毁动作,我们来看下他目前的实现类,
spring:bean的销毁_第1张图片
另外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) {
			// 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) {
		final boolean debug = logger.isDebugEnabled();
		LinkedList<LifecycleElement> initMethods = new LinkedList<LifecycleElement>();
		LinkedList<LifecycleElement> destroyMethods = new LinkedList<LifecycleElement>();
		Class<?> targetClass = clazz;

		do {
			final LinkedList<LifecycleElement> currInitMethods = new LinkedList<LifecycleElement>();
			final LinkedList<LifecycleElement> currDestroyMethods = new LinkedList<LifecycleElement>();

			ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
				@Override
				public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
					if (initAnnotationType != null) {
						if (method.getAnnotation(initAnnotationType) != null) {
							LifecycleElement element = new LifecycleElement(method);
							currInitMethods.add(element);
							if (debug) {
								logger.debug("Found init method on class [" + clazz.getName() + "]: " + method);
							}
						}
					}
					if (destroyAnnotationType != null) {
						if (method.getAnnotation(destroyAnnotationType) != null) {
							currDestroyMethods.add(new LifecycleElement(method));
							if (debug) {
								logger.debug("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 new LifecycleMetadata(clazz, initMethods, destroyMethods);
	}
	...
}

注册关闭钩子ShutdownHook

之前 JVM关闭 里面说过,程序正常关闭的时候,JVM会先去调用注册的关闭钩子ShutdownHook,spring也是通过这个方式进行销毁前的动作处理

SpringApplication#createAndRefreshContext
AbstractApplicationContext#registerShutdownHook
在完成上下文创建后,会注册关闭钩子

@Override
public void registerShutdownHook() {
	if (this.shutdownHook == null) {
		// No shutdown hook registered yet.
		this.shutdownHook = new Thread() {
			@Override
			public void run() {
				synchronized (startupShutdownMonitor) {
					doClose();
				}
			}
		};
		Runtime.getRuntime().addShutdownHook(this.shutdownHook);
	}
}

protected void doClose() {
	if (this.active.get() && this.closed.compareAndSet(false, true)) {
		if (logger.isInfoEnabled()) {
			logger.info("Closing " + this);
		}

		LiveBeansView.unregisterApplicationContext(this);

		try {
			// Publish shutdown event.
			// 发布上下文关闭事件ContextClosedEvent
			publishEvent(new ContextClosedEvent(this));
		}
		catch (Throwable ex) {
			logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
		}

		// Stop all Lifecycle beans, to avoid delays during individual destruction.
		// 调用Lifecycle#stop方法
		try {
			getLifecycleProcessor().onClose();
		}
		catch (Throwable ex) {
			logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
		}

		// Destroy all cached singletons in the context's BeanFactory.
		// 销毁bean
		destroyBeans();

		// Close the state of this context itself.
		closeBeanFactory();

		// Let subclasses do some final clean-up if they wish...
		onClose();

		this.active.set(false);
	}
}

bean销毁

再来具体看bean销毁的方法
AbstractApplicationContext#destroyBeans
DefaultListableBeanFactory#destroySingletons
DefaultSingletonBeanRegistry#destroySingletons

流程总结为:

  1. 取出需要执行销毁方法的bean(前面注册登记的)
  2. 遍历每个bean执行销毁方法
  3. 取出bean的依赖方,先销毁依赖方(就是之前bean装配提到的@DependsOn标志的依赖方)
  4. 执行bean的destroy方法:
    4.1. 调用DestructionAwareBeanPostProcessor来执行销毁方法
    4.2. 执行DisposableBean#destroy方法
    4.3. 执行init-method指定的destroy方法
  5. 销毁内部类对象
  6. 从依赖关系中去掉自己
public void destroySingletons() {
	if (logger.isDebugEnabled()) {
		logger.debug("Destroying singletons in " + this);
	}
	synchronized (this.singletonObjects) {
		this.singletonsCurrentlyInDestruction = true;
	}

	String[] disposableBeanNames;
	synchronized (this.disposableBeans) {
		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();

	synchronized (this.singletonObjects) {
		this.singletonObjects.clear();
		this.singletonFactories.clear();
		this.earlySingletonObjects.clear();
		this.registeredSingletons.clear();
		this.singletonsCurrentlyInDestruction = false;
	}
}

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

protected void destroyBean(String beanName, DisposableBean bean) {
	// Trigger destruction of dependent beans first...
	Set<String> dependencies = this.dependentBeanMap.remove(beanName);
	if (dependencies != null) {
		if (logger.isDebugEnabled()) {
			logger.debug("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) {
			logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
		}
	}

	// Trigger destruction of contained beans...
	Set<String> 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);
}

DisposableBeanAdapter#destroy

public void destroy() {
	if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
		// 调用DestructionAwareBeanPostProcessor来执行销毁方法,就是上文提到的
		for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
			processor.postProcessBeforeDestruction(this.bean, this.beanName);
		}
	}

	if (this.invokeDisposableBean) {
		if (logger.isDebugEnabled()) {
			logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
		}
		try {
			// 执行DisposableBean#destroy方法
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
					@Override
					public Object run() throws Exception {
						((DisposableBean) bean).destroy();
						return null;
					}
				}, acc);
			}
			else {
				((DisposableBean) bean).destroy();
			}
		}
		catch (Throwable ex) {
			String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
			if (logger.isDebugEnabled()) {
				logger.warn(msg, ex);
			}
			else {
				logger.warn(msg + ": " + ex);
			}
		}
	}

	// 执行destroy-method指定的销毁方法
	if (this.destroyMethod != null) {
		invokeCustomDestroyMethod(this.destroyMethod);
	}
	else if (this.destroyMethodName != null) {
		Method methodToCall = determineDestroyMethod();
		if (methodToCall != null) {
			invokeCustomDestroyMethod(methodToCall);
		}
	}
}

你可能感兴趣的:(java,spring)