Spring与bean有关的生命周期示例详解

 更新时间:2020年07月27日 08:35:17   作者:eaglelihh  
这篇文章主要给大家介绍了关于Spring与bean有关的生命周期的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用Spring具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

前言

记得以前的时候,每次提起Spring中的bean相关的生命周期时,内心都无比的恐惧,因为好像有很多,自己又理不清楚:什么beanFactory啊,aware接口啊,beanPostProcessor啊,afterPropertiesSet啊,initMethod啊等等。

今天终于理清这些关系了,并且又新增了对postConstruct和lifecycle的理解。

执行顺序

- 首先是 BeanFactoryPostProcessor,它是针对所有bean的definition的,只执行一次

下面是针对每个bean的初始

  • - 实现了一系列aware接口的,比如BeanNameAware,ApplicationContextAware,调用其set方法
  • - 执行BeanPostProcessor的postProcessBeforeInitialization方法
  • - 带有@PostConstruct注解的方法
  • - 实现InitializingBean接口的afterPropertiesSet方法
  • - 指定的initMethod方法
  • - 执行BeanPostProcessor的postProcessAfterInitialization方法
  • - 实现了SmartLifecycle接口的start方法(实现Lifecycle接口的不会自动调用,需要显式的调用start方法)

下面是针对每个bean的销毁

  • - 实现了SmartLifecycle接口的stop方法(实现Lifecycle接口的不会自动调用,需要显式的调用stop方法)
  • - 带有@PreDestroy注解的方法
  • - 实现DisposableBean接口的destroy方法
  • - 指定的destroyMethod方法

目前就想到这么多了,其他的麻烦在评论区留言呀~

代码实例

bean实体类

/**
 * @date: 2020-07-22
 * 
 * 一个简单的枚举类 
 */
public enum BeanType {
  NORMAL, LIFECYCLE, SMART_LIFECYCLE;
}

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
 * @author: lihui
 * @date: 2020-07-22
 * 一个简单的bean
 */
@Slf4j
public class NormalBean implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
  private BeanType beanType;

  public NormalBean() {
    this(BeanType.NORMAL);
  }

  public NormalBean(BeanType beanType) {
    this.beanType = beanType;
  }

  @PostConstruct
  public void postConstruct() {
    log.info("{}, postConstruct", beanType);
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    log.info("{}, afterPropertiesSet", beanType);
  }

  public void initMethod() {
    log.info("{}, initMethod", beanType);
  }

  @PreDestroy
  public void preDestroy() {
    log.info("{}, preDestroy", beanType);
  }

  @Override
  public void destroy() throws Exception {
    log.info("{}, destroy", beanType);
  }

  public void destroyMethod() {
    log.info("{}, destroyMethod", beanType);
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    log.info("setApplicationContext, applicationContext : {}", applicationContext);
  }

  @Override
  public void setBeanName(String name) {
    log.info("setBeanName, bean name : {}", name);
  }
}

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.Lifecycle;
/**
 * @author: lihui
 * @date: 2020-07-22
 * 实现了Lifecycle的一个bean
 */
@Slf4j
public class LifecycleBean extends NormalBean implements Lifecycle {
  private volatile boolean running = false;

  public LifecycleBean() {
    super(BeanType.LIFECYCLE);
  }

  @Override
  public void start() {
    log.info("start");
    running = true;
  }

  @Override
  public void stop() {
    log.info("stop");
    running = false;
  }

  @Override
  public boolean isRunning() {
    return running;
  }
}

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
/**
 * @author: lihui
 * @date: 2020-07-22
 * 实现了SmartLifecycle的一个bean
 */
@Slf4j
public class SmartLifecycleBean extends NormalBean implements SmartLifecycle {
  private volatile boolean running = false;

  public SmartLifecycleBean() {
    super(BeanType.SMART_LIFECYCLE);
  }

  @Override
  public void start() {
    log.info("start");
    running = true;
  }

  @Override
  public void stop() {
    log.info("stop");
    running = false;
  }

  @Override
  public boolean isRunning() {
    return running;
  }
}

配置类

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
 * @author: lihui
 * @date: 2020-07-25
 */
@Slf4j
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    log.info("postProcessBeanFactory, beanFactory:{}", beanFactory);
  }
}

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
 * @author: lihui
 * @date: 2020-07-25
 */
@Slf4j
public class MyBeanPostProcessor implements BeanPostProcessor {
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    log.info("postProcessBeforeInitialization, bean:{}", beanName);
    return bean;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    log.info("postProcessAfterInitialization, bean:{}", beanName);
    return bean;
  }
}

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author: lihui
 * @date: 2020-07-22
 */
@Configuration
@Slf4j
public class Config {

  @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
  public NormalBean normalBean() {
    return new NormalBean();
  }

  @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
  public LifecycleBean lifecycleBean() {
    return new LifecycleBean();
  }

  @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
  public SmartLifecycle smartLifecycle() {
    return new SmartLifecycleBean();
  }

  @Bean
  public static MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {
    return new MyBeanFactoryPostProcessor();
  }

  @Bean
  public static MyBeanPostProcessor myBeanPostProcessor() {
    return new MyBeanPostProcessor();
  }
}

Main类

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author: lihui
 * @date: 2020-07-22
 */
@Slf4j
public class Main {
  public static void main(String[] args) throws InterruptedException {
    ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
    ctx.registerShutdownHook();
    Thread.sleep(5000);
    log.info("line ----------------------------- line");
    ctx.start();
    ctx.stop();
    log.info("line ----------------------------- line");
  }
}

结果说明

结果正如前面所说的执行顺序一致,主要注意的就是Lifecycle接口和SmartLifecycle接口,只有实现了SmartLifecycle接口的bean在初始化时才会被自动调用,而实现了Lifecycle接口的除非显式调用start和stop方法才会被调用。

总结

到此这篇关于Spring与bean有关的生命周期的文章就介绍到这了,更多相关Spring与bean生命周期内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JAVA使用geotools读取shape格式文件的方法

    JAVA使用geotools读取shape格式文件的方法

    这篇文章主要介绍了JAVA使用geotools读取shape格式文件的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2017-01-01
  • SpringBoot应用的打包和发布实现

    SpringBoot应用的打包和发布实现

    本文主要介绍了SpringBoot应用的打包和发布实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Maven使用方法详及方式详细介绍

    Maven使用方法详及方式详细介绍

    使用maven仓库的话需要从网上下载maven的包,比如“apache-maven-3.5.4-bin.tar”,下载完成之后解压,在解压的文件夹中的conf目录下的settings.xml文件夹下就可以配置maven远程仓库和本地仓库的地址
    2022-11-11
  • Java实现单例设计模式方法解析

    Java实现单例设计模式方法解析

    这篇文章主要介绍了Java实现单例设计模式方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Spring Cloud Zuul的重试配置详解

    Spring Cloud Zuul的重试配置详解

    这篇文章主要介绍了Spring Cloud Zuul的重试配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • springboot的yml配置文件通过db2的方式整合mysql的教程

    springboot的yml配置文件通过db2的方式整合mysql的教程

    这篇文章主要介绍了springboot的yml配置文件通过db2的方式整合mysql的教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • java使用xpath和dom4j解析xml

    java使用xpath和dom4j解析xml

    XPath是一门在XML文档中查找信息的语言,下面介绍一下java使用xpath和dom4j解析xml的示例,大家参考使用吧
    2014-01-01
  • 排序算法图解之Java插入排序

    排序算法图解之Java插入排序

    插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。本文通过图片合示例讲解了插入排序的实现,需要的可以了解一下
    2022-11-11
  • Java并发之AQS与自旋锁详解

    Java并发之AQS与自旋锁详解

    这篇文章主要介绍了Java并发之AQS与自旋锁详解,类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch,需要的朋友可以参考下
    2023-10-10
  • Value注解支持对象类型ConfigurationProperties功能

    Value注解支持对象类型ConfigurationProperties功能

    这篇文章主要为大家介绍了Value注解支持对象类型ConfigurationProperties功能详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10

最新评论