Bean的生命周期
1、创建
2、初始化
3、销毁
的过程
自定义
1、初始化和销毁方法
1、指定初始化销毁方法
在被声明的Bean里面自己定义初始化和销毁的方法,然后通过@Bean注解的属性,制定初始化和销毁的方法;
初始化方法调用时机:在bean创建完成,然后赋值做好了以后,就会调用init方法;【具体调用流程,详见springBean创建过程】
销毁:spring容器被关闭的时候;
关于销毁方法的执行:需要注意只有单实例的bean,容器关闭时,才会执行销毁方法;如果bean是prototype时,这个时候就不会执行销毁方法。为什么,因为多实例bean,spring容器只管给你创建新的,但是具体啥时候要被销毁,对于
spring容器来讲。由使用者自行决定;spring只负责生产。
public class BeanLife {
public BeanLife() {
System.out.println("BeanLife构造函数执行");
}
public void init(){
System.out.println("指定init方法");
}
public void destroy(){
System.out.println("指定destroy方法");
}
}
@Configuration
public class Config4 {
@Bean(initMethod = "init",destroyMethod = "destroy")
public BeanLife beanLife(){
return new BeanLife();
}
}
public static void main(String[] args) throws Exception{
AnnotationConfigApplicationContext configApplicationContext =
new AnnotationConfigApplicationContext(Config4.class);
String[] beanDefinitionNames = configApplicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
System.out.println("***************************");
//关闭容器
configApplicationContext.close();
}
//控制台输出(关键内容)
BeanLife构造函数执行
指定init方法
指定destroy方法
2、实现接口InitializingBean DisposableBean
InitializingBean 初始化接口,里面有方法afterPropertiesSet
DisposableBean 销毁接口,里面有方法destroy
public class BeanLife implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("实现了InitializingBean接口afterPropertiesSet方法被执行");
}
@Override
public void destroy() throws Exception {
System.out.println("实现了DisposableBean接口destroy方法被执行");
}
}
输出
//控制台输出
BeanLife构造函数执行
实现了InitializingBean接口afterPropertiesSet方法被执行
指定init方法
实现了DisposableBean接口destroy方法被执行
指定destroyCustom方法
1、对于自定义的初始化方法优先级小于实现了接口InitializingBean的afterPropertiesSet方法
2、自定义的销毁方法优先级小于DisposableBean接口destroy方法
3、使用JSR250规范
定义的注解
以下代码直接加载BeanLife类里面
@PostConstruct
public void initJsr250(){
System.out.println("initJsr250规范注解初始化");
}
@PreDestroy
public void destroyJsr250(){
System.out.println("destroyJsr250规范注解初始化");
}
执行流程
BeanLife构造函数执行//构造函数执行
initJsr250规范注解初始化//jsr250规范
实现了InitializingBean接口afterPropertiesSet方法被执行//afterPropertiesSet
指定init方法//自定义的
destroyJsr250规范注解初始化//jsr250规范
实现了DisposableBean接口destroy方法被执行//destroy
指定destroyCustom方法//自定义的
4、beanPostProcessor bean的后置处理器
在bean处理前后,进行的一些处理工作
//注意:使用的时候,一定要让他成为spring容器的组件,否则他就无法工作
BeanPostProcessor接口的方法
//初始化之前
postProcessBeforeInitialization
//初始化之后
postProcessAfterInitialization
在任何初始化调用之前工作;也就是在前面的1-3步骤初始化;
在调用初始化之后,也就是前面1-3步骤之后再调用;
//注意哈,在自己搞的时候,虽然你加了这个组件标识;但是如果是自己搞的启动类时,要记得包扫描,否则就算加了,组件也不会加载到spring容器中哟
//@ComponentScan("com.wolf.bean")
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 在初始化之前
*
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor-postProcessBeforeInitialization:" + beanName);
return bean;
}
/**
* 在初始化之后
*
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor-postProcessAfterInitialization:" + beanName);
return bean;
}
}
在分析springbean的创建过程的时候,通过debug的方法,看看方法调用栈,就能看见方法的执行过程;
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory的方法initializeBean
关键点
1、后置处理器执行,为null时,就不在调用了。直接返回
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//在spring容器找到所有的bean后置处理器(最开始我们怼进行的,这里就包含了)spring容器启动的时候,晓得加
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
//这里重点,如果执行的bean后置处理器,如果返回为null时,管你后面还有好多bean后置处理器,通通不执行,return返回
//applyBeanPostProcessorsAfterInitialization依旧如此
if (current == null) {
return result;
}
result = current;
}
return result;
}
2、大概的执行链路
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory的方法doCreateBean
populateBean(beanName, mbd, instanceWrapper);//给bean的属性赋值
xposedObject = initializeBean(beanName, exposedObject, mbd)//初始化bean
1、Aware 实现对当前实例实现了Aware接口的属性设置
2、applyBeanPostProcessorsBeforeInitialization 执行bean后置处理器before
3、invokeInitMethods 调用初始化方法
--JSR250规范的初始化方法,优先于下面1和2的执行
1、InitializingBean 执行的afterPropertiesSet
2、执行自定义的initMethod
4、applyBeanPostProcessorsAfterInitialization 执行bean后置处理器after