1、借用一张BeanFactory中bean的生命周期流程图:
[BeanFactory生命周期流程图]
2、BeanFactory生命周期涉及组件说明:
2.1、InstantiationAwareBeanPostProcessorbean:实例化后置处理器
主要职责:
1、postProcessBeforeInstantiation接口方法就是在bean实例化之前做相应的处理。
2、postProcessAfterInstantiation接口方法就是在bean实例化之后做相应处理。
3、postProcessPropertyValues接口方法就是在bean实例化之后设置bean属性之前做相应处理。
用法:实现InstantiationAwareBeanPostProcessor接口,此处应该注意,InstantiationAwareBeanPostProcessor继承了后面的一个组件BeanPostProcessor接口,如果实现InstantiationAwareBeanPostProcessor此接口就一定也要实现BeanPostProcessor的函数,但是此时bean还没有到BeanPostProcessor函数的处理周期,因此会让人有混淆InstantiationAwareBeanPostProcessor的职责,因此,为了区分开来InstantiationAwareBeanPostProcessor与BeanPostProcessor的职责,spring提供了一个InstantiationAwareBeanPostProcessorAdapter抽象类适配器来区分,因此,我们只需要继承InstantiationAwareBeanPostProcessorAdapter抽象类,重写职责中的三个函数,并且通过工厂的addBeanPostProcessor将其添加到BeanFactory即可。
2.2、BeanNameAware:bean名称设置感知器
主要职责:在设置bean属性值之后提供设置bean name的操作。
用法:需要有设置Bean name 的bean实现此接口重写setBeanName函数即可。
2.3、BeanFactoryAware:bean 工厂实例感知器
主要职责:在BeanNameAware之后让bean 知道自己所在的Bean工厂。
用法:需要知道自己所在的bean 工厂的bean实现此接口重写setBeanFactory函数即可。
2.4、BeanPostProcessor:bean 初始化后置处理器
主要职责:
1、postProcessBeforeInitialization接口方法就是在bean 初始化之前做相应处理。
2、postProcessAfterInitialization接口方法就是在 初始化完成之后做相应处理。
用法:自定义实现BeanPostProcessor接口,然后后通过factory的addBeanPostProcessor将其添加到BeanFactory即可。
2.5、InitializingBean:bean初始化处理器
主要职责:afterPropertiesSet()方法可提供bean初始化功能。
用法:需要提供初始化的bean实现此接口重写afterPropertiesSet()完成自己的业务逻辑。
2.6、<bean/>的init-method 属性
<bean/> 标签定义的初始化函数属性 ,@PostConstruct只针对ApplicationContext加载的时候才能被处理。
主要职责: 使用xml的方式配置bean的初始化函数,在InitializingBean.afterPropertiesSet()之后 BeanPostProcessor.postProcessAfterInitialization()之前做相应处理。
用法:在需要初始化的bean中定义好初始化函数,然后在<bean/>中配置在此属性即可。
2.7、DisposableBean:bean销毁处理器
主要职责:在容器销毁bean之前做相应处理。
用法:有需要做bean销毁前做业务处理的bean实现此接口重写destroy()函数可。
2.8、<bean/>destroy-method属性
<bean/>标签属性定义bean销毁前处理逻辑,@PreDestroy只针对ApplicationContext加载的时候才能被处理。。
主要职责:在DisposableBean之后bean销毁i前做相应处理。
用法:同init-method属性
2.9、BeanFactory.getBean()流程
Car car = factory.getBean(Car.class);
beanFactory.getBean()触发如下:
1、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法。
2、实例化bean。
3、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法。
4、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法。
5、如果bean实现了BeanNameAware接口,调用bean的setBeanName()函数。
6、如果bean实现了BeanFactoryAware接口,调用bean的setBeanFactory()函数。
7、调用添加的所有BeanPostProcessor.postProcessBeforeInitialization()方法。
8、如果bean实现了InitializingBean接口,调用bean的afterPropertiesSet()方法。
9、如果<bean/>上定义的init-method 属性,则调用bean中的init-method属性值的方法。
10、调用添加的所有BeanPostProcessor.postProcessAfterInitialization()方法。
销毁bean触发如下:
11、如果bean实现了DisposableBean接口,则调用bean中的destroy()方法。
12、如果<bean/>上定义的destroy-method 属性,则调用bean中的destroy-method属性值的方法。
2.10、BeanFactory.getBean()方法测试结果
getBean触发如下流程测试输出:
1、InstantiationAwareBeanPostProcessor 的 before。。。 每个bean生命周期中都会触发一次
2、Construct... 每个bean生命周期中都会触发一次
3、InstantiationAwareBeanPostProcessor 的 after。。。 每个bean生命周期中都会触发一次
4、InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues。。。 每个bean生命周期中都会触发一次
5、BeanPostProcessor 的 before。。。 每个bean生命周期中都会触发一次
6、InitializingBean 的afterPropertiesSet。。。 bean如果配置了则生命周期中都会触发一次
7、<bean/> init-method 属性。。。 bean如果配置了则生命周期中都会触发一次
8、BeanPostProcessor 的 after。。。 每个bean生命周期中都会触发一次
9、DisposableBean 的 destroy。。。 bean如果配置了则生命周期中都会触发一次
10、<bean/> destroy-method 属性。。。 bean如果配置了则生命周期中都会触发一次
3、测试代码:
public class Bar implements InitializingBean,DisposableBean {
private String price;
public Bar() {
System.out.println("Construct...");
}
public String getPrice() { return price;}
public void setPrice(String price) {this.price = price;}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean 的 destroy。。。");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean 的afterPropertiesSet。。。");
}
public void myinit(){ System.out.println("<bean/> init-method 属性。。。");}
public void mydestroy(){ System.out.println("<bean/> destroy-method 属性。。。");}
}
public class MyInstantiationAwareBeanPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
@Override
public Object postProcessBeforeInstantiation(Class <?> aClass,
String s)throws BeansException {
if (s.equals("bar")){
System.out.println("InstantiationAwareBeanPostProcessor 的 before。。。");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object o, String s)
throws BeansException {
if (s.equals("bar")){
System.out.println("InstantiationAwareBeanPostProcessor 的 after。。。");
}
return false;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues propertyValues,
PropertyDescriptor[] propertyDescriptors,
Object o, String s)
throws BeansException {
if (s.equals("bar")){
System.out.println("InstantiationAwareBeanPostProcessor 的
postProcessPropertyValues。。。");
}
return propertyValues;
}
}
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o, String s)
throws BeansException {
if (s.equals("bar")){
System.out.println("BeanPostProcessor 的 before。。。");
}
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s)
throws BeansException {
if (s.equals("bar")){
System.out.println("BeanPostProcessor 的 after。。。");
}
return o;
}
}
<bean id="bar" class="com.wzy.springstudy.beanfactoryprocess.Bar" p:price="123"
init-method="myinit" destroy-method="mydestroy"/>
测试代码如下:
ResourcePatternResolver rpr = new PathMatchingResourcePatternResolver()
Resource res = rpr.getResource("classpath:spring-context.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
BeanFactory 加载完毕,只是注册了所有bean 的 beanDefinition,bean 并没有实例化,这就是第一次惩罚的问题,此处与ApplicationContext有 区别的,ApplicationContext在加载完毕以后就会实例化所有的bean,因为在加载ApplicationContext的时候会给所有的bean相应调一次getBean(),以避免第一次惩罚的问题,延迟加载的bean除外。