IOC Bean管理 - Bean生命周期
Bean生命周期
Bean实例的生命周期大致分为以下几个步骤
- 调用无参构造器(调用默认构造器)
- 使用Set方法为Bean属性赋值(调用Set方法)
- 调用初始化方法初始化实例(初始化)
- 获取到实例(获取并使用)
- Bean实例的销毁(使用完毕销毁)
逐个实现
创建测试类
BeanLifeCycle类:
package com.xjy.spring.beanLifeCycle;
public class beanLifeCycleDemo {
private String str;
public void setStr(String str) {
this.str = str;
}
}
创建Bean:
<bean id="BeanLifeCycle" class="com.xjy.spring.beanLifeCycle.beanLifeCycleDemo">
<property name="str" value="LifeCycle"></property>
</bean>
第一步
调用无参构造器(调用默认构造器)
在测试类中创建一个无参构造器:
public beanLifeCycleDemo() {
System.out.println("第一步:调用无参构造器");
}
第二步
调用Set方法为Bean内属性赋值
设置测试类的成员变量Set方法
public void setStr(String str) {
System.out.println("第二步:调用Set方法赋值");
this.str = str;
}
第三步
调用初始化方法为初始化实例
初始化方法需要手动编写,这里写一个测试方法:initMethod()
public void initMethod(){
System.out.println("第三步:调用初始化方法");
}
编写完成后因为这是自己写的方法,所以需要配置XML让Bean调用该方法
<bean id="BeanLifeCycle" class="com.xjy.spring.beanLifeCycle.beanLifeCycleDemo" init-method="initMethod">
- init-method:指定Bean创建时的初始化方法
添加init-method属性并设置为自己编写的初始化方法initMethod()
第四步
获取Bean实例
就是使用getBean获取实例,编写主函数代码:
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("SpringConfig.xml");
beanLifeCycleDemo demo =
context.getBean("BeanLifeCycle", beanLifeCycleDemo.class);
if (demo != null)
System.out.println("第四步:获取Bean实例");
}
第五步
销毁Bean
使用完毕后进行销毁,使用Close方法销毁
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("SpringConfig.xml");
beanLifeCycleDemo demo =
context.getBean("BeanLifeCycle", beanLifeCycleDemo.class);
if (demo != null)
System.out.println("第四步:获取Bean实例");
System.out.println(demo);
context.close();
}
这里做了一些修改,context配置文件读取方法类型从ApplicationContext变为ClassPathXmlApplicationContext,因为ClassPathXmlApplicationContext是ApplicationContext的实现类,而要用的close方法定义在ClassPathXmlApplicationContext中。
销毁时需要设置一个销毁方法,而该方法需要我们手动编写》
实现销毁方法:public void destroy(){ System.out.println("第五步:销毁Bean"); }
因为这个方法是自己编写的,所以仍然需要在配置中指定此方法:
<bean id="BeanLifeCycle" class="com.xjy.spring.beanLifeCycle.beanLifeCycleDemo" init-method="initMethod" destroy-method="destroy">
destroy-Method:制定Bean销毁时的销毁方法
到此五步已全部实现:
完整的TestDemo:
package com.xjy.spring.beanLifeCycle;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class beanLifeCycleDemo {
public beanLifeCycleDemo() {
System.out.println("第一步:调用无参构造器");
}
private String str;
public void setStr(String str) {
System.out.println("第二步:调用Set方法赋值");
this.str = str;
}
public void initMethod(){
System.out.println("第三步:调用初始化方法");
}
public void destroy(){
System.out.println("第五步:销毁Bean");
}
@Test
public static void testDemo(ClassPathXmlApplicationContext context){
beanLifeCycleDemo demo =
context.getBean("BeanLifeCycle", beanLifeCycleDemo.class);
if (demo != null)
System.out.println("第四步:获取Bean实例");
System.out.println(demo);
context.close();
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("SpringConfig.xml");
testDemo(context);
}
}
输出:
第一步:调用无参构造器 第二步:调用Set方法赋值 第三步:调用初始化方法 第四步:获取Bean实例 com.xjy.spring.beanLifeCycle.beanLifeCycleDemo@74f0ea28 第五步:销毁Bean 进程已结束,退出代码0
其他
Bean在被创建时除了这五个基本步骤,还有两个步骤。
这两个步骤由后置处理器完成
分别在第三步初始化之前和第三步初始化之后
具体
引用之前的五个步骤:
- 调用无参构造器(调用默认构造器)
- 使用Set方法为Bean属性赋值(调用Set方法)
- 把Bean实例传递给后置处理器-postProcessBeforeInitialization方法
- 调用初始化方法初始化实例(初始化)
- 把Bean实例传递给后置处理器-postProcessAfterInitialization
- 获取到实例(获取并使用)
- Bean实例的销毁(使用完毕销毁)
要实现这两个步骤,需要手动实现一个BeanPostProcessor接口:
实现:
package com.xjy.spring.beanLifeCycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行postprocessorBefore方法");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postprocessorAfter方法");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
在XML中为后置处理器创建标签:
<!--后置处理器-->
<bean id="PostProcessor" class="com.xjy.spring.beanLifeCycle.MyBeanPost"></bean>
注意:
因为实现了beanpostprocessor接口,所以只需要在XML中配置MyBeanPost的Bean标签,Spring就会将它设为默认后置处理器;
再次运行TestDemo:
输出
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
执行postprocessorBefore方法
postprocessorAfter方法
第一步:调用无参构造器
第二步:调用Set方法赋值
执行postprocessorBefore方法
第三步:调用初始化方法
postprocessorAfter方法
第四步:获取Bean实例
com.xjy.spring.beanLifeCycle.beanLifeCycleDemo@f6efaab
第五步:销毁Bean
之前很多次后置处理器出发是因为XML中存在多个单实例bean,上篇讲到单实例bean在读取配置文件时就会被创建。所以触发了多次。
主要看后面几行
第一步:调用无参构造器 第二步:调用Set方法赋值 执行postprocessorBefore方法 第三步:调用初始化方法 postprocessorAfter方法 第四步:获取Bean实例 com.xjy.spring.beanLifeCycle.beanLifeCycleDemo@f6efaab 第五步:销毁Bean
至此,加入后置处理器一共是7步