Spring——Bean 的生命周期

2023-10-28


一、Bean 的生命周期

  对于普通的 Java 对象,new 的时候会去创建对象,而当它没有任何引用的时候则被垃圾回收机制回收。相较于前者,由Spring IoC 容器托管的对象,它们的生命周期完全由容器控制。Spring 中每个 Bean 的生命周期如下:
在这里插入图片描述

  • 对于 ApplicationContext 容器,当容器启动结束后,实例化所有的 Bean。
  • 设置对象属性,即依赖注入,动态将依赖关系注入到对象中。
  • 紧接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware实例注入给 Bean。
  • 当经过上述几个步骤后,Bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过
    BeanPostProcessor接口实现。

该接口提供了两个函数:

  1. postProcessBeforeInitialzation( Object bean, String beanName ) 当前正在初始化的 Bean 对象会被传递进来,我们就可以对这个 Bean 作任何处理。 这个函数会先于 InitialzationBean 执行,因此称为前置处理。 所有 Aware 接口的注入就是在这一步完成的。
  2. postProcessAfterInitialzation( Object bean, String beanName ) 当前正在初始化的 Bean 对象会被传递进来,我们就可以对这个 Bean 作任何处理。 这个函数会在 InitialzationBean 完成后执行,因此称为后置处理。
  • 当 BeanPostProcessor 的前置处理完成后就会进入以下阶段。
  • 这一阶段也可以在 Bean 正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前 Bean 对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。 若要使用它,我们需要让 Bean 实现该接口,并把要增加的逻辑写在该函数中。然后 Spring 会在前置处理完成后检测当前 Bean 是否实现了该接口,并执行 afterPropertiesSet 函数。

InitializingBean 接口只有一个函数:afterPropertiesSet()

  • 当然,Spring为了降低对客户代码的侵入性,给bean的配置提供了 init-method 属性,该属性指定了在这一阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。 init-method本质上仍然使用了InitializingBean接口。
  • 通过给 destroy-method 指定函数,就可以在 Bean 销毁前执行指定的逻辑。

二、代码演示

项目结构如下:(红框中为代码演示使用到)
在这里插入图片描述

创建启动入口类:org.example.AppLifecycle

package org.example;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppLifecycle {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("lifecycle.xml");
        ((ClassPathXmlApplicationContext) context).close();
    }
}

Spring配置文件:在src/main/resources下,创建lifecycle.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="org.example.config"/>
</beans>

准备要进行生命周期管理的Bean对象,创建org.example.model.LifeCycleTest

package org.example.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class LifeCycleTest implements InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware, BeanFactoryAware {

    public void beanInit(){
        System.out.println("init-method: 注解是使用@Bean(initMethod=\"方法名\")的方式,xml是使用<bean init-method=\"方法名\" />");
    }

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

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

    public void beanDestroy(){
        System.out.println("destroy-method: 注解是使用@Bean(destroyMethod=\"方法名\")的方式,xml是使用<bean destroy-method=\"方法名\" />");
    }

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

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

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("BeanNameAware");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware");
    }
}

使用创建的配置类org.example.config.AppConfig

package org.example.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig implements BeanPostProcessor {

    @Bean(initMethod = "beanInit", destroyMethod = "beanDestroy")
    public LifeCycleTest lifeCycleTest(){
        return new LifeCycleTest();
    }

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

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

代码运行结果
在这里插入图片描述


三、主要步骤简述

  • 实例化 Bean:通过反射调用构造方法实例化对象。
  • 依赖注入:装配 Bean 的属性。
  • 实现了 Aware接口的 Bean,执行接口方法:如顺序执行 BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法。
  • Bean 对象初始化前,循环调用实现了 BeanPostProcessor 接口的预初始化方法(postProcessBeforeInitialization)。
  • Bean 对象初始化:顺序执行 @PostConstruct 注解方法、InitializingBean 接口方法、init-method 方法。
  • Bean 对象初始化后,循环调用实现了 BeanPostProcessor 接口的后初始化方法(postProcessAfterInitialization)。
  • 容器关闭时,执行 Bean 对象的销毁方法,顺序是:@PreDestroy 注解方法、DisposableBean 接口方法、destroy-method。

补充说明:第一步的实例化是指new对象,Spring的语义中说初始化Bean包含Bean生命周期中的初始化步骤。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring——Bean 的生命周期 的相关文章

随机推荐

  • 你敢信?开发一个管理系统我只用了两天时间

    推荐 前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到网站 前言 由于疫情原因 学校通知本学期要提前放暑假 于是老师提前将期末作业公布于众 按照要求开发一个百货中心供应链管理系统 开发周期为半个月
  • SQL注入系列篇之union联合注入

    一 union注入概念 我们知道 SQL语句的union联合查询常用格式如下 select 1 2 3 from table name1 union select 4 5 6 from table name2 而在注入过程中 我们把unio
  • springmvc 防止XSS攻击

    XSS攻击 即Cross Site Script 跨脚本攻击 往web页面注入html代码或者script代码 造成页面混乱 spring mvc框架中 有很多编辑器 每个编辑器有不同的作用 防止XSS攻击 就用到PropertyEdito
  • 图像处理之OpenCV腐蚀和膨胀

    图像处理之OpenCV腐蚀和膨胀 在图像处理中 腐蚀和膨胀是常用的基础操作 它们可以对图像进行去噪 分割和形态学处理等 本文将介绍使用OpenCV库进行腐蚀和膨胀的方法及其相关代码 腐蚀操作 腐蚀操作可以看作是一种局部最小值滤波器 它的主要
  • UNIX环境高级编程习题答案——第四章

    4 1 用stat函数替换图4 3程序中的lstat函数 如若命令行参数之一是符号链接 会发生什么变化 会输出符号链接所指向文件的文件类型 4 2 如果文件模式创建屏蔽字是777 八进制 结果会怎样 用shell的umask命令验证该结果
  • 判断子序列的三种方法

    392 判断子序列https leetcode cn problems is subsequence 给定字符串 s 和 t 判断 s 是否为 t 的子序列 字符串的一个子序列是原始字符串删除一些 也可以不删除 字符而不改变剩余字符相对位置
  • springmvc源码学习(二十六)异步请求管理器WebAsyncManager异步任务执行流程

    目录 前言 一 回顾 二 异步任务分发 三 异步任务执行 总结 前言 接着上一篇进行分析 在异步任务创建完 那接下来springmvc会去处理该异步任务 一 回顾 1 上一篇中 在请求完接口 生成了一个调度任务dispatchTask 存储
  • IDEA如何向Maven项目中添加JDBC

    IDEA如何向Maven项目中添加JDBC 解决这个问题有两个步骤 下载这个jar包 导入这个jar包 向pom xml文件中导入依赖 我们依次展开 一 Jar包的下载 访问MySQL官网 点击顶部栏的下载 点击MySQL Communit
  • python selenium4 使用无界面浏览器 爬虫 并存储mysql数据库

    浏览器驱动 需要查看对应浏览器版本进行下载 selenium PyPIhttps pypi org project selenium 浏览器设置中查看当前版本 from selenium import webdriver from sele
  • 【JavaScript】只需要7行代码实现图片懒加载

    前言 面试的时候 面试官经常会问到一个问题 前端优化性能 其中 图片懒加载是性能优化的一个点 准备 offsetTop offsetTop是元素到offsetParent顶部的距离 offsetParent offsetParent是距离具
  • Python列表元素删除方法详解

    Python列表元素删除方法详解 在Python中 列表是一种非常常用的数据类型 它允许我们按照特定的顺序存储大量元素 但是在实际开发中 经常需要对列表中的元素进行删除操作 本篇文章将向您介绍Python中列表删除元素的四种方法 帮助您轻松
  • ARCGIS一些tips

    1 不同shapefile使用相同的自定义风格
  • 网络空间安全导论-第三章习题

    网络空间安全导论 第三章习题 TCP IP模型共有几层 各层各有什么功能 应用层 访问网络服务的接口 例如为操作系统或网络应用程序提供访问网络服务的接口 表示层 提供数据格式转换服务 如加密与解密 图片解码和编码 数据的压缩和解压缩 会话层
  • 【全国科技者工作日】:致敬每一位科技工作者,时代的发展永远也少不了这一批人!

    在我们的日常生活中 科技已经渗透到了方方面面 从第一台计算机的发明到智能手机的出现 再到人工智能的应用 科技的发展已经深刻地改变了我们的生活 在这个快速发展的时代 科技工作者是推动社会发展的重要力量 他们的辛勤付出和不懈努力为我们带来了更多
  • 量化python:使用热力图heatmap绘制胜率图方法及工具函数

    胜率图是分析策略的一种图形 对于胜率的分析需要三种数据 策略 参数集 表现在胜率图的横纵轴含义 对比的场景编号 表现在对比两个策略时使用的场景 通常见于不同的时间 不同的参数 不同的周期 场景对应的值 场景对应的值 可能代表收益率 模型的分
  • Oracle学习笔记5_简单查询

    Oracle简单查询语句 查看表结构 desc dept 查看所有列 select from dept 查询指定列 select ename sal job deptno from emp 如何取消重复行 select distinct d
  • C语言system函数用法

    system 函数用于向操作系统传递控制台命令行 以WINDOWS系统为例 通过system 函数执行命令和在DOS窗口中执行命令的效果是一样的 所以只要在运行窗口中可以使用的命令都可以用SYSTEM 传递 但要注意的是输入斜线时要输入两个
  • Python中的各种函数

    1 map 函数 将可迭代对象中每一条数据都执行一次函数 并且将函数执行的返回结果放入另一个可迭代对象中 2 filter 函数 会将列表中每一条数据执行一次函数 并将条件为真的数据放入结果中 None False 0这些都是条件为假的 数
  • leetcode算法面试题:单词接龙问题

    题目 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 序列中第一个单词是 beginWord 序列中最后一个单词是 endWord 每次转换只能改变一个字母 转换过程中的中
  • Spring——Bean 的生命周期

    目录 一 Bean 的生命周期 二 代码演示 三 主要步骤简述 一 Bean 的生命周期 对于普通的 Java 对象 new 的时候会去创建对象 而当它没有任何引用的时候则被垃圾回收机制回收 相较于前者 由Spring IoC 容器托管的对