目的
在大三开始学习 spring 时,老师就说 spring bean 周期非常重要,当时也有仔细看,但是说实话搞不大懂,后面工作面试也问过,还是有点模糊,就是没有掌握好,进行深入理解,这次 “老大” 又问到了。不允许再回避了,所以这次坚决搞明白,理解生命周期作用,为啥要这样设计,我们能在生命周期做哪些更高层次的编程。
生命周期流程图
先总体看下 spring 的生命周期流程图,实现(继承)这些接口(抽象类)并在容器里注册,就可以看到 bean 的生命周期会按下面流程进行,后面会给出测试代码。

可以看出设计策略是 “先顾大局”- 类似的操作 BeanFactory 一般出现在 Bean 之前,操作完 Bean 之后,BeanFactory 会进行 “管理”;Bean 操作的前提是应用了 BeanPostProcessor。
测试代码
要被注册的 Person 类
package springBeanTest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {
private String name;
private String address;
private int phone;
private BeanFactory beanFactory;
private String beanName;
public Person() {
System.out.println("【构造器】调用Person的构造器实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【注入属性】name");
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.out.println("【注入属性】address");
this.address = address;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
System.out.println("【注入属性】phone");
this.phone = phone;
}
// 这是BeanFactoryAware接口方法
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【BeanFactoryAware接口】调用setBeanFactory方法");
this.beanFactory = beanFactory;
}
// 这是BeanNameAware接口方法
public void setBeanName(String s) {
System.out.println("【BeanNameAware接口】调用setBeanName方法");
this.beanName = s;
}
// 这是DiposibleBean接口方法
public void destroy() throws Exception {
System.out.println("【DiposibleBean接口】调用destroy方法");
}
// 这是InitializingBean接口方法
public void afterPropertiesSet() throws Exception {
System.out.println("【InitializingBean接口】调用afterPropertiesSet方法");
}
// 通过<bean>的init-method属性指定的初始化方法
public void myInit() {
System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
}
// 通过<bean>的destroy-method属性指定的初始化方法
public void myDestory() {
System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
}
}
实现 BeanFactoryPostProcessor 的类
package springBeanTest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
public MyBeanFactoryPostProcessor() {
super();
System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out
.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
BeanDefinition bd = configurableListableBeanFactory.getBeanDefinition("person");
bd.getPropertyValues().addPropertyValue("phone", "110");
}
}
继承 InstantiationAwareBeanPostProcessorAdapter 的类
package springBeanTest;
import java.beans.PropertyDescriptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
public class MyInstantiationAwareBeanPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out
.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
}
// 接口方法、实例化Bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
return null;
}
// 接口方法、实例化Bean之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
return bean;
}
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
return pvs;
}
}
实现 BeanPostProcessor 的类
package springBeanTest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor{
public MyBeanPostProcessor(){
System.out.println("这是BeanPostProcessor实现类构造器!!");
}
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改");
return o;
}
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改");
return o;
}
}
测试类 BeanLifeCycle
package springBeanTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifeCycle {
public static void main(String[] args) {
System.out.println("现在开始初始化容器");
ApplicationContext factory = new ClassPathXmlApplicationContext("beans.xml");
System.out.println("容器初始化成功");
//得到Preson,并使用
Person person = factory.getBean("person",Person.class);
System.out.println(person);
System.out.println("现在开始关闭容器!");
((ClassPathXmlApplicationContext)factory).registerShutdownHook();
}
}
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="beanPostProcessor" class="springBeanTest.MyBeanPostProcessor">
</bean>
<bean id="instantiationAwareBeanPostProcessor" class="springBeanTest.MyInstantiationAwareBeanPostProcessor">
</bean>
<bean id="beanFactoryPostProcessor" class="springBeanTest.MyBeanFactoryPostProcessor">
</bean>
<bean id="person" class="springBeanTest.Person" init-method="myInit"
destroy-method="myDestory" scope="singleton" p:
p:phone="123567889"/>
</beans>
生命周期的接口和抽象类
大概了解了生命周期的流程和运用到哪些接口和抽象类之后,下面开始进一步深入了解他们的具体作用,按照流程往下一一介绍。
这里 spring 版本是 4.1.8.RELEASE。
BeanFactoryPostProcessor 接口
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
该接口只有一个 postProcessBeanFactory 方法,BeanFactoryPostProcessor:在 bean factory 标准初始化之后可以进行修改。将加载所有 bean 定义,但是还没有实例化 bean。这个方法允许重新覆盖或者添加属性甚至快速的初始化 bean。
初次看不知干嘛,关键在于参数,可以利用参数做一些操作。
下面了解一下这个参数。ConfigurableListableBeanFactory 提供分析、修改 bean 定义和预先实例化单例。这个 BeanFactory 的子接口不应该是被使用于普通应用程序中:BeanFactory 和 ListableBeanFactory 铁铮铮作为最经典的用例; 这个接口是仅应该允许内部框架使用,即使在访问 bean factory 配置方法时也如此。
ConfigurableListableBeanFactory 的方法
freezeConfiguration():冻结全部 bean 定义,给被注册的 bean 定义发信号告诉它们今后不再被修改和进一步后续处理。它允许 factory 去积极缓存 bean 定义元数据。
getBeanDefinition(String beanName):根据指定的 bean name 返回被注册的 bean 定义,允许访问其属性值和构造函数参数值(可以在 bean 工厂后期处理期间被修改)。这个被返回的 bean definition 对象不应该是副本而是原始在工厂被注册的。这意味着如果需要它可以被转换为更具体的实现类型。注意这个方法只能获得本地工厂 bean definition。
Iterator getBeanNamesIterator():返回由这个 bean factory 管理的所有 bean name 统一视图。
void ignoreDependencyType(Class<?> type)
:忽略被给定注入依赖类型 ,例如 String。void ignoreDependencyInterface(Class<?> ifc)
:忽略被给定注入依赖接口 。这个通常被使用由 application contexts 去注册依赖,可以以多种方式实现。例如 BeanFactory 通过 BeanFactoryAware,ApplicationContext 通过 ApplicationContextAware。默认情况下,仅 BeanFactoryAware 接口是被忽略,需要忽略其他接口,调用此方法。boolean isAutowireCandidate(String beanName,DependencyDescriptor descriptor)throws NoSuchBeanDefinitionException
:确认这个被指定的 bean 是否是一个 autowire 候选,将被注入到其他声明匹配类型的依赖的 bean 中。isConfigurationFrozen():返回该工厂的 bean definnitions 是否被冻结。
preInstantiateSingletons():确保所有非懒加载的单例 bean 被实例化,包括 factoryBeans。
void registerResolvableDependency(Class<?> dependencyType,Object autowiredValue)
:注册一个特定类型依赖伴随着相应的 autowired 值。这个是准备被用于应该可以 autowire 而不是在这个工厂被定义的 bean 的工厂 / 上下文引用。例如 将 ApplicationContext 类型的依赖项解析为 Bean 所在的 ApplicationContext 实例。注意~ 在普通的 BeanFactory 中没有注册这样的默认类型,甚至连 BeanFactory 接口本身都没有。
postProcessBeanFactory 使用示例
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
// TODO: 2018/6/7 覆盖属性值
System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
BeanDefinition bd = configurableListableBeanFactory.getBeanDefinition("person");
bd.getPropertyValues().addPropertyValue("phone", "110");
// TODO: 2018/6/7 快速初始化bean
configurableListableBeanFactory.preInstantiateSingletons();
}
BeanPostProcessor 接口
允许自定义修改新 bean 实例的 Factory hook,例如检查标记接口或者把 bean 包装成代理。
ApplicationContext 可以在它们的 beans definitions 自动检测 BeanPostProcessor bean 并且把这些 bean 应用于随后的 bean 创建。普通的 bean factory 允许对后处理器进行程序化注册,通过工厂应用于所有 bean 创建。
BeanPostProcessor 的方法
postProcessBeforeInitialization(Object bean, String beanName):在一些 bean 实例化回调(例如 InitializingBean 的 afterPropertiesSet 或者一个定制的 init-method)之前应用这个 BeanPostProcessor
postProcessAfterInitialization(Object bean, String beanName):在一些 bean 实例化回调(例如 InitializingBean 的 afterPropertiesSet 或者一个定制的 init-method)之后应用这个 BeanPostProcessor
BeanPostProcessor 用法示例
postProcessBeforeInitialization 一
class BeanValidationPostProcessor...
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!this.afterInitialization) {
doValidate(bean);
}
return bean;
}
/**
* Perform validation of the given bean.
* @param bean the bean instance to validate
* @see javax.validation.Validator#validate
*/
protected void doValidate(Object bean) {
Set<ConstraintViolation<Object>> result = this.validator.validate(bean);
if (!result.isEmpty()) {
StringBuilder sb = new StringBuilder("Bean state is invalid: ");
for (Iterator<ConstraintViolation<Object>> it = result.iterator(); it.hasNext();) {
ConstraintViolation<Object> violation = it.next();
sb.append(violation.getPropertyPath()).append(" - ").append(violation.getMessage());
if (it.hasNext()) {
sb.append("; ");
}
}
throw new BeanInitializationException(sb.toString());
}
}
检验 bean 状态是否有效。postProcessBeforeInitialization 二
class ApplicationContextAwareProcessor...
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
判断 bean 是什么接口,然后进行 set 属性。应该就是 api 里面说的检查标记接口。大概意识是 bean 已经实例成功,你可以做一些校验或者补充些内容或者把 bean 包装代理注入。包装代理直接把代理实例返回就行。
postProcessAfterInitialization 和 postProcessBeforeInitialization 类似。
InstantiationAwareBeanPostProcessorAdapter
实现 SmartInstantiationAwareBeanPostProcessor 全部方法的适配器,这将不改变由容器正常处理每一个实例化的 bean。子类仅覆盖自己想要的方法。
注意,只有在实际需要 InstantiationAwareBeanPostProcessor 功能时,才推荐这个基类。如果您所需要的只是简单的 BeanPostProcessor 功能,那么您应该选择直接实现那个 (更简单的) 接口。
postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
:在实例化目标 bean 之前应用此 BeanPostProcessor。这个返回的 bean 也许是一个代理代替目标 bean,有效地抑制目标 bean 的默认实例化。如果此方法返回一个非空对象,则 bean 的创建过程将被短路。唯一的进一步处理被应用是 BeanPostProcessor.postProcessAfterInitialization(java.lang.Object, java.lang.String) 方法(可以自己试下,改变了 bean 的生命周期实例化之后直接进入 BeanPostProcessor.postProcessAfterInitialization)回调来自于配置好的 BeanPostProcessors。这个回调将仅被应用于有 bean class 的 bean defintions。特别是,它不会应用于采用”factory-method“的 beans。后处理器可以实现扩展的 SmartInstantiationAwareBeanPostProcessor 接口,以便预测它们将返回的 bean 对象的类型。postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
:在工厂将给定的属性值应用到给定的 bean 之前,对给定的属性值进行后处理。允许检查全部依赖是否已经全部满足,例如基于一个 @Required 在 bean 属性的 setter 上。还允许替换要应用的属性值,通常通过基于原始的 PropertyValues 创建一个新的 MutablePropertyValues 实例,添加或删除特定的值。postProcessAfterInitialization(Object bean, String beanName)
:在 bean 初始化回调(例如:InitializingBean 的 afterPropertiesSet 或者定制的 init-method)之后,应用这个 BeanPostProcessor 去给一个新的 bean 实例。bean 已经配置了属性值,返回的 bean 实例可能已经被包装。如果是 FactoryBean,这个回调将为 FactoryBean 实例和其他被 FactoryBean 创建的对象所调用。这个 post-processor 可以通过相应的 FactoryBean 实例去检查决定是否应用 FactoryBean 或者被创建的对象或者两个都有。这个回调在一个由 InstantiationAwareBeanPostProcessor 短路的触发之后将被调用。看到这里我也没看懂是啥意思,下面我们看看源代码。
postProcessBeforeInstantiation 使用示例
class AbstractAutoProxyCreator...
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = this.getCacheKey(beanClass, beanName);
if(beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if(this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if(this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
if(beanName != null) {
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if(targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
这个可以返回代理。
postProcessPropertyValues 使用示例
示例一
class RequiredAnnotationBeanPostProcessor ...
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
if (!this.validatedBeanNames.contains(beanName)) {
if (!shouldSkip(this.beanFactory, beanName)) {
List<String> invalidProperties = new ArrayList<String>();
for (PropertyDescriptor pd : pds) {
if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
invalidProperties.add(pd.getName());
}
}
if (!invalidProperties.isEmpty()) {
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
}
}
this.validatedBeanNames.add(beanName);
}
return pvs;
}
这个方法很明显校验需要注入的属性是否有属性值。示例二
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
if (bean instanceof EnhancedConfiguration) {
((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
}
return pvs;
}
在 AutowiredAnnotationBeanPostProcessor 的 postProcessPropertyValues 方法试图自 auto-wire 其他配置 bean 之前注入 BeanFactory。
postProcessAfterInitialization 使用示例
public Object postProcessAfterInitialization(Object bean, String beanName) {
if(bean instanceof AopInfrastructureBean) {
return bean;
} else {
if(bean instanceof Advised) {
Advised advised = (Advised)bean;
if(!advised.isFrozen() && this.isEligible(AopUtils.getTargetClass(bean))) {
if(this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
} else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
if(this.isEligible(bean, beanName)) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
proxyFactory.setTarget(bean);
if(!proxyFactory.isProxyTargetClass()) {
this.evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
return proxyFactory.getProxy(this.getProxyClassLoader());
} else {
return bean;
}
}
}
如果 bean 是一个基础的 aop bean 那么就直接返回,如果不是基础的 aop bean 并且实现了 Advise 接口那么就对这个 bean 进行一些操作,如果不是基础的 aop bean 没实现 Advise 接口并且是合格的 bean 就用代理工厂进行代理,如果不是基础的 aop bean 没实现 Advise 接口并且不是合格的 bean 那么也直接返回。
总之对已经实例化的 bean 进行一些处理,可能这个 bean 在早期已经实例化了又是单例,那么就销毁这个 bean 用原来的 bean。
BeanNameAware 接口
接口是被实现由那些想知道其在 bean factory 中的名称的 bean 实现。请注意,通常不建议对象依赖于它的 bean 名称,因为这表示对外部配置的潜在脆弱依赖性,以及对 Spring API 可能不必要的依赖。
setBeanName(String name):在创建这个 bean 的 bean factory 里设置名字。在填充正常 bean 属性之后调用但是在初始化回调之前例如 InitializingBean 的 afterPropertiesSet 方法或者一个定制的 init-method.
示例
class SchedulerFactoryBean ...
public void setBeanName(String name) {
if(this.schedulerName == null) {
this.schedulerName = name;
}
}
对工厂 bean 进行 set name
BeanFactoryAware 接口
接口由希望知道其拥有的 BeanFactory 的 bean 实现。
例如 beans 可以通过这个工厂去查阅和它合作的 beans(查阅依赖)。注意大部分 beans 将选择通过协作相应 bean 属性或者构造函数参数(依赖注入)去接收协作 beans 的引用。
setBeanFactory(BeanFactory beanFactory) : 为 bean 实例提供所属工厂的回调。在普通的 bean 属性值填充之后但是在初始化回调之前(例如 InitializingBean 的 afterPropertiesSet 方法或者一个定制的 init-method 方法)被调用
setBeanFactory 示例
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if(!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalStateException("Cannot use AdvisorAutoProxyCreator without a ConfigurableListableBeanFactory");
} else {
this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
}
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
获得所属的 beanFactory 并拷贝到本对象中。可以通过这个 bean 所属的 beanFactory 检查 bean 依赖的 bean、beanClassLoader、互斥的单例等。
InitializingBean 接口
接口被实现由那些需要响应所有已经被 BeanFactory set 的属性:例如执行自定义初始化或者仅检查是否已经 set 所有必要属性。
实现 InitializingBean 的另一种方法是指定一个自定义的 init-method,例如在一个 XML 配置文件中指定 bean 的 init-method。
afterPropertiesSet():在设置完所有提供的 bean 属性(并满足 BeanFactoryAware 和 ApplicationContextAware)之后由 beanFactory 调用。这个方法允许 bean 实例只有在所有的 bean 属性都被设置并且在错误配置的情况下抛出异常的情况下才能执行初始化。
afterPropertiesSet 示例
public void afterPropertiesSet() {
if(this.getDataSource() == null) {
throw new IllegalArgumentException("Property 'dataSource' is required");
}
}
检查是否已经 set 所有必要属性。
/**
* Eagerly create the singleton instance, if necessary.
*/
@Override
public void afterPropertiesSet() throws Exception {
if (isSingleton()) {
this.initialized = true;
this.singletonInstance = createInstance();
this.earlySingletonInstance = null;
}
}
这里没做什么自定义初始化和检查是否已经 set 所有必要属性,而是提前初始化单例 bean,说明你可以做一些其他操作。
DisposableBean 接口
接口已经被实现由那些想在销毁释放资源的 bean。如果 BeanFactory 处理缓存的单例对象,那么它应该调用 destroy 方法。应用程序上下文在关闭的时候应该处理它的所有单例。
实现 InitializingBean 的另一种方法是指定一个自定义的 destroy-method,例如在一个 XML 配置文件中指定 bean 的 destroy-method。
destroy 示例
@Override
public void destroy() {
close();
}
/**
* Close this application context, destroying all beans in its bean factory.
* <p>Delegates to {@code doClose()} for the actual closing procedure.
* Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
* @see #doClose()
* @see #registerShutdownHook()
*/
@Override
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
/**
* Actually performs context closing: publishes a ContextClosedEvent and
* destroys the singletons in the bean factory of this application context.
* <p>Called by both {@code close()} and a JVM shutdown hook, if any.
* @see org.springframework.context.event.ContextClosedEvent
* @see #destroyBeans()
* @see #close()
* @see #registerShutdownHook()
*/
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.
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.
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.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
this.active.set(false);
}
}
执行上下文关闭:发布一个 ContextClosedEvent 和破坏了这个应用上下文的 bean 工厂中的单例。
作者:qq_23473123
来源链接:
https://blog.youkuaiyun.com/qq_23473123/article/details/76610052