Bean生命周期:
Bean的创建-----初始化-----销毁的过程(具体细节可以查看博客 Spring IOC源码解析)
- 实例化bean:反射的方式生成对象
- 填充bean的属性:populateBean(),循环依赖的问题(三级缓存)
- 调用aware接口相关的方法:invokeAwareMethod(完成BeanName, BeanFactory, BeanClassLoader 对象的属性设置)
- 调用BeanPostProcessor中的前置处理方法:使用比较多的有(ApplicationContextPostProcessor, 设置ApplicationContext, Environment, ResourceLoader, EmbeddValueResolver 等对象)
- 调用initmethod方法:invokeInitmethod(),判断是否实现了initializingBean接口,如果有,调用afterPropertiesSet方法,没有就不调用
- 调用BeanPostProcessor的后置处理方法:spring的aop就是在此处实现的,AbstractAutoProxyCreator 。注册Destuction相关的回调接口:钩子函数
- 获取到完整的对象,可以通过getBean的方式来进行对象的获取
- 销毁流程:
- 判断是否实现了DispoableBean接口
- 调用destroyMethod方法
1、@Bean注解指定初始化和销毁方法
@Bean(initMethod="initMethod" ,destoryMethod="destoryMethod")
@Scope("singleton")
@Bean(name = "person", initMethod = "initM" , destroyMethod = "destoryM")
public Person person(){
return new Person();
}
public class Person {
public Person(){
System.out.println("create Person");
}
public void initM(){
System.out.println("init Method initM");
}
public void destoryM(){
System.out.println("destory method destoryM");
}
}
测试:
@Test
public void test2() throws InterruptedException{
AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(SpringCondiguration.class);
System.out.println("容器启动");
Thread.sleep(1000);
System.out.println("容器关闭");
application.close();
}
输出结果:
可以看出,容器在启动时就创建了bean实例,容器关闭时销毁bean实例。但是需要有个前提是bean单例的,且不是懒加载模式。如果抛开懒加载模式,仅论单例和多实例模式:
- 单例模式下,容器启动时创建并初始化bean,容器关闭时销毁bean
- 多实例模式,容器启动时创建不创建bean,仅在bean被调用时创建和初始化bean,且不管理bean的销毁,即容器关闭时不会销毁bean。
@Scope("prototype")
@Bean(name = "person", initMethod = "initM" , destroyMethod = "destoryM")
public Person person(){
return new Person();
}
@Test
public void test2() throws InterruptedException{
AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(SpringCondiguration.class);
System.out.println("容器启动");
Thread.sleep(1000);
Object person = application.getBean("person");
System.out.println("容器关闭");
application.close();
}
输出结果:
2、InitiallizingBean、DisposableBean初始化和销毁接口
- 实现IniitalizingBean接口重写afterPropertiesSet方法,bean创建时会自动调用该方法初始化bean。
- 实现DisposableBean接口,重写destory方法,bean销毁前会调用该方法。
@Bean
public Person person(){
return new Person();
}
public class Person implements InitializingBean , DisposableBean {
public Person(){
System.out.println("create Person");
}
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
public void destroy() throws Exception {
System.out.println("destroy");
}
}
测试:
@Test
public void test2(){
AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(SpringCondiguration.class);
System.out.println("容器启动");
System.out.println("容器关闭");
application.close();
}
输出结果:
3、JSR250规范中的注解
- @PostConstruct 用于初始化方法,在bean创建完成后执行该注解标注的方法;
- @PreDestroy 用于销毁方法,bean销毁前执行该方法
public class Person{
public Person(){
System.out.println("create Person");
}
@PostConstruct
@PreDestroy
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
}
4、BeanPostProcessor接口
BeanPostProcessor后置处理器,用于Bean的实例化、配置和其他的初始化前后添加一些自己的逻辑处理,
public interface BeanPostProcessor {
//在bean初始化之前调用该方法,参数bean是带处理的实例bean,返回值Object是处理完成后的bean
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//bean初始化之后调用该方法
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
定义一个类实现该接口,重写两个抽象方法,并将该类注入实例,则该类将对Spring容器中所有的bean起作用。
定义一个MyBeanPostProcessor 类实现BeanPostProcessor :
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("before bean initMethod: "+bean.getClass().getName() + " beanName = "+beanName);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("after bean initMethod: "+bean.getClass().getName() + " beanName = "+beanName);
return bean;
}
}
配置类和测试类:
@Configuration
public class SpringCondiguration {
@Bean
public Person person(){
return new Person();
}
@Bean
public MyBeanPostProcessor bookFactoryBean(){
return new MyBeanPostProcessor();
}
}
public class Person {
public Person(){
System.out.println("create person");
}
@PostConstruct
public void afterPropertiesSet() throws Exception {
System.out.println("person init");
}
@PreDestroy
public void destroy() throws Exception {
System.out.println("destroy");
}
}
测试:
@Test
public void test2(){
AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(SpringCondiguration.class);
}
输出结果:
从输出结果可以看出Spring创建Person实例时方法的调用顺序:Person的构造方法------->postProcessBeforeInitialization------>初始化方法 ------->postProcessAfterInitialization。而且,我们手动注入到容器中的bean只有Person和MyBeanPostProcessor,而MyBeanPostProcessor的作用范围包含了Spring自己定义的bean。
BeanPostProcessor在Spring中的应用非常广泛,后续会有专门的章节介绍Spring中对该接口的应用和原理。