Spring Bean 的生命周期(看着图不迷路)

news2025/4/13 8:31:04

目录

Bean的生命周期5步走系列:

BeanLifeCycle类

Spring.xml 配置文件

BeanLifeTest测试方法

运行结果:

Bean的生命周期7步走系列:在实例化Bean的前和后加了两步。​​​​

定义myInstantiationAwareBeanPostProcessor 类

实现InstantiationAwareBeanPostProcessor 接口

并将这个类配置到Spring.xml中

复用5步走的测试方法

运行结果:

Bean的生命周期9步系列:在初始化Bean的前和后添加两步。

需要实现BeanPostProcessor接口并重写 Initialization 的两个方法

Spring.xml配置

复用5步走的测试方法

测试结果:

Bean的生命周期10步走系列:比9步多了在属性赋值之后感知

BeanLifeCycle类

复用5步走的测试方法

测试结果:

Bean的生命周期11步走系列:比10步多添加了初始化Bean之前处理的方法。

BeanLifeCycle类

复用5步走的测试方法

测试结果:

Bean的生命周期12步走系列:在销毁Bean之前添加了一步。

BeanLifeCycle类

复用5步走的测试方法

测试结果:



Bean的生命周期5步走系列:

分别是如下图:

BeanLifeCycle类

/**
 * Bean的生命周期按照粗略的五步的话:
 * 第一步:实例化Bean(调用无参数构造方法。)
 * 第二步:给Bean属性赋值(调用set方法。)
 * 第三步:初始化Bean (会调用Bean的init方法。注意:这个init方法需要自己写,自己配。)
 * 第四步:使用Bean
 * 第五步:销毁Bean (公调用Bean/destroy方法。注意:这个destroy方法需要自己写,自己配。)
 * @Author darren
 * @Date 2022/11/2 9:25
 */
public class BeanLifeCycle {

    private String name;

    public BeanLifeCycle() {
        System.out.println("第一步:实例化Bean");
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        System.out.println("第二步:给Bean属性赋值");
        this.name = name;
    }


    public void initMethod(){
        System.out.println("第三步:初始化Bean");
    }


    public void destroyMethod(){
        System.out.println("第五步:销毁Bean ");
    }

    @Override
    public String toString() {
        return "BeanLifeCycle{" +
                "name='" + name + '\'' +
                '}';
    }
}

Spring.xml 配置文件

  <!--Bean 的生命周期-->
    <bean id="beanLife" class="com.power.node.spring6.bean.BeanLifeCycle" init-method="initMethod"
          destroy-method="destroyMethod">
        <property name="name" value="bean_name"/>
    </bean>

BeanLifeTest测试方法

public class BeanLifeTest {
    /**
     * Bean的生命周期
     */
    @Test
    public void testBeanLifeCycle(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext =
                new ClassPathXmlApplicationContext("beanLife.xml");
        BeanLifeCycle beanLife = classPathXmlApplicationContext.getBean("beanLife", BeanLifeCycle.class);
        System.out.println("第四步:使用Bean "+beanLife.toString());
        System.out.println("");

        classPathXmlApplicationContext.close();
    }
}

运行结果:

第一步:实例化Bean
第二步:给Bean属性赋值
第三步:初始化Bean
第四步:使用Bean BeanLifeCycle{name='bean_name'}
第五步:销毁Bean 

Bean的生命周期7步走系列:在实例化Bean的前和后加了两步。
​​​​

如图:

 

定义myInstantiationAwareBeanPostProcessor 类

实现InstantiationAwareBeanPostProcessor 接口

/**
 * 实例化前后处理器
 * @Author darren
 * @Date 2022/11/2 17:16
 */
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(final Class<?> beanClass, final String beanName)
            throws BeansException {
        System.out.println("    第1.1步-实例化之前-后期处理器");
        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass,
                beanName);
    }

    @Override
    public boolean postProcessAfterInstantiation(final Object bean, final String beanName)
            throws BeansException {
        System.out.println("    第1.1步-实例化之后-后期处理器");
        System.out.println("");
        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean,
                beanName);
    }
}

并将这个类配置到Spring.xml中


    <!--Bean 的生命周期-->
    <bean id="beanLife" class="com.power.node.spring6.bean.BeanLifeCycle" init-method="initMethod"
          destroy-method="destroyMethod">
        <property name="name" value="bean_name"/>
    </bean>

    <!--实例化前后处理器-->
    <bean id="myInstantiationAwareBeanPostProcessor"
          class="com.power.node.spring6.bean.MyInstantiationAwareBeanPostProcessor"/>
</beans>

复用5步走的测试方法

运行结果:

          第1.1步-实例化之前-后期处理器
    第一步:实例化Bean
          第1.2步-实例化之后-后期处理器
    第二步:Bean属性赋值
    第三步:初始化Bean
    第四步:使用Bean
    第五步:销毁Bean

    注意:
    需要实现InstantiationAwareBeanPostProcessor接口并重写Instantiation方法后并配置到xml,
        postProcessBeforeInstantiation:实例化之前-后期处理器
        postProcessAfterInstantiation :实例化之后-后期处理器

Bean的生命周期9步系列:在初始化Bean的前和后添加两步。

 

需要实现BeanPostProcessor接口并重写 Initialization 的两个方法

postProcessBeforeInitialization:初始化之前-后期处理器
postProcessAfterInitialization :初始化之后-后期处理器
/**
 * 初始化前后置处理器
 * @Author darren
 * @Date 2022/11/2 9:56
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(final Object bean, final String beanName)
            throws BeansException {
        System.out.println("    第3.1步-初始化前的-后期处理器");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);

    }

    @Override
    public Object postProcessAfterInitialization(final Object bean, final String beanName)
            throws BeansException {
        System.out.println("    第3.2步-初始化后的-后期处理器");
        System.out.println("");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

Spring.xml配置

    <!--Bean 的生命周期-->
    <bean id="beanLife" class="com.power.node.spring6.bean.BeanLifeCycle" init-method="initMethod"
          destroy-method="destroyMethod">
        <property name="name" value="bean_name"/>
    </bean>

    <!--实例化前后处理器-->
    <bean id="myInstantiationAwareBeanPostProcessor"
          class="com.power.node.spring6.bean.MyInstantiationAwareBeanPostProcessor"/>

    <!--初始化前后置处理器-->
    <bean id="myBeanPostProcessor" class="com.power.node.spring6.bean.MyBeanPostProcessor"/>

复用5步走的测试方法

测试结果:

    第1.1步-实例化之前-后期处理器
第一步:实例化Bean
    第1.1步-实例化之后-后期处理器

第二步:给Bean属性赋值
    
    第3.1步-初始化前的-后期处理器   
第三步:初始化Bean
    第3.2步-初始化后的-后期处理器

第四步:使用Bean BeanLifeCycle{name='bean_name'}
第五步:销毁Bean 

Bean的生命周期10步走系列:比9步多了在属性赋值之后感知

如图:

BeanLifeCycle类

需要这个类实现Aware(感知)接口,
    如:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware、ApplicationContextAware
在属性赋值之后感知可以获取或设置下面信息
    BeanName、BeanClassLoader、BeanFactory、ApplicationContext
public class BeanLifeCycle implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware,
        ApplicationContextAware {

    private String name;

    public BeanLifeCycle() {
        System.out.println("第一步:实例化Bean");
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        System.out.println("第二步:给Bean属性赋值");
        this.name = name;
    }

    @Override
    public void setBeanName(final String s) {
        System.out.println("    第2.2步-属性感知-设置属性名称:"+s);
    }

    @Override
    public void setBeanClassLoader(final ClassLoader classLoader) {
        System.out.println("    第2.3步-属性感知-设置类加载器:"+classLoader);
    }

    @Override
    public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
        System.out.println("    第2.4步-属性感知-设置bean工厂:"+beanFactory);
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext)
            throws BeansException {
        System.out.println("    第2.5步-属性感知-设置上下文:"+applicationContext);
        System.out.println("");
    }


    public void initMethod(){
        System.out.println("第三步:初始化Bean");
    }


    public void destroyMethod(){
        System.out.println("第五步:销毁Bean ");
    }

    @Override
    public String toString() {
        return "BeanLifeCycle{" +
                "name='" + name + '\'' +
                '}';
    }
}

复用5步走的测试方法

测试结果:

    第1.1步-实例化之前-后期处理器
第一步:实例化Bean
    第1.1步-实例化之后-后期处理器

第二步:给Bean属性赋值
    第2.2步-属性感知-设置属性名称:beanLife
    第2.3步-属性感知-设置类加载器:jdk.internal.loader.ClassLoaders$AppClassLoader@78308db1
    第2.4步-属性感知-设置bean工厂:org.springframework.beans.factory.support.DefaultListableBeanFactory@5812f68b: defining beans [beanLife,myInstantiationAwareBeanPostProcessor,myBeanPostProcessor]; root of factory hierarchy
    第2.5步-属性感知-设置上下文:org.springframework.context.support.ClassPathXmlApplicationContext@29f7cefd, started on Wed Nov 02 21:11:42 CST 2022

    第3.1步-初始化前的-后期处理器
第三步:初始化Bean
    第3.2步-初始化后的-后期处理器

第四步:使用Bean BeanLifeCycle{name='bean_name'}
第五步:销毁Bean 

Bean的生命周期11步走系列:比10步多添加了初始化Bean之前处理的方法。

如图:

BeanLifeCycle类

需要这个类实现InitializingBean接口,重写afterPropertiesSet方法
public class BeanLifeCycle implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware,
        ApplicationContextAware, InitializingBean {

    private String name;

    public BeanLifeCycle() {
        System.out.println("第一步:实例化Bean");
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        System.out.println("第二步:给Bean属性赋值");
        this.name = name;
    }

    @Override
    public void setBeanName(final String s) {
        System.out.println("    第2.2步-属性感知-设置属性名称:"+s);
    }

    @Override
    public void setBeanClassLoader(final ClassLoader classLoader) {
        System.out.println("    第2.3步-属性感知-设置类加载器:"+classLoader);
    }

    @Override
    public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
        System.out.println("    第2.4步-属性感知-设置bean工厂:"+beanFactory);
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext)
            throws BeansException {
        System.out.println("    第2.5步-属性感知-设置上下文:"+applicationContext);
        System.out.println("");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("        第3.1.1步-初始化之前调用");
    }

    public void initMethod(){
        System.out.println("第三步:初始化Bean");
    }


    public void destroyMethod(){
        System.out.println("第五步:销毁Bean ");
    }

    @Override
    public String toString() {
        return "BeanLifeCycle{" +
                "name='" + name + '\'' +
                '}';
    }
}

复用5步走的测试方法

测试结果:

    第1.1步-实例化之前-后期处理器
第一步:实例化Bean
    第1.1步-实例化之后-后期处理器

第二步:给Bean属性赋值
    第2.2步-属性感知-设置属性名称:beanLife
    第2.3步-属性感知-设置类加载器:jdk.internal.loader.ClassLoaders$AppClassLoader@78308db1
    第2.4步-属性感知-设置bean工厂:org.springframework.beans.factory.support.DefaultListableBeanFactory@5812f68b: defining beans [beanLife,myInstantiationAwareBeanPostProcessor,myBeanPostProcessor]; root of factory hierarchy
    第2.5步-属性感知-设置上下文:org.springframework.context.support.ClassPathXmlApplicationContext@29f7cefd, started on Wed Nov 02 21:11:42 CST 2022

    第3.1步-初始化前的-后期处理器
        第3.1.1步-初始化之前调用
第三步:初始化Bean
    第3.2步-初始化后的-后期处理器

第四步:使用Bean BeanLifeCycle{name='bean_name'}
第五步:销毁Bean 

Bean的生命周期12步走系列:在销毁Bean之前添加了一步。

如图:

 

BeanLifeCycle类

需要这个类实现DisposableBean接口,并重写destroy方法,调用时机是在指定destroy-method 之前调用
public class BeanLifeCycle implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware,
        ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;

    public BeanLifeCycle() {
        System.out.println("第一步:实例化Bean");
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        System.out.println("第二步:给Bean属性赋值");
        this.name = name;
    }

    @Override
    public void setBeanName(final String s) {
        System.out.println("    第2.2步-属性感知-设置属性名称:"+s);
    }

    @Override
    public void setBeanClassLoader(final ClassLoader classLoader) {
        System.out.println("    第2.3步-属性感知-设置类加载器:"+classLoader);
    }

    @Override
    public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
        System.out.println("    第2.4步-属性感知-设置bean工厂:"+beanFactory);
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext)
            throws BeansException {
        System.out.println("    第2.5步-属性感知-设置上下文:"+applicationContext);
        System.out.println("");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("        第3.1.1步-初始化之前调用");
    }

    public void initMethod(){
        System.out.println("第三步:初始化Bean");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("    第5.1步-销毁-在destroy-method 之前调用");
    }

    public void destroyMethod(){
        System.out.println("第五步:销毁Bean ");
    }

    @Override
    public String toString() {
        return "BeanLifeCycle{" +
                "name='" + name + '\'' +
                '}';
    }
}

复用5步走的测试方法

测试结果:

    第1.1步-实例化之前-后期处理器
第一步:实例化Bean
    第1.1步-实例化之后-后期处理器

第二步:给Bean属性赋值
    第2.2步-属性感知-设置属性名称:beanLife
    第2.3步-属性感知-设置类加载器:jdk.internal.loader.ClassLoaders$AppClassLoader@78308db1
    第2.4步-属性感知-设置bean工厂:org.springframework.beans.factory.support.DefaultListableBeanFactory@5812f68b: defining beans [beanLife,myInstantiationAwareBeanPostProcessor,myBeanPostProcessor]; root of factory hierarchy
    第2.5步-属性感知-设置上下文:org.springframework.context.support.ClassPathXmlApplicationContext@29f7cefd, started on Wed Nov 02 21:11:42 CST 2022

    第3.1步-初始化前的-后期处理器
        第3.1.1步-初始化之前调用
第三步:初始化Bean
    第3.2步-初始化后的-后期处理器

第四步:使用Bean BeanLifeCycle{name='bean_name'}

    第5.1步-销毁-在destroy-method 之前调用
第五步:销毁Bean

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

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

相关文章

【JavaWeb】一文搞懂Java过滤器与拦截器的区别

✅✅作者主页&#xff1a;&#x1f517;孙不坚1208的博客 &#x1f525;&#x1f525;精选专栏&#xff1a;&#x1f517;JavaWeb从入门到精通&#xff08;持续更新中&#xff09; &#x1f4cb;&#x1f4cb; 本文摘要&#xff1a;本篇文章主要分享Java过滤器与拦截器的知识。…

字节跳动测开实习生面试,拿15K过分吗?

今年9月面了字节跳动的测试开发岗&#xff08;日常实习岗&#xff09;&#xff0c;2面技术面和1面hr面。拿到offer后&#xff0c;考虑到自己还是想保研怕成绩掉&#xff0c;选择留在学校&#xff0c;拒offer。 很幸运的是我的简历被内推到了其他部门&#xff0c;今年10月初字节…

【MySQL性能优化系列】select count(*)走二级索引比主键索引快几百倍,你敢信?

问题 在MySQL版本5.7数据测试过程中&#xff0c;一张百万数据的表用 select count(*)查询特别慢需要20s并且是走了主键索引&#xff0c;为什么查询还需要这么久&#xff1f;如何优化&#xff1f;下面我们将请到当事SQL进行发言 验证分析 猜想 先猜想一波为什么走了主键索引依…

【Vue3】手把手教你创建前端项目 Vue3 + Ts + vite + pinia

文章目录一、 项目初始化二、 代码风格安装eslint安装prettier三、 状态管理工具--Pinia优点使Pinia 基本使用四、Vue-Router4 快速上手指南五、VueUse快速上手指南什么是 VueUse简单上手六、全局样式CSS原生 css 新特性scss 或 less封装axios安装依赖封装UI 样式库一、 项目初…

数据结构(二叉树)——Java实现

作者&#xff1a;~小明学编程 文章专栏&#xff1a;Java数据结构 格言&#xff1a;目之所及皆为回忆&#xff0c;心之所想皆为过往 目录 树型结构 什么是树 树的相关概念 树的表现形式 树的引用 二叉树 概念 二叉树的种类 常规二叉树 满二叉树 完全二叉树 二叉树的性…

京东商品接口加解密算法解析

最近,闲来没事,打开看了一下京东图书的热销榜,想通过接口查看下它接口的加密方式,于是直接打开了M站的地址:https://m.jd.com/,然后打开搜索页面,如下图。 打开页面,打开开发者工具,往下滑动鼠标,获取接口地址。 解析一下接口,接口返回值跟没什么特殊说明,首尾加…

spring boot 整合 shiro 框架

1、整合shiro 1.1、创建spring boot项目 1.2、引入依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.9.0</version> </dependency><!--mybatis…

云手机在黑产中的应用

虚拟化技术是当下黑灰产的热门技术。使用虚拟化环境&#xff0c;让黑灰产可以利用虚拟环境在应用运行环境的更底层这一优势&#xff0c;对 App 进行神不知鬼不觉的修改&#xff0c;从而避免在分析、破解 App 上的投入。 较早之前以 VirtualApp 为代表的 Android 虚拟化多开工具…

OpenHarmony源码分析(二):系统安全

1、 概要 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gc6K9a9A-1667380110547)(PNG/11.png)] 2、 进程隔离 OpenHarmony 内核态的进程之间无隔离,共享一块VMM空间,用户态进程每个用户用于自己独立的空间,相互之间不可见,通过MMU 机制实现进…

拓端tecdat|python在Scikit-learn中用决策树和随机森林预测NBA获胜者

全文链接&#xff1a;http://tecdat.cn/?p5222 原文出处&#xff1a;拓端数据部落公众号 在本文中&#xff0c;我们将以Scikit-learn的决策树和随机森林预测NBA获胜者。美国国家篮球协会&#xff08;NBA&#xff09;是北美主要的男子职业篮球联赛&#xff0c;被广泛认为是首屈…

【Transformers】第 5 章:微调文本分类的语言模型

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

Go语言入门【1】数据类型、变量、常量

常见基本数据类型 uint8&#xff1a;无符号8位整形&#xff0c;取值范围&#xff1a;0-255 uint16&#xff1a;无符号16位整形&#xff0c;取值范围&#xff1a;0-65535 uint32&#xff1a;无符号32位整形&#xff0c;取值范围&#xff1a;0-4294967295 uint64&#xff1a;…

高分辨空间代谢组学测试的样品要求以及常见问题

高分辨空间代谢组学可实现定量检测&#xff0c;亦可定性检测&#xff0c;且可一次可同时检出多种类型的化合物&#xff0c;包括脂类、小分子代谢物、蛋白质、药物及其载体等&#xff0c;并且能够呈现出这些物质的空间分布情况。高分辨空间代谢组学测试的样品要求&#xff1a; …

单链表思路讲解+C语言代码实现

单链表的实现什么是单链表单链表的结构图讲解创建链表打印链表尾插链表尾删链表头插链表和头删链表查询链表特定位置插入特定位置删除销毁链表总结学海无涯&#xff0c;苦作舟啊&#xff01; 老铁们加油 源代码放在总结处&#xff0c;需要的同志可以直接跳转到最后什么是单链表…

题库API调用详细教程

题库API调用详细教程 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点击…

洛谷千题详解 | P1010 [NOIP1998 普及组] 幂次方【C++、Java、Python、Pascal语言】

博主主页&#xff1a;Yu仙笙 专栏地址&#xff1a;洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析&#xff1a; C源码&#xff1a; Pascal源码&#xff1a; Java源码&#xff1a; Python源码&#xff1a; ------------------------------------------------…

C#基础:类class与结构struct的区别

一、类class 类class是引用类型&#xff0c;可以直接赋值为null&#xff0c;默认值也是null XClass xClass null;//语法正确 一般来说&#xff0c;某个类对象使用另一个类的对象赋值时&#xff0c;则两者共用一个内存地址【节约内存空间】&#xff0c;ReferenceEquals引用比…

JDK的安装-详细版

大家好&#xff0c;我是研究大数据领域的 查德-常&#xff0c;大数据是一个随着数据量快速增长而应运而生的行业&#xff0c;让我来带你了解大数据吧。 JDK的安装JDK安装1.1 搜索jdk1.2 登录Oracle1.3 安装jdk1.4 环境配置1.5 验证是否安装好jdk由于粉丝中初学者比较多&#xf…

《web课程设计》用HTML CSS做一个简洁、漂亮的个人博客网站

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: ​​【主页——&#x1f680;获取更多优质源码】​​ &#x1f393; web前端期…

西祠胡同社区彻底消失

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 今天打开西祠胡同&#xff0c;发现网站备案注销了&#xff0c;域名(www.xici.net)停止解析了&#xff0c;半年前1元转让股权的事也不了了之&#xff0c;西祠胡同就这样静悄悄的消失了&#xff0c;连…