欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

谈谈我对Spring Bean 生命周期的理解

程序员文章站 2022-05-28 14:14:23
前言 spring的ioc容器功能非常强大,负责spring的bean的创建和管理等功能。而spring 的bean是整个spring应用中很重要的一部分,了解sprin...

前言

spring的ioc容器功能非常强大,负责spring的bean的创建和管理等功能。而spring 的bean是整个spring应用中很重要的一部分,了解spring bean的生命周期对我们了解整个spring框架会有很大的帮助。

beanfactory和applicationcontext是spring两种很重要的容器,前者提供了最基本的依赖注入的支持,而后者在继承前者的基础进行了功能的拓展,例如增加了事件传播,资源访问和国际化的消息访问等功能。本文主要介绍了applicationcontext和beanfactory两种容器的bean的生命周期。

首先看下生命周期图:

谈谈我对Spring 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 生命周期,希望对大家有所帮助