SpringBoot中的Bean的初始化与销毁顺序解析

我今天学习到SpringBoot里面自定义Bean的初始化与销毁方法

我先总结一下我学到的四种方法:

方法一:

指定init-method 和 destory-method

方法二:

通过让 Bean 实现 InitializingBean 接口,定义初始化逻辑

DisposableBean 接口,定义销毁逻辑

方法三:

用 @PostConstruct,在 Bean 创建完成并且赋值完成后,执行该注解标注的方法

@PreDestroy,在容器销毁 Bean 之前,执行该注解标注的方法

方法四:

通过让 Bean 实现 BeanPostProcessor 接口,在Bean 初始化前后进行一些处理工作

  • postProcessBeforeInitialization: 在初始化之前工作
  • postProcessAfterInitialization: 在初始化之后工作

然后我就在想它们的执行顺序是怎样的:

尝试一:

配置类:

//告诉Spring这是一个配置类
@Configuration
public class MainConfigOfLifeCycle {

        //利用 init-method 和 destory-method
 @Bean(initMethod="initTest", destroyMethod="detoryTest")
 public Car car() {
  return new Car();
 }

        //实现 InitializingBean , DisposableBean 接口
 @Bean
 public Cat cat() {
  return new Cat();
 }

        //利用 @PostConstruct ,@PreDestroy
 @Bean
 public Dog dog() {
  return new Dog();
 }

        //实现 BeanPostProcessor 接口
 @Bean
 public MyBeanPostProcessor myBeanPostProcessor() {
  return new MyBeanPostProcessor();
 }
}

4个 bean:

public class Car{
 public void initTest() {
  System.out.println(" .. init-method .. ");
 }

 public void detoryTest() {
  System.out.println(" .. destory-method .. ");
 }
}
public class Cat implements InitializingBean, DisposableBean {

 //该Bean在销毁时,调用
 public void destroy() throws Exception {
  // TODO Auto-generated method stub
  System.out.println(" .. DisposableBean ..");
 }

 //该Bean创建完成并且赋值完成后,调用
 public void afterPropertiesSet() throws Exception {
  // TODO Auto-generated method stub

  System.out.println(" .. InitializingBean ..");
 }
}
public class Dog {
 //对象创建并赋值之后调用
 @PostConstruct
 public void init() {
  System.out.println(" .. @PostConstruct .. ");
 }

 //容器移除对象之前
 @PreDestroy
 public void detory() {
  System.out.println(" .. @PreDestroy .. ");
 }
}
public class MyBeanPostProcessor implements BeanPostProcessor {

 @Override
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  // TODO Auto-generated method stub

  System.out.println(" .. postProcessBeforeInitialization .. ");
  return bean;
 }

 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  // TODO Auto-generated method stub

  System.out.println(" .. postProcessBeforeInitialization .. ");
  return bean;
 }
}

运行:

public class IOCTest_LifeCycle {
 @Test
 public void test01() {
  // 1. 创建IOC容器
  AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
  System.out.println("容器创建完成");

  // 关闭容器
  applicationContext.close();
 }
}

执行结果:

思考:发现容器在加载 Bean 时是顺序的,因为我在MainConfigOfLifeCycle这个配置类里 @Bean 是顺序的,所有不能确定这次结果是否准确。

尝试二:我把上面四种方法都杂糅到一个类里

配置类:

@Configuration
public class MainConfigOfLifeCycle {
 @Bean(initMethod="initTest", destroyMethod="detoryTest")
 public Car car() {
  return new Car();
 }
}

Bean:

public class Car implements InitializingBean, DisposableBean, BeanPostProcessor {
 public Car() {
  System.out.println("Car 创建");
 }

 public void initTest() {
  System.out.println(" .. init-method .. ");
 }

 public void detoryTest() {
  System.out.println(" .. destory-method .. ");
 }

 @Override
 public void afterPropertiesSet() throws Exception {
  System.out.println(" .. InitializingBean .. ");
 }

 @Override
 public void destroy() throws Exception {
  System.out.println(" .. DisposableBean .. ");
 } 

 @Override
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  System.out.println(" .. postProcessBeforeInitialization .. ");
  return bean;
 }

 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  System.out.println(" .. postProcessAfterInitialization .. ");
  return bean;
 }

 @PostConstruct
 public void postConstructTest() {
  System.out.println(" .. @PostConstruct .. ");
 }

 @PreDestroy
 public void preDestroyTest() {
  System.out.println(" .. @PreDestroy .. ");
 }
}

运行:

public class IOCTest_LifeCycle {
 @Test
 public void test01() {
  // 1. 创建IOC容器
  AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
  System.out.println("容器创建完成");

  // 关闭容器
  applicationContext.close();
 }
}

执行结果:

总结:

创建:

  • Bean 构造函数 ——> @PostConstruct ——> InitializingBean 接口 ——> bean 定义的 init-method——> postProcessBeforeInitialization ——> Bean 初始化完成 ——> postProcessAfterInitialization ——> 容器创建完成

销毁:

  • @PreDestroy ——> DisposableBean 接口 ——> bean 定义的 destoryMethod ——> Bean销毁

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 如何正确控制springboot中bean的加载顺序小结篇

    1.为什么需要控制加载顺序 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能. 在一般业务场景,可能你不大关心一个bean是如何被注册进spring容器的.只需要把需要注册进容器的bean声明为@Component即可,spring会自动扫描到这个Bean完成初始化并加载到spring上下文容器. 而当你在项目启动时需要提前做一个业务的初始化工作时,或者你正在开发某个中间

  • Spring Bean初始化及销毁多种实现方式

    这篇文章主要介绍了Spring Bean初始化及销毁多种实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.前言 日常开发过程有时需要在应用启动之后加载某些资源,或者在应用关闭之前释放资源.Spring 框架提供相关功能,围绕 Spring Bean 生命周期,可以在 Bean 创建过程初始化资源,以及销毁 Bean 过程释放资源.Spring 提供多种不同的方式初始化/销毁 Bean,如果同时使用这几种方式,Spring 如何处理这几

  • 详解Spring Boot 配置加载顺序及属性加载顺序

    先给大家介绍下spring boot 配置加载顺序,具体内容如下所示: 使用 Spring Boot 会涉及到各种各样的配置,如开发.测试.线上就至少 3 套配置信息了.Spring Boot 可以轻松的帮助我们使用相同的代码就能使开发.测试.线上环境使用不同的配置. 在 Spring Boot 里面,可以使用以下几种方式来加载配置.本章内容基于 Spring Boot 2.0 进行详解. 1.properties文件: 2.YAML文件: 3.系统环境变量: 4.命令行参数: 等等-- 我们可

  • 详解Spring Boot中初始化资源的几种方式

    假设有这么一个需求,要求在项目启动过程中,完成线程池的初始化,加密证书加载等功能,你会怎么做?如果没想好答案,请接着往下看.今天介绍几种在Spring Boot中进行资源初始化的方式,帮助大家解决和回答这个问题. CommandLineRunner 定义初始化类 MyCommandLineRunner 实现 CommandLineRunner 接口,并实现它的 run() 方法,在该方法中编写初始化逻辑 注册成Bean,添加 @Component注解即可 示例代码如下: @Component p

  • springboot2.x解决运行顺序及Bean对象注入顺序的问题

    1 前言 通过指定接口,重写指定方法,可以在Bean对应的生命周期方法中执行相应的程序 2 测试 本文将分析几个Bean对象,为它们设置优先级(通过@Order),然后再打断点调试,测试各种生命周期方法的运行的顺序 在项目当中最让人头疼的就是bean对象不被注入的问题,通过本文,你可以很好的解决这个问题. 先看看本程序使用的依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="

  • SpringBoot中的Bean的初始化与销毁顺序解析

    我今天学习到SpringBoot里面自定义Bean的初始化与销毁方法 我先总结一下我学到的四种方法: 方法一: 指定init-method 和 destory-method 方法二: 通过让 Bean 实现 InitializingBean 接口,定义初始化逻辑 DisposableBean 接口,定义销毁逻辑 方法三: 用 @PostConstruct,在 Bean 创建完成并且赋值完成后,执行该注解标注的方法 @PreDestroy,在容器销毁 Bean 之前,执行该注解标注的方法 方法四:

  • Spring中bean的初始化和销毁几种实现方式详解

    Bean的生命周期 : 创建bean对象 – 属性赋值 – 初始化方法调用前的操作 – 初始化方法 – 初始化方法调用后的操作 – --- 销毁前操作 – 销毁方法的调用. [1]init-method和destroy-method 自定义初始化方法和销毁方法两种方式:xml配置和注解. ① xml配置 <bean id="person" class="com.core.Person" scope="singleton" init-meth

  • Spring Bean的初始化和销毁实例详解

    本文实例讲述了Spring Bean的初始化和销毁.分享给大家供大家参考,具体如下: 一 点睛 在开发过程中,经常遇到在Bean使用之前或者之后做一些必要的操作,Spring对Bean的生命周期的操作提供了支持. 1 Java配置方式:使用@Bean的initMethod和destroyMethod. 2 注解方式:利用JSR-250的@PostConstruct和@PreDestroy. 二 实战 1 增加JSR250支持 <dependency> <groupId>javax.

  • 浅谈SpringBoot中的Bean初始化方法 @PostConstruct

    目录 注解说明 代码示例 注解示例 错误示例 正确示例 SpringBoot @PostConstruct虽好,也要慎用 1 问题的产生 2 案例模拟 3 总结 注解说明 使用注解: @PostConstruct 效果:在Bean初始化之后(构造方法和@Autowired之后)执行指定操作.经常用在将构造方法中的动作延迟. 备注:Bean初始化时候的执行顺序: 构造方法 -> @Autowired -> @PostConstruct 代码示例 注解示例 @Component public cl

  • web.xml中servlet, bean, filter, listenr 加载顺序_动力节点Java学院整理

    web.xml 文件中一般包括 servlet, spring, filter, listenr的配置.那么他们是按照一个什么顺序加载呢?加载顺序会影响对spring bean 的调用. 比如filter需要用到 bean ,但是加载顺序是 先加载filter 后加载spring,则filter中初始化操作中的bean为null:首先可以肯定 加载顺序与他们在web.xml 文件中的先后顺序无关. web.xml 中 listener 和 serverlet 的加载顺序为 先 listener

  • springboot中自定义异常以及定制异常界面实现过程解析

    不多说废话,直接进入主菜!! 步骤: 1.搭建SpringBoot的开发环境,略(有不会的可以私信我). 2.编写一个自定义异常,自定义异常需要继承RuntimeException.写一个构造函数,并调用父类保存异常信息. public class MyException extends RuntimeException { public MyException(String massage) { super(massage); } } 3.编写一个控制器,用于抛出异常.当请求参数param=a

  • 总结Bean的三种自定义初始化和销毁方法

    目录 Bean三种自定义初始化和销毁 一. 三种方法概述 二. 方法详述 spring初始化后获取自定义注解Bean 一.新建注解类 二.新建接口类 三.实现接口ApplicationListener Bean三种自定义初始化和销毁 一. 三种方法概述 在配置类中指定 @Bean(initMethod = “init”,destroyMethod = “destory”)注解 实现InitializingBean接口并重写其afterPropertiesSet方法,实现DisposableBea

  • 详解SpringBoot中添加@ResponseBody注解会发生什么

    SpringBoot版本2.2.4.RELEASE. [1]SpringBoot接收到请求 ① springboot接收到一个请求返回json格式的列表,方法参数为JSONObject 格式,使用了注解@RequestBody 为什么这里要说明返回格式.方法参数.参数注解?因为方法参数与参数注解会影响你使用不同的参数解析器与后置处理器!通常使用WebDataBinder进行参数数据绑定结果也不同. 将要调用的目标方法如下: @ApiOperation(value="分页查询") @Re

  • 写了两年代码之后再来谈一谈Spring中的Bean

    目录 (一)什么是Bean (二)如何往Spring容器中添加Bean (三)Bean的作用域 (四)Bean的常用注解 4.1 Conditional 4.2 ComponentScan 4.3 @Import (五)Bean的初始化和销毁 1.自定义初始化方法和销毁方法 2.通过 InitializingBean, DisposableBean 接口实现 3.BeanPostProcessor (六)总结 (一)什么是Bean Spring中的Bean简单来讲就是一个个被Spring容器管理

随机推荐