Spring 中 bean 的生命周期
在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例会经历几个执行阶段
英文翻译: PostProcessor:后置处理
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1、Bean自身的方法: Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法
2、Bean级生命周期接口方法: BeanNameAware、BeanFactoryAware、InitializingBean、DiposableBean等接口中的方法
3、容器级生命周期接口方法:InstantiationAwareBeanPostProcessor、BeanPostProcessor等后置处理器实现类中重写的方法
4、工厂后处理器接口方法:AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
1. Bean的建立:
容器寻找Bean的定义信息并将其实例化,默认bean是单例
2. 属性注入:
使用依赖注入,Spring按照Bean定义信息配置Bean所有属性
3. BeanNameAware的setBeanName():
如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。
4. BeanFactoryAware的setBeanFactory():
如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身(BeanFactory)实例。
如果bean实现了ApplicationContextAware接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;
5. BeanPostProcessors的ProcessBeforeInitialization()
如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。
6. initializingBean的afterPropertiesSet():
如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法
7. Bean定义文件中定义init-method:可以在Bean定义文件中使用"init-method"属性设定方法名称。
如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法
8:BeanPostProcessors的ProcessaAfterInitialization()
如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法
此时,Bean已经可以被应用程序使用,并且将保留在BeanFactory(或一直驻留在应用上下文中,直到该应用上下文被销毁;)中直到它不在被使用。
有两种方法可以将其从BeanFactory中删除掉 :
1. DisposableBean的destroy()
在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法
2. Bean定义文件中定义destroy-method
在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称,进行至这个阶段时,就会执行该方法,
测试如下:
【BeanFactoryPostProcessor接口】调用BeanFactoryPostProcessor实现类构造方法
【BeanFactoryPostProcessor接口】调用BeanFactoryPostProcessor接口的postProcessBeanFactory方法
【BeanPostProcessor接口】调用BeanPostProcessor的构造方法
【InstantiationAwareBeanPostProcessor接口】调用InstantiationAwareBeanPostProcessor构造方法
【InstantiationAwareBeanPostProcessor接口】调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法
【Bean构造方法】学生类的无参构造方法
【InstantiationAwareBeanPostProcessor接口】调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法
【set注入】注入学生的name属性
【set注入】注入学生的age属性
【BeanNameAware接口】调用BeanNameAware的setBeanName方法得到Bean的名称
【BeanFactoryAware接口】调用BeanFactoryAware的setBeanFactory方法得到beanFactory引用
【BeanPostProcessor接口】调用postProcessBeforeInitialization方法,这里可对studentBean的属性进行更改。
【InitializingBean接口】调用InitializingBean接口的afterPropertiesSet方法
【init-method】调用init-method属性配置的初始化方法
【BeanPostProcessor接口】调用postProcessAfterInitialization方法,这里可对
的属性进行更改。
【InstantiationAwareBeanPostProcessor接口】调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInitialization方法
-------------------【容器初始化成功】------------------
StudentBean{name='yanxiao', age=21, beanName='studentBean'}
--------------------【销毁容器】----------------------
2018-10-24 16:06:37,045 [Thread-0] INFO [org.springframework.context.support.ClassPathXmlApplicationContext] [AbstractApplicationContext.java:960] - Closing org.springframework.context.support.ClassPathXmlApplicationContext@3a93b025: startup date [Wed Oct 24 16:05:41 CST 2018]; root of context hierarchy
【DisposableBean接口】调用DisposableBean接口的destroy方法
【destroy-method】调用destroy-method属性配置的销毁方法
_____________________________________________________________________________________________________
如果想在生成对象时候完成某些初始化操作,而偏偏这些初始化操作又依赖于依赖注入,那么就无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖注入完成后被自动调用。
Constructor >> @Autowired >> @PostConstruct
1.@PostConstruct说明
被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
2.@PreConstruct说明
被@PreConstruct修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreConstruct修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。(详见下面的程序实践)