Bean的生命周期:bean的创建--赋值--初始化(自定义)--销毁
我们有4种方式定义Bean的初始化和销毁方法
- Spring提供注入Bean(xml或者注解)的initMethod属性和destoryMethod属性
- Bean实现 InitializingBean(初始化)和 DisposableBean(销毁)接口
- 使用JSR250规范定义的注解
-
@PostConstruct: 在Bean创建完成,且属于赋值完成后进行初始化,属于JDK规范的注解
-
@PreDestroy: 在bean将被移除之前进行通知, 在容器销毁之前进行清理工作
-
-
实现Spring提供的后置处理器
initMethod & destoryMethod
在bean中自定义需要在初始化和销毁前需要执行的方法,在注入时引用
public class Cat {
private String name;
public Cat() {
System.out.println("Cat-construtor()------------------");
}
public Cat(String name) {
System.out.println("Cat-construtor(name)------------------");
this.name = name;
}
public void init(){
System.out.println("Cat-init()-----------------------------");
}
public void destory(){
System.out.println("Cat-destory()-----------------------------");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("Cat-setName(name)------------------");
}
}
public class Dog {
public Dog() {
System.out.println("Dog-construtor()------------------");
}
public void init(){
System.out.println("Dog-init()-----------------------------");
}
public void destory(){
System.out.println("Dog-destory()-----------------------------");
}
}
@Configuration
public class MyConfigration8 {
@Bean(initMethod = "init",destroyMethod = "destory")
public Cat cat(){
Cat cat = new Cat();
cat.setName("mimi");
return cat;
}
@Scope("prototype")
@Bean(initMethod = "init",destroyMethod = "destory")
public Dog dog(){
return new Dog();
}
}
public class Part8Test {
@Test
public void test() throws Exception {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MyConfigration8.class);
System.out.println("IOC 容器初始化完成....");
app.close();
System.out.println("IOC 容器关闭....");
}
}
结果:
可以发现Cat为单例模型,则Cat Bean在容器初始化时已经开始注入. 而Dog为多例则容器启动时不会初始化。根据结果可以发现
整个生命周期方法的执行顺序为:1.构造器2.属性赋值3.initMethod方法,在关闭IOC容器时执行destoryMethod
Cat-construtor()------------------
Cat-setName(name)------------------
Cat-init()-----------------------------
IOC 容器初始化完成....
Cat-destory()-----------------------------
IOC 容器关闭....
InitializingBean & DisposableBean接口
Bean实现InitializingBean的afterPropertiesSet()方法-- 在Bean实例化完成,并且属性设置完成后执行
Bean实现InitializingBean的DisposableBean()方法-- 在Bean销毁前执行
@Component
public class Fish implements InitializingBean, DisposableBean {
public Fish() {
System.out.println("Fish-construtor()------------------");
}
/**
* 在Bean实例化完成,并且属性设置完成后执行
*/
public void afterPropertiesSet() throws Exception {
System.out.println("Fish-afterPropertiesSet()-----------------------------");
}
/**
* 在Bean销毁前执行
*/
public void destroy() throws Exception {
System.out.println("Fish-afterPropertiesSet()-----------------------------");
}
}
@ComponentScan(value = "com.lb.spring.day3.part9.bean")
@Configuration
public class MyConfigration9 {
}
public class Part9Test {
@Test
public void test() throws Exception {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MyConfigration9.class);
System.out.println("IOC 容器初始化完成....");
app.close();
System.out.println("IOC 容器关闭....");
}
}
结果:
Fish-construtor()------------------
Fish-afterPropertiesSet()-----------------------------
IOC 容器初始化完成....
Fish-afterPropertiesSet()-----------------------------
IOC 容器关闭....
@PostConstruct & @PreDestroy
@Component
public class Tiger {
public Tiger() {
System.out.println("Tiger-construtor()------------------");
}
//在Bean创建完成,且属于赋值完成后进行初始化,属于JDK规范的注解
@PostConstruct
public void init(){
System.out.println("Tiger-init()------------------");
}
//在bean将被移除之前进行通知, 在容器销毁之前进行清理工作
@PreDestroy
public void destory(){
System.out.println("Tiger-destory()------------------");
}
}
@ComponentScan(value = "com.lb.spring.day3.part10.bean")
@Configuration
public class MyConfigration10 {
}
public class Part10Test {
@Test
public void test() throws Exception {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MyConfigration10.class);
System.out.println("IOC 容器初始化完成....");
app.close();
System.out.println("IOC 容器关闭....");
}
}
结果:
Tiger-construtor()------------------
Tiger-init()------------------
Tiger-destory()------------------
IOC 容器关闭....
BeanPostProcessor接口
* BeanPostProcessor为Spring提供的Bean的后置处理器,可以在初始化(init)的前后进行功能加强 * postProcessBeforeInitialization():在init前执行 * postProcessAfterInitialization():在init后执行
public class LbBeanPostProcessor implements BeanPostProcessor{
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("LbBeanPostProcessor---postProcessBeforeInitialization----"+beanName+"----"+bean);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("LbBeanPostProcessor---postProcessAfterInitialization----"+beanName+"----"+bean);
return bean;
}
}
public class Lb2BeanPostProcessor implements BeanPostProcessor{
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Lb2BeanPostProcessor---postProcessBeforeInitialization----"+beanName+"----"+bean);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Lb2BeanPostProcessor---postProcessAfterInitialization----"+beanName+"----"+bean);
return bean;
}
}
@Configuration
public class MyBeanPostProcessorConfig {
@Bean
public LbBeanPostProcessor lbBeanPostProcessor(){
return new LbBeanPostProcessor();
}
@Bean
public Lb2BeanPostProcessor lb2BeanPostProcessor(){
return new Lb2BeanPostProcessor();
}
}
@ComponentScan(value = "com.lb.spring.day3.part11")
@Configuration
public class MyConfigration11 {
@Bean
public Person person(){
return new Person("lb",18);
}
@Bean(initMethod = "init",destroyMethod = "destory")
public Monkey monkey(){
return new Monkey();
}
}
public class Part11Test {
@Test
public void test() throws Exception {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MyConfigration11.class);
System.out.println("IOC 容器初始化完成....");
app.close();
System.out.println("IOC 容器关闭....");
}
}
创建了2个BeanPostProcessor接口的实现类,为了测试先后顺序
结果:
1.BeanPostProcessor的实现类默认使用所有的Bean注入
2.BeanPostProcessor子类的顺序由加载入IOC容器的先后顺序决定, 如果设置@Order会不起作用
LbBeanPostProcessor---postProcessBeforeInitialization----person----Person{name='lb', aga=18}
Lb2BeanPostProcessor---postProcessBeforeInitialization----person----Person{name='lb', aga=18}
LbBeanPostProcessor---postProcessAfterInitialization----person----Person{name='lb', aga=18}
Lb2BeanPostProcessor---postProcessAfterInitialization----person----Person{name='lb', aga=18}
LbBeanPostProcessor---postProcessBeforeInitialization----monkey----com.lb.spring.day3.part11.bean.Monkey@33afa13b
Lb2BeanPostProcessor---postProcessBeforeInitialization----monkey----com.lb.spring.day3.part11.bean.Monkey@33afa13b
Monkey-init()-----------------------------
LbBeanPostProcessor---postProcessAfterInitialization----monkey----com.lb.spring.day3.part11.bean.Monkey@33afa13b
Lb2BeanPostProcessor---postProcessAfterInitialization----monkey----com.lb.spring.day3.part11.bean.Monkey@33afa13b
IOC 容器初始化完成....
Monkey-destory()-----------------------------
IOC 容器关闭....
4个种方式同时满足的顺序为:
public class Pig implements InitializingBean, DisposableBean {
public Pig() {
System.out.println("Pig--construct----------------");
}
public void initMethod(){
System.out.println("Pig--initMethod----------------");
}
public void destoryMethod(){
System.out.println("Pig--destoryMethod----------------");
}
@PostConstruct
public void postConstruct(){
System.out.println("Pig--@PostConstruct----------------");
}
@PreDestroy
public void preDestory(){
System.out.println("Pig--@PreDestroy----------------");
}
public void destroy() throws Exception {
System.out.println("Pig--DisposableBean-destroy----------------");
}
public void afterPropertiesSet() throws Exception {
System.out.println("Pig--InitializingBean-afterPropertiesSet----------------");
}
}
public class LbBeanPostProcessor implements BeanPostProcessor{
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("LbBeanPostProcessor---postProcessBeforeInitialization----"+beanName+"----"+bean);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("LbBeanPostProcessor---postProcessAfterInitialization----"+beanName+"----"+bean);
return bean;
}
}
@Configuration
public class MyConfigration12 {
@Bean(initMethod = "initMethod",destroyMethod = "destoryMethod")
public Pig pig(){
return new Pig();
}
@Bean
public LbBeanPostProcessor lbBeanPostProcessor(){
return new LbBeanPostProcessor();
}
}
结果:
由控制台输出可以看出,当4种方式同时存在时的Bean的整个生命周期的的执行顺序为:
1.构造器方法
2.BeanPostProcessor的postProcessBeforeInitialization方法
3.@PostConstruct修饰的方法
4.InitializingBean的afterPropertiesSet方法
5.Bean的initMethod方法(初始化方法)
6.BeanPostProcessor的postProcessAfterInitialization方法
销毁时:
7.@PreDestory修饰的方法
8.DisposableBean的destory方法
9.Bean的destoryMethod方法
Pig--construct----------------
LbBeanPostProcessor---postProcessBeforeInitialization----pig----com.lb.spring.day3.part12.bean.Pig@1460a8c0
Pig--@PostConstruct----------------
Pig--InitializingBean-afterPropertiesSet----------------
Pig--initMethod----------------
LbBeanPostProcessor---postProcessAfterInitialization----pig----com.lb.spring.day3.part12.bean.Pig@1460a8c0
IOC 容器初始化完成....
Pig--@PreDestroy----------------
Pig--DisposableBean-destroy----------------
Pig--destoryMethod----------------
IOC 容器关闭....