当前位置: 首页 > news >正文

Spring学习笔记之Bean的“出生入死”

文章目录

  • 什么是Bean的生命周期
  • 为什么要知道Bean的生命周期
  • Bean的生命周期之五个阶段
  • Bean生命周期之七个阶段
  • Bean生命周期的十个阶段
  • Bean的作用域不同,管理方式不同
  • 自己new的对象如何让Spring管理

什么是Bean的生命周期

Spring其实就是一个管理Bean对象的工厂。它负责对象的创建,对象的销毁等。


所谓的生命周期就是:对象从创建开始到最终销毁的整个过程。
什么时候创建Bean对象?
创建Bean对象的前后会调用什么方法?
Bean对象什么时候销毁(去世)?
Bean对象的销毁前后调用什么方法?

为什么要知道Bean的生命周期

其实生命周期的本质是:在哪个时间点上调用哪个类的哪个方法。
我们需要充分的了解在这个生命线上,都有那些特殊的时间节点。
只有我们知道了特殊的时间节点都在哪,到时我们才可以确定代码写到哪。
我们可能需要在某个特殊的时间点上执行一段特殊的代码,这段代码就可以放到这个节点上。当生命线走到这里的时候,自然会被调用。

Bean的生命周期之五个阶段

Bean生命周期的管理,可以参考Spring的源码:
AbstractAutowireCapableBeanFactory类的doCreateBean()方法。


Bean的出生入死大概可以分为五个阶段:

  • 第一阶段:实例化Bean(小屁孩)
  • 第二阶段:Bean属性赋值(少年)
  • 第三阶段:初始化Bean(青年)
  • 第四阶段:使用Bean(中年)
  • 第五阶段:销毁Bean(老年)

package org.powernode;public class User {private String name;public User(){System.out.println("1.小破孩Bean");}public void setName(String name){System.out.println("2.少年Bean");}public void initBean(){System.out.println("3.青年Bean");}public void destroyBean(){System.out.println("5.老年Bean");}
}
<?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="userBean" class="org.powernode.User" init-method="initBean" destroy-method="destroyBean"><property name="name" value="gouba"/></bean>
</beans>
//test@Testpublic void test(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User userBean = applicationContext.getBean("userBean", User.class);System.out.println("4.中年Bean");ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;context.close();}

注意:

  • 只有正常关闭spring容器,bean的销毁方法才会被调用
  • ClassPathXmlApplicationContext类才有close()方法
  • 配置文件中的init-method指定初始化方法。destroy-method指定销毁方法

Bean生命周期之七个阶段

在上面五个阶段中,第三个阶段是初始化Bean,如果还想在初始化前和初始化后添加代码,可以加入”Bean后处理器“

编写一个类实现BeanPostProcessor类,并且重写before和after方法:

package com.powernode.spring6.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class LogBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("Bean后处理器的before方法执行,即将开始初始化");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("Bean后处理器的after方法执行,已完成初始化");return bean;}
}
<!--配置Bean后处理器。这个后处理器将作用于当前配置文件中所有的bean。-->
<bean class="com.powernode.spring6.bean.LogBeanPostProcessor"/>

一定要注意:在spring.xml文件配置的Bean后期处理器将作用于当前配置文件中所有的Bean。

Bean生命周期的十个阶段

  • 实例化Bean
  • Bean属性赋值
  • 检查Bean是否实现了Aware的相关接口,并设置相关依赖
  • Bean后处理器before执行
  • 检查Bean是否实现了InitializingBean接口,并调用接口方法
  • 初始化Bean
  • Bean后处理器after执行
  • 使用Bean
  • 检查Bean是否实现了DisposableBean接口,并调用接口方法
  • 销毁Bean

检查Bean是否实现了Aware的相关接口是什么意思?
Aware相关的接口包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

  • 当Bean实现了BeanNameAware,Spring会将Bean的名字传递给Bean。
  • 当Bean实现了BeanClassLoaderAware,Spring会将加载该Bean1的类加载器传递给Bean。
  • 当Bean实现了BeanFactoryAware,Spring会将Bean工厂对象传递给Bean。

测试以上十步,可以让User类实现5个接口,并实现所有方法:

  • BeanNameAware
  • BeanClassLoaderAware
  • BeanFactoryAware
  • InitializingBean
  • DisposableBean

//User.java
package com.powernode.spring6.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;/*** @author 动力节点* @version 1.0* @className User* @since 1.0**/
public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {private String name;public User() {System.out.println("1.实例化Bean");}public void setName(String name) {this.name = name;System.out.println("2.Bean属性赋值");}public void initBean(){System.out.println("6.初始化Bean");}public void destroyBean(){System.out.println("10.销毁Bean");}@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println("3.类加载器:" + classLoader);}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("3.Bean工厂:" + beanFactory);}@Overridepublic void setBeanName(String name) {System.out.println("3.bean名字:" + name);}@Overridepublic void destroy() throws Exception {System.out.println("9.DisposableBean destroy");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("5.afterPropertiesSet执行");}
}
//LogBeanPostProcessor.java
package com.powernode.spring6.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;/*** @author 动力节点* @version 1.0* @className LogBeanPostProcessor* @since 1.0**/
public class LogBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("4.Bean后处理器的before方法执行,即将开始初始化");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("7.Bean后处理器的after方法执行,已完成初始化");return bean;}
}
  • InitializingBean的方法早于init-method的执行
  • DisposbleBean的方法早于destroy-method的执行。

Bean的作用域不同,管理方式不同

Spring根据Bean的作用域来选择管理方式。

  • 对于singleton作用域的Bean,Spring能够精确地知道该Bean何时被创建,何时初始化完成,以及何时被销毁。
  • 而对于prototype作用域的Bean,Spring只负责创建,当容器创建了Bean的实例后,Bean的实例就交给客户端代码管理,Spring容器将不再跟踪其生命周期。
<!-- spring.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"><!--init-method属性指定初始化方法。destroy-method属性指定销毁方法。--><bean id="userBean" class="com.powernode.spring6.bean.User" init-method="initBean" destroy-method="destroyBean" scope="prototype"><property name="name" value="zhangsan"/></bean><!--配置Bean后处理器。这个后处理器将作用于当前配置文件中所有的bean。--><bean class="com.powernode.spring6.bean.LogBeanPostProcessor"/></beans>

自己new的对象如何让Spring管理

有时候会遇到这样的需求,某个java对象是我们自己new的,然后希望这个对象被Spring容器管理,该如何实现

package com.powernode.spring6.bean;public class User {
}
package com.powernode.spring6.test;import com.powernode.spring6.bean.User;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;/*** @author 动力节点* @version 1.0* @className RegisterBeanTest* @since 1.0**/
public class RegisterBeanTest {@Testpublic void testBeanRegister(){// 自己new的对象User user = new User();System.out.println(user);// 创建 默认可列表BeanFactory 对象DefaultListableBeanFactory factory = new DefaultListableBeanFactory();// 注册Beanfactory.registerSingleton("userBean", user);// 从spring容器中获取beanUser userBean = factory.getBean("userBean", User.class);System.out.println(userBean);}
}

相关文章:

Spring学习笔记之Bean的“出生入死”

文章目录 什么是Bean的生命周期为什么要知道Bean的生命周期Bean的生命周期之五个阶段Bean生命周期之七个阶段Bean生命周期的十个阶段Bean的作用域不同&#xff0c;管理方式不同自己new的对象如何让Spring管理 什么是Bean的生命周期 Spring其实就是一个管理Bean对象的工厂。它负…...

hbase 报错 Master passed us a different hostname to use; was=

原因 wsl2的 /etc/hosts 配置的不兼容,我这里是ubuntu22 命令行输入hostname 看输出什么,比如输出 aaa 那么替换/etc/hosts 127.0.0.1 aaa...

Aspera替代方案:探索这些安全且可靠的文件传输工具

科技的发展日新月异&#xff0c;文件的传输方式也在不断地更新换代。传统的邮件附件、FTP等方式已经难以满足人们对于传输速度和安全性的需求了。近年来&#xff0c;一些新兴的文件传输工具受到了人们的关注&#xff0c;其中除了知名的Aspera之外&#xff0c;还有许多可靠安全的…...

你真的了解数据结构与算法吗?

数据结构与算法&#xff0c;是理论和实践必须紧密结合的一门学科&#xff0c;有关数据结构和算法同类的课程或书籍&#xff0c;有些只是名为“数据结构”&#xff0c;而非“数据结构与算法”&#xff0c;它们在内容上并无很大区别。 实际上&#xff0c;数据结构和算法&#xf…...

kafka使用心得(一)

kafka入门 一种分布式的、基于发布/订阅的消息系统&#xff0c;scala编写&#xff0c;具备快速、可扩展、可持久化的特点。 基本概念 topic 主题 partition 分区&#xff0c;一个topic下可以有多个partition&#xff0c;消息是分散到多个partition里存储的&#xff0c;part…...

Django图书商城系统实战开发-实现商品管理

Django图书商城系统实战开发 - 实现商品管理 在本教程中&#xff0c;我们将使用Django框架来实现一个简单的图书商城系统&#xff0c;并重点讨论如何实现商品管理功能。此外&#xff0c;我们还将介绍如何使用Markdown格式来写博客&#xff0c;并将其集成到我们的图书商城系统中…...

走出象牙塔:李郓梁的区块链实践之路丨对话MVP

如何从科研走向实践&#xff1f;李郓梁在社区找到了答案。 作为西安工业大学的硕士研究生&#xff0c;李郓梁从学校的实验室接触区块链技术。通过研读大量论文&#xff0c;李郓梁为区块链多中心化、不可篡改等前沿理论深深着迷&#xff0c;并选择将区块链作为主要研究方向&…...

【hive】hive分桶表的学习

hive分桶表的学习 前言&#xff1a; 每一个表或者分区&#xff0c;hive都可以进一步组织成桶&#xff0c;桶是更细粒度的数据划分&#xff0c;他本质不会改变表或分区的目录组织方式&#xff0c;他会改变数据在文件中的分布方式。 分桶规则&#xff1a; 对分桶字段值进行哈…...

ReactDOM模块react-dom/client没有默认导出报错解决办法

import ReactDOM 模块“"E:/Dpandata/Shbank/rt-pro/node_modules/.pnpm/registry.npmmirror.comtypesreact-dom18.2.7/node_modules/types/react-dom/client"”没有默认导出。 解决办法 只需要在tsconfig.json里面添加配置 "esModuleInterop": true 即…...

TiDB数据库的安装配置

一、 TiDB 软件和硬件环境建议配置 Linux 操作系统版本要求 Linux 操作系统 版本 Red Hat Enterprise Linux 7.3 及以上的 7.x 版本 CentOS 7.3 及以上的 7.x 版本 Oracle Enterprise Linux 7.3 及以上的 7.x 版本 Amazon Linux 2 Ubuntu LTS 16.04 及以上的版本 …...

Unity智慧园区夜景制作

近期使用Unity做了一个智慧园区场景的demo&#xff0c;初步了解了3D开发的一些步骤和知识&#xff0c;以下为制作的步骤&#xff0c;比较简略&#xff0c;备忘&#xff1a; 1. 制作前的设计分析&#xff1a; 1. 分析日光角度&#xff0c;阴影长度&#xff0c;效果 2. 分析冷暖…...

Linux MQTT智能家居项目(LED界面的布局设置)

文章目录 前言一、LED界面布局准备工作二、LED界面布局三、逻辑实现总结 前言 上篇文章我们完成了主界面的布局设置那么这篇文章我们就来完成各个界面的布局设置吧。 一、LED界面布局准备工作 首先添加LED灯光控制的图标。 将选择好的LED图标添加进来&#xff1a; 图标可以…...

LeetCode 160.相交链表

文章目录 &#x1f4a1;题目分析&#x1f4a1;解题思路&#x1f6a9;步骤一&#xff1a;找尾节点&#x1f6a9;步骤二&#xff1a;判断尾节点是否相等&#x1f6a9;步骤三&#xff1a;找交点&#x1f344;思路1&#x1f344;思路2 &#x1f514;接口源码 题目链接&#x1f449;…...

【深度学习_TensorFlow】调用keras高层API重写手写数字识别项目

写在前面 上一阶段我们完成了手写数字识别项目的构建&#xff0c;了解了网络构建、训练、测试的基本流程&#xff0c;但是对于一些常见的操作&#xff0c;因其使用过于频繁&#xff0c;实际上并无必要手动实现&#xff0c;而早已被封装为函数了。 这篇文章我们将了解keras高层…...

柔性数组(C语言)

也许你从来没有听说过柔性数组&#xff08; flexible array &#xff09;这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff0c;结构中的最后一个元素允许是未知大小的数组&#xff0c;这就叫做柔性数组成员&#xff0c;但结 构中的柔性数组成员前面必须至少一个其他…...

判断推理 -- 图形推理 -- 属性规律

中心对称&#xff1a;取一个点&#xff0c;穿过中心能找到另一个对称点。把轴对称 中心对称标出来。五角星不是中心对称。 BD对称轴方向相同&#xff0c;但135自带对称轴&#xff0c;24没带&#xff0c;所以6应该不带对称轴。 百分号不是轴对称。 白色对称轴 平行 或者 夹角…...

【注解使用】使用@Autowired后提示:Field injection is not recommended(Spring团队不推荐使用Field注入)

问题发生场景&#xff1a; 在使用 IDEA 开发 SpringBoot 项目时&#xff0c;在 Controller 类中使用注解 Autowired 注入一个依赖出现了警告提示&#xff0c;查看其他使用该注解的地方同样出现了警告提示。这是怎么回事&#xff1f;由于先去使用了SpringBoot并没有对Spring进行…...

Rust语法: 枚举,泛型,trait

这是我学习Rust的笔记&#xff0c;本文适合于有一定高级语言基础的开发者看不适合刚入门编程的人&#xff0c;对于一些概念像枚举&#xff0c;泛型等&#xff0c;不会再做解释&#xff0c;只写在Rust中怎么用。 文章目录 枚举枚举的定义与赋值枚举绑定方法和函数match匹配枚举…...

hivesql-dayofweek 函数

返回日期或时间戳的星期几。 此函数是 extract(DAYOFWEEK FROM expr) 的同义函数。 语法 dayofweek(expr) 参数 expr&#xff1a;一个 DATE 或 TIMESTAMP 表达式。 返回 一个 INTEGER&#xff0c;其中 1 Sunday 和 7 Saturday。 示例 > SELECT dayofweek(2009-07-30)…...

DIP:《Deep Image Prior》经典文献阅读总结与实现

文章目录 Deep Image Prior1. 方法原理1.1 研究动机1.2 方法 2. 实验验证2.1 去噪2.2 超分辨率2.3 图像修复2.4 消融实验 3. 总结 Deep Image Prior 1. 方法原理 1.1 研究动机 动机 深度神经网络在图像复原和生成领域有非常好的表现一般归功于神经网络学习到了图像的先验信息…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...