高级Spring之Bean 生命周期

news2025/1/18 3:48:43

         老样子,话不多说,直接上代码:

         准备容器:

@SpringBootApplication
public class A03 {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(A03.class, args);
        context.close();
    }
}

   准备Bean:

@Component
public class LifeCycleBean {
    private static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);

    public LifeCycleBean() {
        log.debug("构造");
    }

    @Autowired
    public void autowire(@Value("${JAVA_HOME}") String home) {
        log.debug("依赖注入: {}", home);
    }

    @PostConstruct
    public void init() {
        log.debug("初始化");
    }

    @PreDestroy
    public void destroy() {
        log.debug("销毁");
    }
}

         这些方法的执行顺序是怎样的? 对于生命周期而言,首先执行的肯定是构造方法,再执行依赖注入方法,依赖注入完之后执行bean的初始化方法,当Spring容器关闭后,执行销毁方法,销毁方法默认情况是在bean是单例的情况下调用,其他的情况下调用时机是不太一样的。

输出结果如下:

 

说完bean生命周期的四个方法后,还有一个与生命周期相关的,那就是bean的后处理器,它有很多的扩展功能,通过bean生命周期各个阶段的方法扩展,怎么扩展的呢?以下面的代码为例:

/**
*bean 后处理器
*
*/
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {

    private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<< 销毁之前执行, 如 @PreDestroy");
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.debug("<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段");
//            return false;
        }
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
        return bean;
    }
}

输出结果:

   

创建前后的增强

  • postProcessBeforeInstantiation

    • 这里返回的对象若不为 null 会替换掉原本的 bean,并且仅会走 postProcessAfterInitialization 流程

  • postProcessAfterInstantiation

    • 这里如果返回 false 会跳过依赖注入阶段

依赖注入前的增强

  • postProcessProperties

    • 如 @Autowired、@Value、@Resource

初始化前后的增强

  • postProcessBeforeInitialization

    • 这里返回的对象会替换掉原本的 bean

    • 如 @PostConstruct、@ConfigurationProperties

  • postProcessAfterInitialization

    • 这里返回的对象会替换掉原本的 bean

    • 如代理增强

销毁之前的增强

  • postProcessBeforeDestruction

    • 如 @PreDestroy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/178145.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【价格型需求响应】基于Logistic函数的负荷转移率模型需求响应研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

前端学习——CSS

文章目录1.CSS1.1什么是CSS1.2快速入门1.3.三种CSS导入方式2.选择器2.1基本选择器2.1.1标签选择器2.1.2类选择器2.1.3id选择器2.2层次选择器2.2.1后代选择器2.2.2子选择器2.2.3相邻兄弟选择器2.2.4通用选择器2.3结构伪类选择器2.4属性选择器3.美化网页元素3.1span标签3.2字体样…

swagger测试Restful API

swagger出现背景 我们构建Restful API的目的通常都是由于多终端的原因&#xff0c;这些终端会共用很多底层业务逻辑&#xff0c;因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端&#xff0c;不同端由不同的团队或者小组负责&#xff0c;为了减少与其他团队平时开发…

LabVIEW将台式电脑转换为 Phar Lap ETS 实时目标

LabVIEW将台式电脑转换为 Phar Lap ETS 实时目标注意&#xff1a;NI将在NI2020软件版本中删除对cRIO的Pharlap和NI2022软件版本中对PXI的支持。更多信息&#xff0c;请参阅PharLapRTOSEOL路线图。您可能已经拥有一台台式PC&#xff0c;可以作为下一个可靠的确定性测试或控制系统…

初识 Express(基于 NodeJS http 模块封装的 Web 框架)

初识 Express&#xff08;基于 NodeJS http 模块封装的 Web 框架&#xff09;参考描述Express获取nodemon获取使用使用创建一个基本的服务器基本路由对客户端的 GET 请求进行响应获取通过 GET 方式提交的 URL 参数静态 URL 参数动态 URL 参数静态资源托管服务器public前缀参考 …

steam搬砖,蓝海信息差副业项目

今天就给大家分享下这个steam搬砖项目的玩法&#xff0c;看完你收藏执行&#xff0c;学不会你可以随便骂我&#xff01;&#xff01; 首先我们讲一下项目原理&#xff1a; 我们需要利用国外steam平台来赚取差价&#xff0c;简单点就是在游戏里面搬砖购买一些道具&#xff0c;然…

零基础学Python(全彩版)

ISBN: 978-7-5692-2225-8 编著&#xff1a;明日科技 页数&#xff1a;448页 阅读时间&#xff1a;2022-08-14 推荐指数&#xff1a;★★★★★ 一本非常适合入门的Python 3编程教程书籍&#xff0c; 不仅有视频教程还有很多的代码示例&#xff0c; 让你在一步步学习中掌握Pytho…

力扣刷题记录——645. 错误的集合、657. 机器人能否返回原点、674. 最长连续递增序列

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《力扣刷题记录——645. 错误的集合、657. 机器人能否返回…

【vue2】对路由的理解

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;vue路由概念、路由写法、路由模式、路由重定向、路由跳转传参方式 目录 一、vue路由概念…

Tkinter的Checkbutton控件

Tkinter的Checkbutton是一个有着许多选项的控件&#xff0c;可以一次选择几个选项 使用方法 var1tk.IntVar() var2tk.IntVar() def printf():if (var1.get()1)&(var2.get()0):L.config(text1)elif (var1.get()0)&(var2.get()1):L.config(text2)elif (var1.get()0)&am…

【docker实践遗留问题】解决个人制作镜像在 dockerhub 上拉取缓慢的问题

目录背景正文1. 创建阿里云docker仓库2. 修改本地 pom 文件尾声背景 通过不断实践&#xff0c;发现了一个问题&#xff1a;dockerHub服务器在国外&#xff0c;虽然拉取一些常用依赖时&#xff0c;可以通过更改镜像源的方式来解决&#xff0c;但倘若是自己制作的docker镜像&…

Python3 条件控制

Python 条件语句是通过一条或多条语句的执行结果&#xff08;True 或者 False&#xff09;来决定执行的代码块。 IF-ELSE判断 常用的if-else语句&#xff0c;通常用于二分支结构的条件语句代码。 Python 中用 elif 代替了else if&#xff0c;所以if语句的关键字为&#xff1a…

【机器学习】(西瓜书习题8.5)编程实现Bagging模型,以决策树桩为基学习器,在西瓜数据集3.0a上训练一个Bagging集成,并与教材图8.6进行比较。

&#xff08;1&#xff09;问题理解与分析 编程实现Bagging模型&#xff0c;以决策树桩为基学习器&#xff0c;在西瓜数据集3.0a上训练一个Bagging集成&#xff0c;并与教材图8.6进行比较。 &#xff08;2&#xff09;Bagging算法原理阐述 若想得到泛化性能强的集成&#xf…

6、算术运算符与算术表达式

目录 一、算术运算符 二、算术表达式 三、优先级与结合性 1. 算术运算符的优先级 2. 算术运算符的结合性 四、自增&#xff0f;自减运算符 一、算术运算符 算术运算符包括两个单目运算符&#xff08;正和负&#xff09;和5个双目运算符&#xff08;即乘法、除法、取模、…

ARP渗透与攻防(六)之限制网速攻击

系列文章 ARP渗透与攻防(一)之ARP原理 ARP渗透与攻防(二)之断网攻击 ARP渗透与攻防(三)之流量分析 ARP渗透与攻防(四)之WireShark截获用户数据 ARP渗透与攻防(五)之Ettercap劫持用户流量 ARP限制网速攻击 大家没想到吧&#xff0c;ARP还能限制对方网速。当kali欺骗了网关和受…

Linux-Ubuntu入门到精通之常用终端指令之操作文件目录和文件内容(2)

常用的终端命令 ctrl shift 放大终端窗口的字体显示 ctrl - 缩小终端窗口的字体显示 按 上&#xff0f;下 光标键可以在曾经使用过的命令之间来回切换 如果想要退出选择&#xff0c;并且不想执行当前选中的命令&#xff0c;可以按 ctrl c . ls 常用选项&#xff08;白色…

DFS(四)39. 组合总和 1079. 活字印刷

39. 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复…

flowable定时任务和表单

流程定义定时激活 &#xff1a; act_re_procdef 的 suspension_status ClassPathResource classPathResource new ClassPathResource("hehe/HistoryDemo01.bpmn20.xml");repositoryService.createDeployment().addInputStream(classPathResource.getFilename(),clas…

【HBase入门】3. HBase数据模型

简介 在HBASE中&#xff0c;数据存储在具有行和列的表中。这是看起来关系数据库(RDBMS)一样&#xff0c;但将HBASE表看成是多个维度的Map结构更容易理解。 { “zzzzz” : “woot”, “xyz” : “hello”, “aaaab” : “world”, “1” : “x”, “aaaaa” : “y” } 术语 表…

MCAL系列介绍05-ICU

本文框架1. 前言2. 基本概念3. ICU采集过程3.1 获取周期占空比3.2 获取边沿数量3.3 获取时间戳4. Autosar系列文章快速链接1. 前言 ICU驱动器是使用Input Capture Uint模块&#xff08;ICU&#xff09;解调PWM信号、计数脉冲、测量频率和占空比、生成简单中断以及唤醒中断的模…