概述

Bean 生命周期管理是 Spring Boot 中的关键功能之一。它负责管理应用程序中的 Java 对象,这些对象被称为 Beans。Spring Boot 通过创建、配置、初始化和销毁这些 Beans 来确保应用程序的正常运行。这个功能的目的是提供一种灵活的方式,使开发人员能够轻松地管理对象的生命周期,从而实现高效的依赖注入和组件化开发。

1、实例化:在 Spring 容器启动时,Spring 会创建配置中定义的所有 Bean。这是通过 Java 类的构造函数或工厂方法来完成的。

2、属性注入:一旦 Bean 被实例化,Spring 会注入所有相关的属性,包括通过构造函数注入或 Setter 方法注入的属性。

3、初始化方法调用:一旦属性被注入,Spring 容器会调用 Bean 的初始化方法。这可以通过@PostConstruct注解、实现InitializingBean接口来完成。初始化过程还提供了一些扩展口:BeanNameAware,BeanFactoryAware,ApplicationContextAware

4、使用 Bean:Bean 现在可以在应用程序中使用,执行其业务逻辑。

5、销毁方法调用:当 Spring 容器关闭时,它会调用 Bean 的销毁方法以释放资源。这可以通过@PreDestroy注解、实现DisposableBean接口来完成。

使用场景

  • 依赖注入:当你需要将一个对象注入到另一个对象中时,Bean 的生命周期管理可以确保被注入的对象已正确初始化。
  • 配置管理:如果你希望根据不同的环境或配置文件来配置 Bean 的属性,Bean 的生命周期管理可以帮助你实现这一目标。
  • 组件扩展:当你需要创建自定义的 Bean,以扩展 Spring Boot 的功能时,Bean 的生命周期管理可以为你提供扩展点。
  • 切面编程:可以在生命周期中预埋代码实现切面编程。例如SpringBoot AOP代理类的实现。

代码演示bean初始化

编写代码演示bean初始化各个节点。

演示代码将创建以下类:

  • TestSupport:一个普通的组件,将作为被观测对象
  • BeanPostProcessorImpl:BeanPostProcessor接口的实现类,用于实现postProcessBeforeInitialization 和postProcessAfterInitialization 并观测TestSupport对象

TestSupport



import com.alibaba.fastjson2.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct; @Slf4j
@RequiredArgsConstructor
@Component
public class TestSupport implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {     private final ApplicationContext  applicationContext;     @Override
    public void setBeanName(String s) {
        log.info("TestSupport-BeanNameAware-setBeanName.param={}", s);
    }     @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        log.info("TestSupport-BeanFactoryAware-setBeanFactory.param={}", "beanFactory");
    }     @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("TestSupport-ApplicationContextAware-setApplicationContext.param={}", JSON.toJSONString(applicationContext.getId()));
    }     @Override
    public void afterPropertiesSet() throws Exception {
        log.info("TestSupport-InitializingBean-afterPropertiesSet");
    }     @PostConstruct
    public void InitSomething() {
        log.info("通过 @PostConstruct 注解执行自定义初始化逻辑");
    }
}
  • BeanNameAware:通过实现BeanNameAware接口并重写setBeanName方法可以获取到bean的name
  • BeanFactoryAware:通过实现BeanFactoryAware接口并重写setBeanFactory方法可以在bean初始化过程中添加额外的扩展,比如可以通过判断beanFactory.alreadyCreated中是否有某bean而做一些不同的操作
  • ApplicationContextAware:通过实现ApplicationContextAware接口并重写setApplicationContext方法可以在bean初始化过程中添加额外扩展。
  • InitializingBean:通过实现InitializingBean接口并重写afterPropertiesSet 方法可以在bean初始化过程中添加额外扩展。比如将此bean存入map中以备它用
  • @PostConstruct:此外还可以通过在方法上面添加@PostConstruct注解来执行一些自定义的业务代码

BeanPostProcessorImpl



import com.ramble.beanlife.support.TestSupport;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class BeanPostProcessorImpl implements BeanPostProcessor {
    /**
     * bean 加工器之在bean实例化之前得预处理
     * 这个处理类针对所有得bean,所以如果需要对特定得bean做处理需要通过 beanName.equals("testSupport")  或者  bean instanceof TestSupport 来过滤
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//        if (beanName.equals("testSupport")) {
//            log.info("执行  TestSupport 初始化前置方法");
//        }
        if (bean instanceof TestSupport) {
            log.info("bean 加工器捕捉到  TestSupport ,做初始化前置方法");
        }
        // do something
        return bean;
    }
    /**
     * bean 加工器之在bean实例化之后得预处理
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
//        if (beanName.equals("testSupport")) {
//            log.info("执行 TestSupport 初始化后置方法");
//        }
        if (bean instanceof TestSupport) {
            log.info("bean 加工器捕捉到  TestSupport ,做初始化后置方法");
        }
        // do something
        return bean;
    }
}
  • postProcessBeforeInitialization:bean 加工器之在bean初始化完毕之前的预处理
  • postProcessAfterInitialization:bean 加工器之在bean初始化之后的预处理
  • 这个扩展点是针对所有的bean的,所以如果需要观测特定的bean在BeanPostProcessor中的情况,需要通过 bean instanceof 或者 beanName equals 进行判断

log


2024-04-07 15:25:33.488 INFO 51628 --- [ main] com.ramble.beanlife.support.TestSupport : TestSupport-BeanNameAware-setBeanName.param=testSupport
2024-04-07 15:25:35.271 INFO 51628 --- [ main] com.ramble.beanlife.support.TestSupport : TestSupport-BeanFactoryAware-setBeanFactory.param=beanFactory
2024-04-07 15:25:35.783 INFO 51628 --- [ main] com.ramble.beanlife.support.TestSupport : TestSupport-ApplicationContextAware-setApplicationContext.param="bean-life-app"
2024-04-07 15:25:36.198 INFO 51628 --- [ main] c.r.b.processor.BeanPostProcessorImpl : bean 加工器捕捉到 TestSupport ,做初始化前置方法
2024-04-07 15:25:36.651 INFO 51628 --- [ main] com.ramble.beanlife.support.TestSupport : 通过 @PostConstruct 注解执行自定义初始化逻辑
2024-04-07 15:25:36.652 INFO 51628 --- [ main] com.ramble.beanlife.support.TestSupport : TestSupport-InitializingBean-afterPropertiesSet
2024-04-07 15:25:38.453 INFO 51628 --- [ main] c.r.b.processor.BeanPostProcessorImpl : bean 加工器捕捉到 TestSupport ,做初始化后置方法

通过log打印的顺序可以观测到bean初始化的各个扩展口的执行顺序。

代码

https://gitee.com/naylor_personal/ramble-spring-boot/tree/master/bean-life

SpringBoot中bean的生命周期的更多相关文章

  1. spring IOC 容器中 Bean 的生命周期

    IOC 容器中 Bean 的生命周期: 1.通过构造器或工厂方法创建 Bean 实例 2.为 Bean 的属性设置值和对其他 Bean 的引用 3.调用 Bean 后置处理器接口(BeanPostPr ...

  2. (spring-第1回【IoC基础篇】)Spring容器中Bean的生命周期

    日出日落,春去秋来,花随流水,北雁南飞,世间万物皆有生死轮回.从调用XML中的Bean配置信息,到应用到具体实例中,再到销毁,Bean也有属于它的生命周期. 人类大脑对图像的认知能力永远高于文字,因此 ...

  3. JAVA面试题:Spring中bean的生命周期

    Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...

  4. Spring IOC容器中Bean的生命周期

    1.IOC容器中Bean的生命周期 构造器函数 设置属性 初始化函数(在Bean配置中 init-method) 使用Bean 结束时关闭容器(在Bean中配置destroy-method) 2.Be ...

  5. 深入理解Spring中bean的生命周期

    [Spring中bean的生命周期] bean的生命周期 1.以ApplocationContext上下文单例模式装配bean为例,深入探讨bean的生命周期: (1).生命周期图: (2).具体事例 ...

  6. Spring中Bean的生命周期及其扩展点

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6106456.html Spring中Bean的管理是其最基本的功能,根据下面的图来了解Spr ...

  7. 简:Spring中Bean的生命周期及代码示例

    (重要:spring bean的生命周期. spring的bean周期,装配.看过spring 源码吗?(把容器启动过程说了一遍,xml解析,bean装载,bean缓存等)) 完整的生命周期概述(牢记 ...

  8. spring BeanFactory及ApplicationContext中Bean的生命周期

    spring bean 的生命周期 spring BeanFactory及ApplicationContext在读取配置文件后.实例化bean前后.设置bean的属性前后这些点都可以通过实现接口添加我 ...

  9. ApplicationContext中Bean的生命周期

    引言 Bean应用上下文中的生命周期和在BeanFactory中生命周期类似,不同的是,如果Bean实现了org.springframework.context.ApplicationContextA ...

  10. 通过BeanPostProcessor理解Spring中Bean的生命周期

    通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理 Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProces ...

随机推荐

  1. 逆向实战31——xhs—xs算法分析

    前言 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 公众号链接 目标网站 aH ...

  2. 【LeetCode剑指offer#06】实现pow函数、计算x的平方根

    实现pow函数 实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,xn ). 示例 1: 输入:x = 2.00000, n = 10 输出:1024.00000 示例 2: 输入:x ...

  3. 苹果工程师对iOS线程开发的那点事津津乐道

    pthread,Thread总结 pthread: 通用的多线程API 使用方法 // 1. 创建线程: 定义一个pthread_t类型变量 pthread_t thread; // 2. 开启线程: ...

  4. 智能升级:AntSK教你如何让聊天机器人实现智能联网操作

    随着人工智能技术的飞速发展,智能体已经逐步融入到我们的日常生活中.不过,要想让智能体不仅能聊天,还能接入网络实时获取信息,为我们提供更多便利,所需技术的复杂性不得不让人瞩目.今天,我将和各位分享如何在 ...

  5. Java 开发人员调度软件项目 (java基础编程总结项目)+javaBean+测试代码+数组知识+数据结构+继承+多态+封装+自定义异常,异常处理+构造器知识+重载+重写+接口+实现接口+关键字使用(static +equalsIgnoreCase+fianl+instanceof判断类型)+向下转型与向上转型

    /** * * @Description Java 开发人员调度软件项目 (java基础编程总结项目) * +javaBean+测试代码+数组知识+数据结构+继承+多态+封装+自定义异常,异常处理 * ...

  6. sed 资源

    sed教程 菜鸟教程正则 MDN正则 正则测试工具 文本替换 s sed有多种分割符,比如你要替换路径字符串时,使用反斜杠很难看,则可以用 : 或者 _ 或者 | 这三个符号都可作为分隔符. & ...

  7. 摆脱鼠标系列 - vscode - ctrl+up 光标上移动4行 ctrl+down 光标下移4行

    为什么 摆脱鼠标系列 - vscode - ctrl+up 光标上移动4行 之前滚动屏幕总是用鼠标,现在改为 ctrl + 上箭头或下箭头 实现起来稍微有些麻烦 实现 需要安装 macros 插件 这 ...

  8. .vscode/extensions.json 是项目用到的 插件 推荐列表,项目应该将此配置 写入用到的插件

    .vscode/extensions.json 是项目用到的 插件 推荐列表,项目应该将此配置 写入用到的插件 .vscode/extensions.json { "recommendati ...

  9. pfx文件导出pem和私钥,更换网站域名证书

    openssl 路径: C:\Program Files\OpenSSL-Win64\bin -- 导出pem证书openssl pkcs12 -in C:\BackUp\Lightning\cert ...

  10. Java 学习分享

    建议语言入门可以先看看视频,学习网站可以是github,极客时间,infoQ等,然后去看书深入研究学习.学习最有效的方式一定是自己动手写代码,而不是看别人的代码,自己下载Intelli Idea多敲敲 ...