Spring 之bean的生命周期

news2024/9/27 9:29:57

文章目录

    • IOC
    • Bean的生命周期
      • 运行结果
      • 实例演示
        • 实体类
        • 实例化前后置代码
        • 初始化的前后置代码
        • application.xml
    • 总结

今天我们来聊一下Spring Bean的生命周期,这是一个非常重要的问题,Spring Bean的生命周期也是比较复杂的。

IOC

IOC,控制反转概念需要提前了解一下,简单说就是把new对象的权利交给容器,所有的对象都由容器控制,称为控制反转

然后再通过依赖注入把它依赖的类注入给它。

Bean的生命周期

首先我们先来了解一下bean的作用域有哪些?

  • singleton: 在Spring IOC仅存在一个Bean实例,是Spring默认的bean作用域

  • prototype: 每次请求都会创建一个新的bean实例,即允许IOC中存在多个bean实例

  • request: 每次HTTP请求都会产生一个bean,该bean仅在HTTP request内有效

  • session:每一次HTTP请求都会产生一个新的bean,该bean在这个Session中共享

  • application:限定Bean的作用域为ServletContext的生命周期,该作用域仅适用于web的Spring WebApplicationContext环境

  • websocket: 限定Bean的作用域为WebSocket,该作用域仅适用于web的Spring WebApplicationContext环境

在Spring 中Bean的生命周期大致可以概况为:

实例化 -> 属性赋值 -> 初始化 -> 销毁

在Spring的Bean的生命周期种提供了很多的扩展点,常见的扩展接口有 InitializingBean, BeanNameAware, DisposableBean, ApplicationContextAware,InstantiationAwareBeanPostProcessor,BeanPostProcessor

其中的生命周期可以简单写为以下四步

  1. 实例化:首先,实例化一个Bean对象

  2. 属性赋值:为Bean对象设置属性和依赖

  3. 初始化:初始化,在完成后就可以被使用了

  4. 销毁:可以i通过第4步两种方法来添加配置

其中Bean的大致流程如图所示,展示了初始后的前置和后置过程,在实例化过程中也区分前置和后置过程,而初始化的前置和后置过程中主要是通过重写BeanPostProcessor中的postProcessBeforeInitialization和postProcessAfterInitialization实现的,销毁和初始也支持用户自定义方法。

下面我们继续来看在实例化和初始化时可以扩展的前置方法和后置方法。

![在这里插入图片描述](https://img-blog.csdnimg.cn/bec65f8914c542baa1330a2f207f9f71.png

运行结果

![在这里插入图片描述](https://img-blog.csdnimg.cn/cb95073c57dc4c2ba04ecc14f0489d72.png

实例演示

实体类

public class User implements InitializingBean, BeanNameAware, DisposableBean, ApplicationContextAware {

    private String name;

    public User() {
        System.out.println("1.2 User的无参构造, 实例化");
    }

    /**
     * 初始化方法
     */
    public void initMethod() {
        System.out.println("3.3. bean对象的初始化,调用指定的初始化方法");
    }

    /**
     * 销毁方法
     */
    public void destroyMethod() {
        System.out.println("4.2 bean对象的销毁,调用指定的销毁方法");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("2.1 设置User.name属性 设置属性");
        this.name = name;
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("2.2调用BeanNameAware.setBeanName()方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("4.1调用 DisposableBean.destroy() 方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("3.2调用 InitializingBean.afterPropertiesSet() 方法");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        User user = (User)applicationContext.getBean("user");
        System.out.println(user);
        System.out.println("调用ApplicationContextAware.setApplicationContext()");
    }
}

实例化前后置代码

public class MyBeanInstant implements InstantiationAwareBeanPostProcessor {

    /**
     * Spring 扩展点一、在bean实例化前和实例化后
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("1.1bean的前置处理器实例前 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
        System.out.println(beanName + ": :" + beanClass);
        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("1.3bean的前置处理器实例后 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
        System.out.println(beanName + ": :" + bean);
        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {

        if ("user".equals(beanName)) {
            System.out.println("1.4调用InstantiationAwareBeanPostProcessor.postProcessProperties()方法");
        }
        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
    }
}

初始化的前后置代码

public class MyBeanPost implements BeanPostProcessor {


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("3.1 bean的后置处理器初始化前 BeanPostProcessor.postProcessBeforeInitialization");
        System.out.println(beanName + ": :" + bean);
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("3.4 bean的后置处理器初始化后 BeanPostProcessor.postProcessAfterInitialization");
        System.out.println(beanName + ": :" + bean);
        System.out.println();
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

}

application.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myBeanPost" class="com.zly.ioc.life.MyBeanPost"/>
    <bean id="myBeanInstant" class="com.zly.ioc.life.MyBeanInstant"/>

    <bean id="user" class="com.zly.ioc.life.User" scope="singleton" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="dy"/>
    </bean>
</beans>

总结

本文主要是介绍了Bean的生命周期,简单介绍生命周期中的各种状态概念,以及各个阶段所执行的方法和操作。

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

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

相关文章

华为OD机试题,用 Java 解【合规数组】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…

JAVA基础常见面试题

1.Java接口和抽象类的区别&#xff1f; 接口 接口中不能定义构造器 方法全部都是抽象方法&#xff0c;JDK8提供方法默认实现 接口中的成员都是public的 接口中定义的成员变量实际上都是常量 一个类可以实现多个接口 抽象类 抽象类中可以定义构造器 可以有抽象方法和具体…

字节序

字节序 字节序&#xff1a;字节在内存中存储的顺序。 小端字节序&#xff1a;数据的高位字节存储在内存的高位地址&#xff0c;低位字节存储在内存的低位地址 大端字节序&#xff1a;数据的低位字节存储在内存的高位地址&#xff0c;高位字节存储在内存的低位地址 bit ( 比特…

设计模式第八讲:观察者模式和中介者模式详解

一. 观察者模式1. 背景在现实世界中&#xff0c;许多对象并不是独立存在的&#xff0c;其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变。例如&#xff0c;某种商品的物价上涨时会导致部分商家高兴&#xff0c;而消费者伤心&#xff1b;还有&#x…

内网部署api接口文档服务器端口如何让外网访问?

计算机业内人士对于swagger并不陌生&#xff0c; 不少人选择用swagger做为API接口文档管理。Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新文件的方法&#x…

Apache Hadoop生态部署-3台设置的免密登录,xsync分发脚本,jpsall脚本

目录 查看服务架构图-服务分布、版本信息 集群服务器间的免密登录 jpsall集群jps查看脚本 xsync集群分发脚本 查看服务架构图-服务分布、版本信息 系统环境&#xff1a;centos7 Java环境&#xff1a;Java8 集群服务器间的免密登录 作用&#xff1a;这里配置的是root用户…

联想昭阳E5-ITL电脑开机后绿屏怎么U盘重装系统?

联想昭阳E5-ITL电脑开机后绿屏怎么U盘重装系统&#xff1f;有用户电脑正常开机之后&#xff0c;出现了屏幕变成绿屏&#xff0c;无法进行操作的情况。这个问题是系统出现了问题&#xff0c;那么如何去进行问题的解决呢&#xff1f;接下来我们一起来分享看看如何使用U盘重装电脑…

数据库系统概论——绪论

1、绪论 1.1、数据库系统概述 数据库系统的构成示意图 1.1.1、数据库系统基本概念 基本概念&#xff1a;数据、数据库、数据库管理系统和数据库系统 1&#xff09;数据&#xff08;data&#xff09; 定义&#xff1a;描述事物的符号记录称为数据数据是数据库中存储的基本对象…

Latex三线表画法合集

Latex常用表格画法合集 前言 当我们使用Latex写论文的时候&#xff0c;三线表是展示实验结果的常用方法&#xff0c;但网上的方法杂七杂八&#xff0c;找到自己想要的表格需要花费一番功夫。本篇文章旨在记录论文常用表格的画法&#xff0c;方便论文的书写。 导入的包&#x…

11.7 指针和多维数组

C语言学习栏目目录 目录 1 指向多维数组的指针 2 指针的兼容性 3 函数和多维数组 指针和多维数组有什么关系&#xff1f;为什么要了解它们的关系&#xff1f;处理多维数组的函数要用到指针&#xff0c;所以在使用这种函数之前&#xff0c;先要更深入地学习指针。至于第 1 个…

工作实战之系统交互api调用认证设计

目录 前言 一、黄金段位接口交互 二、钻石段位接口交互设计 1.接口文档定义 2.工具类以及demo提供 a.调用方部分代码 b.被调用方 三.星耀段位接口访问设计 1.在钻石段位的基础上&#xff0c;进行sdk的封装 a.maven引入 b.sdk包含工具类 四.王者段位接口访问设计 1.开发详情 2.…

大数据技术为何诞生,它究竟解决了哪些问题?

大数据诞生背景与基本概念大数据为什么会诞生&#xff1f;以及它解决了哪些问题&#xff1f;1.大数据诞生之前的数据处理模式2.结构化数据在传统处理方式下的瓶颈3.非结构化与半结构化数据在传统处理方式下的瓶颈4.大数据诞生的初衷与定义大数据场景特征大数据为什么会诞生&…

day19_Set

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、Set 三、HashSet 四、LinkedHashSet 五、TreeSet 六、Collections 零、 复习昨日 提问过了… 一、作业 见代码… 二、Set Set集合是Collecti…

Mybatis源码笔记

String resource "mybatis-config.xml";Reader reader;try {//将XML配置文件构建为Configuration配置类reader Resources.getResourceAsReader(resource);// 通过加载配置文件流构建一个SqlSessionFactory DefaultSqlSessionFactorySqlSessionFactory sqlMapper …

多点电容触摸屏实验

目录 一、简介 二、硬件原理 ​编辑1、CT_INT 2、I2C2_SCL和I2C2_SDA 3、RESET复位引脚 三、FT54x6/FT52x6电容触摸芯片 四、代码编写 1、编写ft5426.h 2、编写ft5426.c 3、main函数 一、简介 电容屏只需要手指轻触即可&#xff0c;而电阻屏是需要手指给予一定的压力才…

Elasticsearch7.8.0版本进阶——动态更新索引

目录一、如何在保留不变性的前提下实现倒排索引的更新二、按段搜索执行流程三、按段搜索的文档查询四、按段搜索的文档删除五、按段搜索的文档更新一、如何在保留不变性的前提下实现倒排索引的更新 用更多的索引。通过增加新的补充索引来反映最近的修改&#xff0c;而不是直接…

【华为OD机试模拟题】用 C++ 实现 - 整理扑克牌(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

[Flink]部署模式(看pdf上的放上面)

运行一个wordcountval dataStream: DataStream[String] environment.socketTextStream("hadoop1", 7777) //流式数据不能进行groupBy,流式数据要来一条处理一次.0表示第一个元素,1表示第二个元素 //keyBy(0)根据第一个元素进行分组 val out: DataStream[(String, In…

Spring Boot中使用Sa-Token实现轻量级登录与鉴权

1. Sa-Token 介绍 Sa-Token 是一个轻量级 Java 权限认证框架&#xff0c;主要解决&#xff1a;登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。 功能结构图 2. 登录认证 对于一些登录之后才能访问的接口&#xff08;例如&…

Graph Embedding基础 图表示学习 什么是Graph Embedding

本文包括 DeepWalk LINE SDNE Node2vec Struc2vec等几个重要的Graph Embedding 方法 先说下不同embedding的区别是什么&#xff1a; DeepWalk&#xff1a;采用随机游走&#xff0c;形成序列&#xff0c;采用skip-gram方式生成节点embedding。node2vec&#xff1a;不同的随机游…