Bean生命周期、自定义初始化方法、BeanPostProcessor后置处理器原理及应用。 浅尝Spring注解开发,基于Spring 4.3.12
包含Bean生命周期、自定义初始化方法、Debug BeanPostProcessor执行过程及在Spring底层中的应用
浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配
浅尝Spring注解开发_Bean生命周期及执行过程
了解Bean的生命周期,就可以在Bean声明周期的不同阶段进行自定义的操作,满足更复杂的需求。简单的将Bean生命周期分为三个阶段:Bean创建、初始化、销毁
- 对象创建:单实例在容器启动的时候创建对象,多实例在每次获取的时候创建对象
- 初始化之前:BeanPostProcessor.postProcessBeforeInitialization()
- 初始化:对象创建完成,并赋值好,调用初始化方法
- 初始化之后:BeanPostProcessor.postProcessAfterInitialization()
- [容器创建完成]
- 销毁:单实例在容器关闭的时候销毁,多实例容器不会管理这个bean,容器不会调用销毁方法
现在可以通过下面方法在初始化和销毁时自定义初始化方法来干涉Bean创建过程。
- @Bean()注解参数
- InitializingBean、DisposableBean接口
- @PostConstruct、@PreDestroy注解
- BeanPostProcessor接口
通过@Bean指定init-method和destroy-method的初始化方法
先自定义Bean初始化和销毁方法
@Componentpublic class Car { public Car(){ System.out.println("car constructor..."); } //现在只是普通方法 public void init(){ System.out.println("car ... init..."); } //现在只是普通方法 public void detory(){ System.out.println("car ... destory..."); }}配置进容器
@Configurationpublic class MainConfigOfLifeCycle { //@Scope("prototype")多实例,不管销毁 //指定用于初始化和销毁的方法 @Bean(initMethod="init",destroyMethod="destory") public Car car(){ return new Car(); }}测试
public class IOCTest_LifeCycle { @Test public void test01(){ //1、创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器创建完成..."); //applicationContext.getBean("car"); //关闭容器 applicationContext.close(); }}输出
//先创建对象car constructor...//再自定义初始化方法car ... init...//创建完成容器创建完成...//关闭时自定义销毁方法car ... destory...接口,需实现,通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑);
实现接口,自定义初始化Bean
public class Cat implements InitializingBean,DisposableBean { public Cat(){ System.out.println("cat constructor..."); } //定义销毁逻辑 @Override public void destroy() throws Exception { // TODO Auto-generated method stub System.out.println("cat...destroy..."); } //定义初始化逻辑 @Override public void afterPropertiesSet() throws Exception { // TODO Auto-generated method stub System.out.println("cat...afterPropertiesSet..."); }}配置进容器
//配置组件@Componentpublic class Cat implements InitializingBean,DisposableBean { //...}//扫描进容器@ComponentScan("com.xxx.bean")@Configurationpublic class MainConfigOfLifeCycle { //...}测试
public class IOCTest_LifeCycle { @Test public void test01(){ //1、创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器创建完成..."); //applicationContext.getBean("car"); //关闭容器 applicationContext.close(); }}输出
//注意顺序,每个Bean先构造并初始化,然后才进行下一个Bean,关闭时从内向外(猫)cat constructor...(猫)cat...afterPropertiesSet...(车)car constructor...(车)car ... init...//创建完成 容器创建完成...//关闭时销毁(车)car ... destory...(猫)cat...destroy...可以使用JSR250;
@PostConstruct:在bean创建完成并且属性赋值完成之后,来执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
标注注解,自定义初始化Bean
public class Dog { public Dog(){ System.out.println("dog constructor..."); } //对象创建并赋值之后调用 @PostConstruct public void init(){ System.out.println("Dog....@PostConstruct..."); } //容器移除对象之前 @PreDestroy public void detory(){ System.out.println("Dog....@PreDestroy..."); }}配置进容器
@Componentpublic class Dog { //...}//扫描进容器@ComponentScan("com.xxx.bean")@Configurationpublic class MainConfigOfLifeCycle { //...}测试
public class IOCTest_LifeCycle { @Test public void test01(){ //1、创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器创建完成..."); //applicationContext.getBean("car"); //关闭容器 applicationContext.close(); }}输出
//注意顺序,每个Bean先构造并初始化,然后才进行下一个Bean,关闭时从内向外(猫)cat constructor...(猫)cat...afterPropertiesSet...(狗)dog constructor...(狗)Dog....@PostConstruct...(车)car constructor...(车)car ... init...//创建完成容器创建完成...//关闭时销毁(车)car ... destory...(狗)Dog....@PreDestroy...(猫)cat...destroy...postProcessBeforeInitialization:在创建Bean实例之后,在自定义初始化之前进行调用
postProcessAfterInitialization:在自定义初始化之后进行调用
BeanPostProcessor接口:bean的后置处理器,需实现,在bean初始化前后进行一些处理工作
postProcessBeforeInitialization:在(自定义初始化,如InitializingBean[afterPropertiesSet]、init-method等,就是上面那些自定义初始化方法)初始化之前工作(创建Bean实例之后,在自定义初始化之前)
postProcessAfterInitialization:在(自定义)初始化之后工作
实现后置处理器接口
public class MyBeanPostProcessor implements BeanPostProcessor { //初始化前置方法 //bean:新创建的实例,还未初始化 //beanName:未初始化的Bean名字 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean); return bean; } //初始化后置方法 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean); return bean; } }配置进容器
@Componentpublic class MyBeanPostProcessor implements BeanPostProcessor { //...}//扫描进容器@ComponentScan("com.xxx.bean")@Configurationpublic class MainConfigOfLifeCycle { //...}测试
public class IOCTest_LifeCycle { @Test public void test01(){ //1、创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器创建完成..."); //applicationContext.getBean("car"); //关闭容器 applicationContext.close(); }}输出
//对于每一个Bean都要执行一遍//1.创建//2.BeanPostProcessor.postProcessBeforeInitialization()//3.初始化:对象创建完成,并赋值好,调用初始化方法...//4.BeanPostProcessor.postProcessAfterInitialization()//5.销毁//以其中一个Bean为例://构造对象cat constructor...//初始化之前postProcessBeforeInitialization...cat=>com.xxx.bean.Cat@7d68ef40//使用InitializingBean自定义初始化逻辑cat...afterPropertiesSet...//初始化之后postProcessAfterInitialization...cat=>com.xxx.bean.Cat@7d68ef40//创建完成容器创建完成...//关闭时销毁cat ... destroy...bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxxBeanPostProcessor都通过BeanPostProcessor实现
详细视频 https://www.bilibili.com/video/BV1gW411W7wy?p=16
主要方法
populateBean(beanName, mbd, instanceWrapper):给bean进行属性赋值initializeBean:初始化Bean{ applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);初始化前应用后置处理器 invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);初始化后应用后置处理器}遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,一但返回null,跳出for循环了解BeanPostProcessor的执行过程,从AnnotationConfigApplicationContext开始Debug
public class IOCTest_LifeCycle { @Test public void test01(){ //1、创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器创建完成..."); //applicationContext.getBean("car"); //关闭容器 applicationContext.close(); }}AnnotationConfigApplicationContext()构造方法,执行里面的refresh()方法刷新容器refresh()方法里面有一个finishBeanFactoryInitialization(beanFactory)初始化所有剩余的单实例对象,进入这个方法beanFactory.preInstantiateSingletons()初始化所有单实例Bean,进入这个方法getBean(beanName),getBean(beanName)里面再调用doGetBean(name,null,null,false)doGetBean(name,null,null,false)里面有getSingleton(beanName,new ObjectFactory(){singletonFactory.getObject()})通过匿名内部类调用getObject()getObject()进入下一个调用栈AbstractBeanFactory$1.getObject(),如果是单例,调用createBean(beanName,mbd,args)createBean(beanName,mbd,args)调用doCreateBean(beanName,mbd,args)创建一个实例,过程如下doCreateBean(beanName,mbd,args),里面调用一个initializeBean(beanName,exposedObject,mbd)初始化方法,这个方法里面就是调用的后置处理器populateBean(beanName,mbd,instanceWrapper)方法,这个方法为Bean属性赋值initializeBean(beanName,exposedObject,mbd),下面有一个invokeInitMethods(beanName,wrappedBean,mbd)执行初始化方法(就是上面的自定义初始化InitializingBean[afterPropertiesSet]、init-method)invokeInitMethods(beanName,wrappedBean,mbd)[在初始化之前应用 BeanPost 处理器]上面有一个applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName)下面有一个applyBeanPostProcessorsAfterInitialization(wrappedBean,beanName)[在初始化之后应用 BeanPost 处理器],作用是在初始化之前应用所有的BeanPostProcessors在初始化之后应用所有的BeanPostProcessorsapplyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName)getBeanPostProcessors()找到所有BeanPostProcessors遍历,包括Spring系统的BeanPostProcessor如ApplicationContextAwareProcessor、ConfigurationClassPostProcessor等,然后才是自定义的MyBeanPostProcessor,依次执行beanProcessor.postProcessBeforeInitialization()BeanPostProcessors了)获取单例

创建实例Bean

给Bean属性赋值和初始化Bean

Spring底层对 BeanPostProcessor 的使用;

许多注解底层都是基于BeanPostProcessor
BeanPostProcessor接口实现类

在Bean创建过程中,初始化之前,判断是否实现了某Aware接口,如果实现了,就向Bean中注入ApplicationContext容器
向Bean中注入IoC容器
实现ApplicationContextAware接口,声明属性,赋值,就可以在组件中使用Ioc容器
@Componentpublic class Dog implements ApplicationContextAware { //声明IoC容器 private ApplicationContext applicationContext; public Dog(){ System.out.println("dog constructor..."); } //对象创建并赋值之后调用 @PostConstruct public void init(){ System.out.println("Dog....@PostConstruct..."); } //容器移除对象之前 @PreDestroy public void detory(){ System.out.println("Dog....@PreDestroy..."); } //把applicationContext IoC容器赋值给属性 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub this.applicationContext = applicationContext; }}原理是通过ApplicationContextAwareProcessor实现
ApplicationContextAwareProcessor实现了BeanPostProcessor接口

在postProcessBeforeInitialization()方法中
ApplicationContextAware接口,或其他Aware接口invokeAwareInterfaces(bean)给Bean注入值((ApplicationContextAware)bean).setApplicationContext(this.applicationContext)注入IoC容器BeanValidationPostProcessor也实现了BeanPostProcessor接口postProcessBeforeInitialization()方法,进行数据校验postProcessBeforeInitialization(){doValidate(bean)}postProcessAfterInitialization(){doValidate(bean)}@PostConstruct注解,也是通过BeanPostProcessor实现InitDestroyAnnotationBeanPostProcessor处理@PostConstruct和@PreDestroy注解postProcessBeforeInitialization()中找到Bean的生命周期注解所标注的方法,如initMethods、destroyMethodsmetatata.invokeInitMethods(bean,beanName)和element.invoke(target),利用反射执行。AutowiredAnnotationBeanPostProcessor实现BeanPostProcessors接口@Autowired标注的所有属性进行注入值