本章节源码github
对于普通的 java 对象,当 new 的时候创建对象,然后该对象就能够使用了。一旦该对象不再被使用,则由 java 自动进行垃圾回收。
而 spring 中的对象是 bean,bean 和普通的 java 对象没啥大的区别,只不过 spring 不再自己去 new 对象了,而是由 ioc 容器去帮助我们实例化对象并且管理它,我们需要哪个对象,去问 ioc 容器要即可。ioc 其实就是解决对象之间的耦合问题,spring bean 的生命周期完全由容器控制。
spring bean的生命周期阶段是:
1.bean定义
:就是从xml或注解定位资源加载读取bean的元信息并定义成一个beandefinition对象2.bean注册
:将beandefinition对象根据相应的规则放到缓存池map中3.实例化
:根据beandefinition实例化真正的bean,即是调用构造函数4.依赖注入
:属性赋值调用tter方法,即是依赖注入(di)5.初始化
: 初始化是用户能自定义扩展的阶段6.销毁
: 销毁是用户能自定义扩展的阶段
注:其他都是在这阶段前后的扩展点
refresh()
public void refresh() throws beanxception, illegalstateexception { synchronized(this.startupshutdownmonitor) { startupstep contextrefresh = this.applicationstartup.start("spring.context.refresh"); // 准备bean初始化相关的环境信息,其内部提供了一个空实现的initpropertysources()方法用于提供给用户一个更改相关环境信息的机会 this.preparerefresh(); // 创建beanfactory实例,并且注册相关的bean信息 configurablelistablebeanfactory beanfactory = this.obtainfreshbeanfactory(); // 注册aware和processor实例,并且注册了后续处理请求所需的一些editor信息 this.preparebeanfactory(beanfactory); try { // 提供的一个空方法,用于供给子类对已经生成的beanfactory的一些信息进行定制 this.postprocessbeanfactory(beanfactory); startupstep beanpostprocess = this.applicationstartup.start("spring.context.beans.post-process"); // 调用beanfactorypostprocessor及其子接口的相关方法,这些接口提供了一个入口,提供给了调用方一个修改已经生成的beandefinition的入口 this.invokebeanfactorypostprocessors(beanfactory); // 对beanpostprocessor进行注册 this.registerbeanpostprocessors(beanfactory); beanpostprocess.end(); // 初始化国际化所需的bean信息 this.initmessagesource(); // 初始化事件广播器的bean信息 this.initapplicationeventmulticaster(); // 提供的一个空方法,供给子类用于提供自定义的bean信息,或者修改已有的bean信息 this.onrefresh(); // 注册事件监听器 this.registerlisteners(); // 对已经注册的非延迟(配置文件指定)bean的实例化 this.finishbeanfactoryinitialization(beanfactory); // 清除缓存的资源信息,初始化一些声明周期相关的bean,并且发布context已被初始化的事件 this.finishrefresh(); } catch (beanxception var10) { if (this.logger.iswarnenabled()) { this.logger.warn("exception encountered during context initialization - cancelling refresh attempt: " + var10); } // 发生异常则销毁已经生成的bean this.destroybeans(); // 重置refresh字段信息 this.cancelrefresh(var10); throw var10; } finally { // 初始化一些缓存信息 this.retcommoncaches(); contextrefresh.end(); } }}
1. 自动加载配置类
2. bean定义和注册
注:springboot只是比spring多了自动配置相关流程,在spring上做了一层逻辑封装。
abstractautowirecapablebeanfactory为autowirecapablebeanfactory接口的一个实现类,其中abstractautowirecapablebeanfactory实现类的一个方法docreatebean()
//位置:abstractautowirecapablebeanfactory#docreatebeanprotected object docreatebean(string beanname, rootbeandefinition mbd, @nullable object[] args) throws beancreationexception { beanwrapper instancewrapper = null; if (mbd.issingleton()) { instancewrapper = (beanwrapper)this.factorybeaninstancecache.remove(beanname); } if (instancewrapper == null) { // 实例化阶段 instancewrapper = this.createbeaninstance(beanname, mbd, args); } ... object expodobject = bean; try { // 依赖注入,属性赋值阶段 this.populatebean(beanname, mbd, instancewrapper); // 初始化阶段 expodobject = this.initializebean(beanname, expodobject, mbd); } catch (throwable var18) { ... } ...}
可以发现,分别调用三种方法:
createbeaninstance() -> 实例化populatebean() -> 依赖注入initializebean() -> 初始化销毁
销毁阶段是在容器关闭时调用的,在configurableapplicationcontext#clo()
至于xxxaware,beanpostprocessor,beanfactorypostprocessor等类,只不过是对主流程的一系列扩展点而已。
spring bean 的生命周期的扩展点很多,这里不可能全部列出来,只说核心的扩展点。这也就是为什铬离子么 spring 的扩展性很好的原因,开了很多的口子,尽可能让某个功能高内聚松耦合,用户需要哪个功能就用哪个,而不是直接来一个大而全的东西。
这些接口的实现类是基于 bean 的,只要实现了这些接口的bean才起作用。
beannameawarebeanfactoryawareapplicationcontextawareinitializingbeandisposablebean还要很多的xxxaware,这些不常用,下面生命周期测试就不加上,如:
beanclassloaderawareenvironmentawareembeddedvalueresolverawareresourceloaderawareapplicationeventpublisherawaremessagesourceawarervletcontextaware这些接口的实现类是独立于 bean 的,并且会注册到 spring 容器中。一般称它们的实现类为后置处理器。
在 spring 容器创建任何 bean 的时候,这些后置处理器都会发生作用
beanpostprocessor
instantiationawarebeanpostprocessor(instantiationawarebeanpostprocessor 是继承了 beanpostprocessor)
工厂后处理器接口也是容器级的。在应用上下文装配配置文件之后立即调用:
aspectjweavingenablerconfigurationclasspostprocessorcustomautowireconfigurer该类是 beanpostprocessor 的子接口,常用的有如下三个方法:
postprocessbeforeinstantiation(class beanclass, string beanname):在bean实例化之前调用postprocessproperties(propertyvalues pvs, object bean, string beanname):在bean实例化之后、设置属性前调用postprocessafterinstantiation(class beanclass, string beanname):在bean实例化之后调用beannameaware接口是为了让自身bean能够感知到,只有一个方法tbeanname(string name),获取到自身在spring容器中的id或name属性。
该接口只有一个方法tbeanfactory(beanfactory beanfactory),用来获取当前环境中的 beanfactory,可以对工厂中的所有bean进行扩展。
该接口只有一个方法tapplicationcontext(applicationcontext applicationcontext),用来获取当前环境中的 applicationcontext,可以对整个容器进行扩展。
注:有时候并不会调用该接口,这要根据你的ioc容器来决定:spring ioc容器最低要求是实现beanfactory接口,而不是实现applicationcontext接口,对于那些没有实现applicationcontext接口的容器,在生命周期对应的app侦查学是干什么的licationcontextaware定义的方法也是不会调用的,只要实现了applicationcontext接口的容器,才会调用。
postprocessbeforeinitialization(object bean, string beanname):在初始化之前调用此方法,spring 的 aop 就是利用它实现的。
postprocessafterinitialization(object bean, string beanname):在初始化之后调用此方法
该接口只有一个方法afterpropertiest(),在属性注入完成后调用。
凡是继承该接口的类,在初始化bean的时候都会执行该方法,可以进行一些属性配置等工作。
initializingbean 对应生命周期的初始化阶段,在源码的invokeinitmethods(beanname, wrappedbean, mbd)方法中调用。
该接口的作用是在对象销毁时调用,可以做一些资源销毁操作。
disposablebean 类似于initializingbean,对应生命周期的销毁阶段,以configurableapplicationcontext#clo()方法作为入口,实现是通过循环取所有实现了disposablebean接口的bean然后调用其destroy()方法
@bean声明一个bean,配合@configuration注解使用
initmethod:声明bean初始化时回调一个方法,该方法需要程序员编写
destroymethod:声明bean销毁时回调一个方法,该方法需要程序员编写
bean的一个基于注解的初始化方法
bean的一个基于注解的销毁方法
@configurationpublic class beaninitanddestroyconfig { /** * @return 这里没有指定bean名字,默认是方法名 */ @description("测试bean的生命周期") @bean(initmethod = "initmethod", destroymethod = "destroymethod") public myrvice myrvicebeanname() {//入参数可注入其他依赖 return new myrvice(); }}声明一个名为:myrvicebeanname的beaninitmethod:bean的初始化方法为:initmethoddestroymethod:bean的销毁方法为:destroymethod
这里只是想用来说明 @qualifier注解能根据bean名称匹配。
即是针对当前bean只调用一次的接口
/** * @description: bean生命周期测试:这些接口只针对当前bean * @author: jianweil * @date: 2021/12/8 9:46 */public class myrvice implements person, beannameaware, beanfactoryaware, applicationcontextaware, initializingbean, disposablebean { private animal animal = null; private applicationcontext applicationcontext; /** *接口规定方法 */ @override public void rvice() { this.animal.u(); } public myrvice() { system.out.println("2. [bean实例化]:"+this.getclass().getsimplename()+"----------构造方法"); } /** *接口规定方法:注入依赖 */ @override @autow小女生化妆ired @qualifier("dog") public void tanimal(animal animal) { system.out.println("5. [bean属性赋值]:dog----依赖注入"); this.animal = animal; } @override public void tbeanname(string s) { system.out.println("6. 调用【beannameaware】--tbeanname:"+s); } @override public void tbeanfactory(beanfactory beanfactory) throws beanxception { system.out.println("7. 调用【beanfactoryaware】--tbeanfactory"); } @override public void tapplicationcontext(applicationcontext applicationcontext) throws beanxception { this.applicationcontext = applicationcontext; system.out.println("8. 调用【applicationcontextaware】--tapplicationcontext"); } /** * 初始化1 */ @postconstruct public void myinit() { system.out.println("10. [初始化] 注解@postconstruct自定义初始化方法[myinit]"); } /** * 初始化2 */ @override public void afterpropertiest() throws exception { system.out.println("11. [初始化] 接口initializingbean方法[afterpropertiest]"); } /** * 初始化3 */ public void initmethod() { system.out.println("12. [初始化] 注解@bean自定义初始化方法[initmethod]"); } /** * 销毁1 */ @predestroy public void mydestroy() { system.out.println("14. [销毁] 注解@predestroy自定义销毁方法[mydestroy]"); } /** * 销毁2 */ @override public void destroy() throws exception { system.out.println("15. [销毁] 接口disposablebean方法[destroy]"); } /** * 销毁3 */ public void destroymethod() { system.out.println("16. [销毁] 注解@bean自定义销毁方法[destroymethod]"); }}
这里实现的接口只作用于当前bean(即是上面@bean定义的bean名为mydefinebeanname)生命周期
每个bean生命周期都执行一次
后置处理器是作用于ioc容器中所有bean的生命周期。
/** * @description: todo * @author: jianweil * @date: 2021/12/20 17:20 */@componentpublic class myinstantiationawarebeanpostprocessor implements instantiationawarebeanpostprocessor { @override public ob四川高考报名网ject postprocessbeforeinstantiation(class<?> beanclass, string beanname) thr池方圆ows beanxception { if ("myrvicebeanname".equals(beanname) || "dog".equals(beanname)) { system.out.println("============================instantiationawarebeanpostprocessor-开始======================"); system.out.println("1. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessbeforeinstantiation() 方法:beanname为"+beanname); } return null; } @override public boolean postprocessafterinstantiation(object bean, string beanname) throws beanxception { if ("myrvicebeanname".equals(beanname) || "dog".equals(beanname)) { system.out.println("3. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessafterinstantiation() 方法:beanname为"+beanname); } return true; } @override public propertyvalues postprocessproperties(propertyvalues pvs, object bean, string beanname) throws beanxception { if ("myrvicebeanname".equals(beanname) || "dog".equals(beanname)) { system.out.println("4. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessproperties() 方法:beanname为"+beanname); system.out.println("============================instantiationawarebeanpostprocessor-结束======================"); } return null; }}
/** * @description: 后置bean的初始化器:所有的bean都会拦截执行 * @author: jianweil * @date: 2021/12/8 9:46 */@componentpublic class mybeanpostprocessor implements beanpostprocessor { @override public object postprocessbeforeinitialization(object bean, string beanname) throws beanxception { //这里过滤掉springboot自动配置的bean,只打印我们项目的bean情况 if ("myrvicebeanname".equals(beanname) || "dog".equals(beanname)) { system.out.println("9. [容器级别每个bean都回调] 调用 beanpostprocessor.postprocessbeforeinitialization 方法:beanname为" + beanname); } return bean; } @override public object postprocessafterinitialization(object bean, string beanname) throws beanxception { if ("myrvicebeanname".equals(beanname) || "dog".equals(beanname)) { system.out.println("13. [容器级别每个bean都回调] 调用 beanpostprocessor.postprocessafterinitialization 方法:beanname为" + beanname); } return bean; }}
容器级别,只允许一次
@componentpublic class mybeanfactorypostprocessor implements beanfactorypostprocessor { @override public void postprocessbeanfactory(configurablelistablebeanfactory beanfactory) throws beanxception { system.out.println("0. [容器级别只调用一次] 调用 beanfactorypostprocessor.postprocessbeanfactory() 方法"); }}
“//”标记为解读
//容器级别的工厂后置处理器,只在应用上下文装配配置文件之后立即调用1次0. [容器级别只调用一次] 调用 beanfactorypostprocessor.postprocessbeanfactory() 方法//因为我们生命过程只打印("myrvicebeanname".equals(beanname) || "dog".equals(beanname)),所有猫只有构造方法打印了猫----------构造方法//###############################dog的生命周期###############################################//后置处理器,容器级别,作用于所有bean============================instantiationawarebeanpostprocessor-开始======================1. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessbeforeinstantiation() 方法:beanname为dog//狗的实例化狗----------构造方法//后置处理器,容器级别,作用于所有bean3. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessafterinstantiation() 方法:beanname为dog//后置处理器,容器级别,作用于所有bean4. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessproperties() 方法:beanname为dog============================instantiationawarebeanpostprocessor-结束======================//后置处理器,容器级别,作用于所有bean9. [容器级别每个bean都回调] 调用 beanpostprocessor.postprocessbeforeinitialization 方法:beanname为dog//后置处理器,容器级别,作用于所有bean13. [容器级别每个bean都回调] 调用 beanpostprocessor.postprocessafterinitialization 方法:beanname为dog//###############################dog的bean完成,开始myrvicebeanname###############################################//后置处理器,容器级别,作用于所有bean============================instantiationawarebeanpostprocessor-开始======================1. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessbeforeinstantiation() 方法:beanname为myrvicebeanname//实例化2. [bean实例化]:myrvice----------构造方法//后置处理器,容器级别,作用于所有bean3. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessafterinstantiation() 方法:beanname为myrvicebeanname//后置处理器,容器级别,作用于所有bean4. [容器级别每个bean都回调] 调用 instantiationawarebeanpostprocessor.postprocessproperties() 方法:beanname为myrvicebeanname============================instantiationawarebeanpostprocessor-结束======================//属性赋值,即是依赖注入5. [bean属性赋值]:dog----依赖注入//bean级别,bean:myrvicebeanname实现了接口beannameaware6. 调用【beannameaware】--tbeanname:myrvicebeanname//bean级别7. 调用【beanfactoryaware】--tbeanfactory//bean级别8. 调用【applicationcontextaware】--tapplicationcontext//后置处理器,容器级别,作用于所有bean:初始化前处理9. [容器级别每个bean都回调] 调用 beanpostprocessor.postprocessbeforeinitialization 方法:beanname为myrvicebeanname//初始化10. [初始化] 注解@postconstruct自定义初始化方法[myinit]11. [初始化] 接口initializingbean方法[afterpropertiest]12. [初始化] 注解@bean自定义初始化方法[initmethod]//后置处理器,容器级别,作用于所有bean:初始化后处理13. [容器级别每个bean都回调] 调用 beanpostprocessor.postprocessafterinitialization 方法:beanname为myrvicebeanname//容器环境加载完成,这时可以使用所有bean2021-12-21 11:18:42.994 info 18956 --- [ main] c.l.s.springbootbeanlifecycleapplication : started springbootbeanlifecycleapplication in 0.719 conds (jvm running for 1.312)//销毁14. [销毁] 注解@predestroy自定义销毁方法[mydestroy]15. [销毁] 接口disposablebean方法[destroy]16. [销毁] 注解@bean自定义销毁方法[destroymethod]process finished with exit code 0
了解 spring 生命周期的意义就在于,可以利用 bean 在其存活期间的指定时刻完成一些相关操作。一般情况下,会在 bean 被初始化后和被销毁前执行一些相关操作。
以上就是深入了解spring的bean生命周期的详细内容,更多关于spring bean生命周期的资料请关注www.887551.com其它相关文章!
本文发布于:2023-04-04 11:13:46,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/8b3803af3154ce235b97c240dd305619.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:深入了解Spring的Bean生命周期.doc
本文 PDF 下载地址:深入了解Spring的Bean生命周期.pdf
留言与评论(共有 0 条评论) |