此文章为本人原创,转载请说明出处。
https://www.jianshu.com/p/0044e351a028
作者:敲破电脑问到底
BeanFactory的继承关系
我用的Spring 4.3.1.RELEASE版本的
一个bean的一生
通过一个例子了解一下bean生命周期中的一些方法
- 首先定义bean类LifeCycleBean
package cn.com.servyou.xqy.burningchart.service.impl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class BeanLifeCycle implements BeanNameAware, BeanFactoryAware, DisposableBean, InitializingBean {
private int age;
private String name;
private String beanName;
private BeanFactory beanFactory;
public BeanLifeCycle() {
System.out.println("调用构造方法");
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("调用自己的setAge设置age属性");
this.age = age;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("设置BeanFactory,调用BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)");
this.beanFactory = beanFactory;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
System.out.println("设置BeanName,调用了BeanNameAware.setBeanName(String s)");
this.beanName = beanName;
}
public void destroy() throws Exception {
System.out.println("调用摧毁方法,DisposableBean.destroy()");
}
public void afterPropertiesSet() throws Exception {
System.out.println("我的属性已经设置好,调用了InitializingBean.afterPropertiesSet()");
}
@Override
public String toString() {
return ",age:" + this.getAge();
}
}
BeanNameAware, BeanFactoryAware, DisposableBean, InitializingBean
都是bean级别的生命周期中的一些方法的接口。
-
setBeanName
是BeanNameAware
的方法,设置beanName
的时候会调用这个方法。 -
setBeanFactory
是BeanFactoryAware
的方法,设置BeanFactory
的时候会调用这个方法。 -
destroy
方法是DisposableBean
的方法,在bean
被摧毁的时候会调用。 -
afterPropertiesSet
方法是InitializingBean
的方法,在bean
的属性被设置好的时候被调用。
- 设置
BeanFactory
容器级的一些方法,这些方法对所有的bean
都是有效的,我们这里只选择name
为beanLifeCycle
的bean进行一些操作
package cn.com.servyou.xqy.burningchart.service.impl;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import java.beans.PropertyDescriptor;
public class BeanFactoryLifeCycle extends InstantiationAwareBeanPostProcessorAdapter {
public BeanFactoryLifeCycle() {
}
/**
* 实例化bean之前后处理程序
*
* @param aClass
* @param s
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> aClass, String s) throws BeansException {
if ("beanLifeCycle".equals(s)) {
System.out.println("beanLifeCycle还没有被实例化,method:" + "postProcessBeforeInstantiation");
}
return null;
}
/**
* 实例化bean之后的后处理程序
*
* @param o
* @param s
* @return
* @throws BeansException
*/
@Override
public boolean postProcessAfterInstantiation(Object o, String s) throws BeansException {
if ("beanLifeCycle".equals(s)) {
System.out.println("我已经被实例化,method:postProcessAfterInstantiation");
}
//这里要返回true,否则不会调用你bean定义中的设置属性值,也不会调用postProcessPropertyValues
return true;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues propertyValues, PropertyDescriptor[] propertyDescriptors, Object o, String s) throws BeansException {
if ("beanLifeCycle".equals(s)) {
System.out.println("我的属性要被设置,method:" + "postProcessPropertyValues");
}
return propertyValues;
}
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
if ("beanLifeCycle".equals(s)) {
BeanLifeCycle cycle = (BeanLifeCycle) o;
if (cycle.getAge() == 0) {
cycle.setAge(999);
System.out.println("我的age被设置为" + cycle.getAge() + ",method:postProcessBeforeInitialization");
}
}
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
if ("beanLifeCycle".equals(s)) {
BeanLifeCycle cycle = (BeanLifeCycle) o;
if (cycle.getAge() != 0) {
System.out.println("我原来的age" + cycle.getAge());
cycle.setAge(0);
System.out.println("age被更改为" + cycle.getAge() + ",method:postProcessAfterInitialization");
}
}
return o;
}
}
- 通过继承
InstantiationAwareBeanPostProcessorAdapter
类,重写他的四个方法,分别是: -
postProcessBeforeInstantiation
(实例化之前后处理器), -
postProcessAfterInstantiation
(实例化之后后处理器)这里要返回true,否则不会调用你bean定义中的设置属性值,也不会调用postProcessPropertyValues
。 -
postProcessPropertyValues
(设置属性值之前处理器) -
postProcessBeforeInitialization
(初始化之前后处理器) -
postProcessAfterInitialization
(初始化之后后处理器)
需要注意的是每个方法的返回值,要返回参数列表的bean
,不然可能初选NPE问题。 - 还有就是
postProcessBeforeInitialization
(初始化之前后处理器),postProcessAfterInitialization
(初始化之后后处理器)最终是来自于BeanPostProcessor接口,这个接口十分重要,BeanPostProcessor接口无需与代码产生耦合,可作为插件注册到Spring容器,充分对bean进行后加工。
- bean的xml定义:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanLifeCycle" class="cn.com.servyou.xqy.burningchart.service.impl.BeanLifeCycle"
destroy-method="destroy">
<property name="name" value="wang"/>
</bean>
</beans>
- 通过BeanFactory容器调用类,观察它的生命周期
package cn.com.servyou.xqy.burningchart.service;
import cn.com.servyou.xqy.burningchart.service.impl.BeanFactoryLifeCycle;
import cn.com.servyou.xqy.burningchart.service.impl.BeanLifeCycle;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/**
* @author wangwenj
*/
public class Main {
public static void main(String[] args) {
Resource res = new ClassPathResource("spring-config/lifecycle.xml");
BeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory) factory);
reader.loadBeanDefinitions(res);
((ConfigurableBeanFactory) factory).addBeanPostProcessor(new BeanFactoryLifeCycle());
BeanLifeCycle cycle = factory.getBean(BeanLifeCycle.class);
System.out.println(cycle.toString());
//第二次从缓存中拿出第一次的bean
BeanLifeCycle cycle2 = factory.getBean(BeanLifeCycle.class);
System.out.println(cycle2.toString());
((DefaultListableBeanFactory) factory).destroySingleton("beanLifeCycle");
}
}
最后的结果如下所示
beanLifeCycle还没有被实例化,method:postProcessBeforeInstantiation
调用构造方法
我已经被实例化,method:postProcessAfterInstantiation
我的属性要被设置,method:postProcessPropertyValues
设置BeanName,调用了BeanNameAware.setBeanName(String s)
设置BeanFactory,调用BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)
调用自己的setAge设置age属性
我的age被设置为999,method:postProcessBeforeInitialization
我的属性已经设置好,调用了InitializingBean.afterPropertiesSet()
我原来的age999
调用自己的setAge设置age属性
age被更改为0,method:postProcessAfterInitialization
,age:0
,age:0
调用摧毁方法,DisposableBean.destroy()
ApplicationContext与BeanFactory过程也是类似的,只不过多了一个ApplicationContextAware接口,继承此接口Spring会通过setApplicationContext()方法自动注入ApplicationContext上下文。你可以调用get方法获得。