谈谈我对Spring Bean 生命周期的理解
前言
spring的ioc容器功能非常强大,负责spring的bean的创建和管理等功能。而spring 的bean是整个spring应用中很重要的一部分,了解spring bean的生命周期对我们了解整个spring框架会有很大的帮助。
beanfactory和applicationcontext是spring两种很重要的容器,前者提供了最基本的依赖注入的支持,而后者在继承前者的基础进行了功能的拓展,例如增加了事件传播,资源访问和国际化的消息访问等功能。本文主要介绍了applicationcontext和beanfactory两种容器的bean的生命周期。
首先看下生命周期图:
再谈生命周期之前有一点需要先明确:
spring 只帮我们管理单例模式 bean 的 完整 生命周期,对于 prototype 的 bean ,spring 在创建好交给使用者之后则不会再管理后续的生命周期。
注解方式
在 bean 初始化时会经历几个阶段,首先可以使用注解 @postconstruct , @predestroy 来在 bean 的创建和销毁阶段进行调用:
@component public class annotationbean { private final static logger logger = loggerfactory.getlogger(annotationbean.class); @postconstruct public void start(){ logger.info("annotationbean start"); } @predestroy public void destroy(){ logger.info("annotationbean destroy"); } }
initializingbean, disposablebean 接口
还可以实现 initializingbean,disposablebean 这两个接口,也是在初始化以及销毁阶段调用:
@service public class springlifecycleservice implements initializingbean,disposablebean{ private final static logger logger = loggerfactory.getlogger(springlifecycleservice.class); @override public void afterpropertiesset() throws exception { logger.info("springlifecycleservice start"); } @override public void destroy() throws exception { logger.info("springlifecycleservice destroy"); } }
自定义初始化和销毁方法
也可以自定义方法用于在初始化、销毁阶段调用:
@configuration public class lifecycleconfig { @bean(initmethod = "start", destroymethod = "destroy") public springlifecycle create(){ springlifecycle springlifecycle = new springlifecycle() ; return springlifecycle ; } } public class springlifecycle{ private final static logger logger = loggerfactory.getlogger(springlifecycle.class); public void start(){ logger.info("springlifecycle start"); } public void destroy(){ logger.info("springlifecycle destroy"); } }
以上是在 springboot 中可以这样配置,如果是原始的基于 xml 也是可以使用:
<bean class="com.crossoverjie.spring.springlifecycle" init-method="start" destroy-method="destroy"> </bean>
来达到同样的效果。
实现 *aware 接口
*aware 接口可以用于在初始化 bean 时获得 spring 中的一些对象,如获取 spring 上下文 等。
@component public class springlifecycleaware implements applicationcontextaware { private final static logger logger = loggerfactory.getlogger(springlifecycleaware.class); private applicationcontext applicationcontext ; @override public void setapplicationcontext(applicationcontext applicationcontext) throws beansexception { this.applicationcontext = applicationcontext ; logger.info("springlifecycleaware start"); } }
这样在 springlifecycleaware 这个 bean 初始化会就会调用 setapplicationcontext 方法,并可以获得 applicationcontext 对象。
beanpostprocessor 增强处理器
实现 beanpostprocessor 接口,spring 中所有 bean 在做初始化时都会调用该接口中的两个方法,可以用于对一些特殊的 bean 进行处理:
@component public class springlifecycleprocessor implements beanpostprocessor { private final static logger logger = loggerfactory.getlogger(springlifecycleprocessor.class); /** * 预初始化 初始化之前调用 * @param bean * @param beanname * @return * @throws beansexception */ @override public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception { if ("annotationbean".equals(beanname)){ logger.info("springlifecycleprocessor start beanname={}",beanname); } return bean; } /** * 后初始化 bean 初始化完成调用 * @param bean * @param beanname * @return * @throws beansexception */ @override public object postprocessafterinitialization(object bean, string beanname) throws beansexception { if ("annotationbean".equals(beanname)){ logger.info("springlifecycleprocessor end beanname={}",beanname); } return bean; } }
执行之后观察结果:
018-03-21 00:40:24.856 [restartedmain] info c.c.s.p.springlifecycleprocessor - springlifecycleprocessor start beanname=annotationbean 2018-03-21 00:40:24.860 [restartedmain] info c.c.spring.annotation.annotationbean - annotationbean start 2018-03-21 00:40:24.861 [restartedmain] info c.c.s.p.springlifecycleprocessor - springlifecycleprocessor end beanname=annotationbean 2018-03-21 00:40:24.864 [restartedmain] info c.c.s.aware.springlifecycleaware - springlifecycleaware start 2018-03-21 00:40:24.867 [restartedmain] info c.c.s.service.springlifecycleservice - springlifecycleservice start 2018-03-21 00:40:24.887 [restartedmain] info c.c.spring.springlifecycle - springlifecycle start 2018-03-21 00:40:25.062 [restartedmain] info o.s.b.d.a.optionallivereloadserver - livereload server is running on port 35729 2018-03-21 00:40:25.122 [restartedmain] info o.s.j.e.a.annotationmbeanexporter - registering beans for jmx exposure on startup 2018-03-21 00:40:25.140 [restartedmain] info com.crossoverjie.application - started application in 2.309 seconds (jvm running for 3.681) 2018-03-21 00:40:25.143 [restartedmain] info com.crossoverjie.application - start ok! 2018-03-21 00:40:25.153 [thread-8] info o.s.c.a.annotationconfigapplicationcontext - closing org.springframework.context.annotation.annotationconfigapplicationcontext@3913adad: startup date [wed mar 21 00:40:23 cst 2018]; root of context hierarchy 2018-03-21 00:40:25.155 [thread-8] info o.s.j.e.a.annotationmbeanexporter - unregistering jmx-exposed beans on shutdown 2018-03-21 00:40:25.156 [thread-8] info c.c.spring.springlifecycle - springlifecycle destroy 2018-03-21 00:40:25.156 [thread-8] info c.c.s.service.springlifecycleservice - springlifecycleservice destroy 2018-03-21 00:40:25.156 [thread-8] info c.c.spring.annotation.annotationbean - annotationbean destroy
直到 spring 上下文销毁时则会调用自定义的销毁方法以及实现了 disposablebean 的 destroy() 方法。
总结
以上所述是小编给大家介绍的spring bean 生命周期,希望对大家有所帮助