管理Bean生命周期
- 使用XML文件配置: init-method和destroy-method
- 使用@Bean注解: 通过@Bean指定init-method和destroy-method
- 实现InitializingBean、DisposableBean: 让Bean实现InitializingBean(定义初始化逻辑),实现DisposableBean(销毁逻辑)
- 使用@PostConstruct、@PreDestroy: 标注在方法上
- 使用BeanPostProcessor接口(bean的后置处理器): 在bean初始化前后进行一些处理工作
综合示例
对第2、3、4和5种方式举例:
**用于举例的Beans**
package pers.zhang.bean;
/**
第二种
*/
public class Car {
public Car() {
System.out.println("car constructor..");
}
public void init(){
System.out.println("car init...");
}
public void destroy(){
System.out.println("car destroy...");
}
}
package pers.zhang.bean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
第三种
*/
public class Cat implements InitializingBean, DisposableBean {
public Cat(){
System.out.println("cat constructor...");
}
//销毁方法,容器关闭调用
@Override
public void destroy() throws Exception {
System.out.println("cat destory...");
}
//初始化方法,属性赋值完毕掉用
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat init...");
}
}
package pers.zhang.bean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
第四种
*/
public class Dog {
public Dog(){
System.out.println("dog constructor...");
}
//对象创建并赋值之后调用
@PostConstruct
public void init(){
System.out.println("dog PostConstruct...");
}
//在容器移除对象之前调用
@PreDestroy
public void destroy(){
System.out.println("dog PreDestroy...");
}
}
package pers.zhang.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
第五种
*/
//后置处理器,初始化前后进行处理
@Component//加入容器中
public class MyBeanPostProcessor implements BeanPostProcessor {
/*
初始化之前调用
参数:Object,容器刚创建的实例;String,实例的名字;
返回值:返回将要使用的对象,也可以包装一下再返回
*/
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessBeforeInitialization..." + "s," + o);
return o;
}
/*
初始化之后调用
*/
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessAfterInitialization..." + "s," + o);
return o;
}
}
主配置文件:
package pers.zhang.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import pers.zhang.bean.Car;
import pers.zhang.bean.Cat;
import pers.zhang.bean.Dog;
/**
* Bean的生命周期: bean创建---初始化---销毁的过程
*
* 容器管理bean的生命周期;
* 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
*
* 构造(对象创建):
* 单实例:在容器启动的时候创建对象
* 多实例:在每次获取的时候创建对象
* 初始化:
* 对象创建完成,并赋值好,调用初始化方法。
* 销毁:
* 容器关闭的时候(单例);
* 容器不会管理这个bean(多实例),容器不会调用销毁方法;
*
* 1) 、 指定初始化和销毁方法
* 通过@Bean指定init-method和destroy-method
*
* 2) 、让Bean实现InitializingBean(定义初始化逻辑),实现DisposableBean(销毁逻辑)
*
* 3) 、使用@PostConstruct(标注在方法上,在Bean创建完成,属性赋值完毕调用);
* @PreDestroy(标注在方法上,在容器销毁bean之前通知我们进行清理工作)
*
* 4) 、使用BeanPostProcessor接口(bean的后置处理器):在bean初始化前后进行一些处理工作
* 接口中的两个方法:
* Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;初始化方法之前进行后置处理
*
* Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;初始化方法之后进行后置处理
*
* 实现原理:
* 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
* 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
*
* BeanPostProcessor原理
* populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
* initializeBean
* {
* applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
* invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
* applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
* }
*
* Spring底层对 BeanPostProcessor 的使用;
* bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;
*
*/
@Configuration
@ComponentScan("pers.zhang.bean")
public class MainConfigOfLifeCircle {
//指定初始化和销毁方法
@Bean(initMethod = "init", destroyMethod = "destroy")
public Car car(){
return new Car();
}
@Bean
public Cat cat(){
return new Cat();
}
@Bean
public Dog dog(){
return new Dog();
}
}
测试方法:
@Test
public void test01(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfigOfLifeCircle.class);
System.out.println("容器创建完成...");
}
输出:
postProcessBeforeInitialization...s,org.springframework.context.event.EventListenerMethodProcessor@157632c9
postProcessAfterInitialization...s,org.springframework.context.event.EventListenerMethodProcessor@157632c9
postProcessBeforeInitialization...s,org.springframework.context.event.DefaultEventListenerFactory@55040f2f
postProcessAfterInitialization...s,org.springframework.context.event.DefaultEventListenerFactory@55040f2f
postProcessBeforeInitialization...s,pers.zhang.config.MainConfigOfLifeCircle$$EnhancerBySpringCGLIB$$b99b2960@400cff1a
postProcessAfterInitialization...s,pers.zhang.config.MainConfigOfLifeCircle$$EnhancerBySpringCGLIB$$b99b2960@400cff1a
car constructor..//car构造
postProcessBeforeInitialization...s,pers.zhang.bean.Car@14a2f921//初始化前调用
car init...//初始化
postProcessAfterInitialization...s,pers.zhang.bean.Car@14a2f921//初始化后调用
cat constructor...
postProcessBeforeInitialization...s,pers.zhang.bean.Cat@548a102f
cat init...
postProcessAfterInitialization...s,pers.zhang.bean.Cat@548a102f
dog constructor...
postProcessBeforeInitialization...s,pers.zhang.bean.Dog@16aa0a0a
dog PostConstruct...
postProcessAfterInitialization...s,pers.zhang.bean.Dog@16aa0a0a
容器创建完成...