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

Spring(Bean生命周期)

目录

  • 1. 生命周期简图
  • 2. 扩展接口介绍
    • 2.1 Aware接口
    • 2.2 BeanPostProcessor接口
    • 2.3 InitializingBean
    • 2.4 DisposableBean
    • 2.5 BeanFactoryPostProcessor接口
  • 3. spring的简化配置
    • 3.1 项目搭建
    • 3.2 Bean的配置和值注入
    • 3.3 AOP的示例

1. 生命周期简图

 

 

2. 扩展接口介绍

2.1 Aware接口

在spring中Aware接口表示的是感知接口,表示spring框架在Bean实例化过程中以回调的方式将特定在资源注入到Bean中去(如:ApplicationContext, BeanName,BeanFactory等等)。Aware接口本事没有声明任何方法,是一个标记接口,其下有多个子接口,如:BeanNameAware,ApplicationContextAware,BeanFactoryAware等。
每个特定的子接口都会固定一个特定的方法,并注入特定的资源,如BeanFactoryAware接口,定义了setBeanFactory(BeanFactory beanFactory),在spring框架实例化Bean过程中,将回调该接口,并注入BeanFactory对象。再例如:ApplicationContextAware接口,定义了setApplicationContext(ApplicationContext applicationContext) 方法,在spring完成Bean实例化,将回调该接口,并注入ApplicationContext对象(该对象即spring的上下文)。

Aware接口示例(ApplicationContextAware 是 Aware 接口的子接口):

public class ApplicationContextAwareTest implements ApplicationContextAware {private static ApplicationContext ctx;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {ctx = applicationContext;System.out.println("---- ApplicationContextAware 示例 -----------");}public static  <T> T getBean(String beanName) {return (T) ctx.getBean(beanName);}}

配置文件:

<bean id="applicationContextAwareTest" class="org.lisen.springstudy.aware.ApplicationContextAwareTest">
</bean>

2.2 BeanPostProcessor接口

Bean在初始化之前会调用该接口的postProcessBeforeInitialization方法,在初始化完成之后会调用
postProcessAfterInitialization方法。

除了我们自己定义的BeanPostProcessor实现外,spring容器也会自动加入几个,如ApplicationContextAwareProcessor、ApplicationListenerDetector,这些都是BeanPostProcessor的实现类。

BeanPostProcessor接口的定义:

public interface BeanPostProcessor {Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

方法的第一个参数为bean实例,第二个参数为beanName,且返回值类型为Object,所以这给功能扩展留下了很大的空间,比如:我们可以返回bean实例的代理对象。

开发示例:

public class BeanPostProcessorTest implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println(beanName + " postProcessBeforeInitialization");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println(beanName + " postProcessAfterInitialization");return bean;}}

配置文件:

<bean id="beanPostProcessorTest" 
class="org.lisen.springstudy.beanpostprocessor.BeanPostProcessorTest"></bean>

2.3 InitializingBean

该接口是Bean初始化过程中提供的扩展接口,接口中只定义了一个afterPropertiesSet方法。如果一个bean实现了InitializingBean接口,则当BeanFactory设置完成所有的Bean属性后,会回调afterPropertiesSet方法,可以在该接口中执行自定义的初始化,或者检查是否设置了所有强制属性等。

也可以通过在配置init-method方法执行自定义的Bean初始化过程。

示例:

public class InitializingBeanTest implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean.afterPropertiesSet() ......");}}

配置文件:

<bean id="initializingBeanTest" class="org.lisen.springstudy.initializingbean.InitializingBeanTest">
</bean>

2.4 DisposableBean

实现了DisposableBean接口的Bean,在该Bean消亡时Spring会调用这个接口中定义的destroy方法。

public class TestService implements DisposableBean {public void hello() {System.out.println("hello work ... ");}@Overridepublic void destroy() throws Exception {System.out.println("TestService destroy ..... ");}
}

在Spring的应用上下文关闭时,spring会回调destroy方法, 如果Bean需要自定义清理工作,则可以实现该接口。

除了实现DisposableBean接口外,还可以配置destroy-method方法来实现自定义的清理工作。

2.5 BeanFactoryPostProcessor接口

该接口并没有在上面的流程图上体现出来,因为该接口是在Bean实例化之前调用的(但BeanFactoryPostProcessor接口也是spring容器提供的扩展接口,所以在此处一同列出),如果有实现了BeanFactoryPostProcessor接口,则容器初始化后,并在Bean实例化之前Spring会回调该接口的postProcessorBeanFactory方法,可以在这个方法中获取Bean的定义信息,并执行一些自定义的操作,如属性检查等。

3. spring的简化配置

3.1 项目搭建

启用注解,对spring的配置进行简化。

  1. 创建一个maven web工程
  2. 将web改为web3.1,参考第一次课件
  3. 修改pom.xml文件,引入必要的包
<properties><spring.version>5.3.18</spring.version><junit.version>4.12</junit.version></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><!-- junit 测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency></dependencies>
  1. 在resources根目录下添加spring的配置文件 spring.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"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.xsdhttp://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.zking"/><!-- 配置properties文件,与Spring @Value 配合使用   方式一    --><!-- <bean ><property name="locations"><list><value>classpath:/test.properties</value></list></property></bean><bean ><property name="properties" ref="configProp"></property></bean> --><!-- 配置properties文件,与Spring @Value 配合使用   方式二 。也可以不使用xml的方式配置,使用程序方式进行配置,可以参考ConfigurationBean  方式三--><bean id="propPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>classpath:/test.properties</value></list></property></bean></beans>

程序方式注册如下:

@Configuration
public class ConfigurationBean {@Beanpublic static PropertySourcesPlaceholderConfigurer setPropertiesFile() {PropertySourcesPlaceholderConfigurer config = new PropertySourcesPlaceholderConfigurer();ClassPathResource contextPath = new ClassPathResource("/test.properties");config.setLocation(contextPath);return config;}}
  1. 在resources根目录下新建一个test.properties文件,和spring.xml的配置文件中的配置是相对应的

3.2 Bean的配置和值注入

  1. 创建并注册一个Bean
@Component("stu")
public class Student {//@Value("#{configProp['stu.name']}")@Value("${stu.name}")private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student [name=" + name + "]";}}
  1. 通过容器获取Bean
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");Student stu = (Student)ctx.getBean("stu");//stu.setName("zs");System.out.println(stu);

3.3 AOP的示例

1.创建一个切面,记录程序运行时间

@Component
@Aspect
@EnableAspectJAutoProxy
public class ProcessAop {//execution(* com.cybx..*.*(..))/*@Pointcut("@annotation(com.zking.mavendemo.config.MyAnnotation)")public void logPointcut() {}*/@Around("execution(* com.zking.mavendemo.service..*.hello*(..))")public Object around(ProceedingJoinPoint  joinPoint) throws Throwable {Class<? extends Signature> signatureClass = joinPoint.getSignature().getClass();System.out.println("AOP signatureClass = " + signatureClass);Object target = joinPoint.getTarget();Class<? extends Object> targetClass = target.getClass();System.out.println("AOP targetClass = " + targetClass);Object returnValue = joinPoint.proceed(joinPoint.getArgs());System.out.println("AOP After ... ");return returnValue;}}

2.创建一个service接口和实现类演示AOP且面
接口:

public interface ITestService {	void helloAop(String msg);
}

实现类:

@Service("testService")
public class TestService implements ITestService {@Overridepublic void helloAop(String msg) {System.out.println("target obj method: " + msg);}}

测试:

		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");ITestService bean = (ITestService)ctx.getBean("testService");bean.helloAop("fdfdfdfdfdfdfdf");

相关文章:

Spring(Bean生命周期)

目录 1. 生命周期简图2. 扩展接口介绍 2.1 Aware接口2.2 BeanPostProcessor接口2.3 InitializingBean2.4 DisposableBean2.5 BeanFactoryPostProcessor接口3. spring的简化配置 3.1 项目搭建3.2 Bean的配置和值注入3.3 AOP的示例 1. 生命周期简图 2. 扩展接口介绍 2.1 Aware接…...

什么是分布式锁?几种分布式锁分别是怎么实现的?

一、什么是分布式锁&#xff1a; 1、什么是分布式锁&#xff1a; 分布式锁&#xff0c;即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题&#xff0c;而分布式锁&#xff0c;就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是&am…...

【一天一门编程语言】R 语言程序设计极简教程

R 语言程序设计极简教程 文章目录 R 语言程序设计极简教程R语言简介1.1 介绍1.2 R 语言的基础知识1.2.1 语法1.2.2 数据类型1.2.3 基本操作1.3 R 语言的高级知识1.3.1 函数1.3.2 包1.3.3 面向对象编程1.4 使用 R 语言的实践1.4.1 数据处理1.4.2 数据可视化1.4.3 数据建模1.4.3.…...

记一次顿悟的经历

2023.02.20 一次顿悟的经历 体验一次顿悟 ​ 需求&#xff1a; ​为避免接收数据时一直阻塞&#xff0c;先调用 select 在一定时间内判断是否有数据可读 如果超时&#xff0c;就报错没读到数据&#xff0c;即使返回 如果仍然在 set 里&#xff0c;就调用 recv 函数接收数据 问…...

19_FreeRTOS软件定时器

目录 软件定时器介绍 FreeRTOS软件定时器特点 软件定时器的命令队列 软件定时器的相关配置 单次定时器和周期定时器 软件定时器结构体成员 FreeRTOS软件定时器相关API函数 实验源码 软件定时器介绍 定时器描述:从指定的时刻开始,经过一个指定时间,然后触发一个超时事件…...

值得推荐!安利5款良心又好用的小众软件

电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。今天分享5个实用的软件&#xff0c;简单实用&#xff0c;效果拉满&#xff0c;堪称工作生活必备&#xff01; …...

Enhanced ShockBurst (ESB)原文翻译

自我学习为主&#xff0c;同时也为所需要的提供一份资料 官方地址 增强型ShockBurst&#xff08;ESB&#xff09;是一种支持双向数据包通信的基本协议&#xff0c;包括数据包缓冲、数据包确认和丢失数据包的自动重传。ESB以低功耗提供无线通信&#xff0c;并且实现的代码量小且…...

软件测试之兼容性测试

对于基于计算机平台的软件&#xff0c;在测试过程中必须考虑软、硬件的兼容性&#xff0c;在设计测试用例的过程中必须考虑数据转换或转移的问题&#xff0c;应该尽力发现其可能带来的错误。不仅是基于计算机平台的软件&#xff0c;对于嵌入式软件也一样&#xff0c;在软件升级…...

笔记(一)——容器

容器分类&#xff1a;序列式容器&#xff1a;每个元素都有固定位置&#xff0c;取决于插入的时机和地点&#xff0c;和元素无关&#xff0c;如vector、deque、list、stack、queue。关联式容器&#xff1a;元素位置取决于特定的排序准则&#xff0c;和插入顺序无关&#xff0c;如…...

C++入门:命名空间

假设这样一种情况&#xff0c;当一个班上有两个名叫 Zara 的学生时&#xff0c;为了明确区分它们&#xff0c;我们在使用名字之外&#xff0c;不得不使用一些额外的信息&#xff0c;比如他们的家庭住址&#xff0c;或者他们父母的名字等等。同样的情况也出现在 C 应用程序中。例…...

操作系统(复试准备)

操作系统&#xff08;复试准备&#xff09; 第一章知识点 操作系统概述 操作系统的概念 负责协调软硬件等计算机资源的工作 为上层用户&#xff0c;应用程序提供简单易用的接口 是一种系统软件 操作系统的功能与目标 资源的管理者 处理机管理&#xff0c;存储器管理&#x…...

2023年CDGA考试模拟题库(501-600)

2023年CDGA考试模拟题库(501-600) 501.希望从数据中获取价值的组织认识到,高质量数据比低质量数据更有价值。使用劣质数据充满风险,会损害组织的声誉,导致罚款、收入损失、客户流失和负面的媒体曝光等组织基于各种业务驱动因素而着手进行数据质量管理活动,下列哪项不属于上述驱…...

NCNN+Int8+yolov5部署和量化

【GiantPandaCV引言】 还记得我在两个月前写的文章吗,关于yolov4-tiny+ncnn+int8量化的详细教程:NCNN+INT8+YOLOV4量化模型和实时推理 后来准备写yolov5+ncnn+int8量化的教程,却在yolov5的量化上遇到了麻烦,一方面是量化后速度更慢了,另一方面是精度下降严重,出现满屏都…...

springboot+vue.js协同过滤算法之智能旅游推荐系统java

目 录 第一章 绪论 3 1.1课题背景 3 1.2课题研究的目的和意义 3 1.3 研究现状 4 1.4论文所做的主要工作 4 第二章 技术介绍 5 2.1B/S结构 5 2.2MySQL 介绍 5 2.3MySQL环境配置 6 第三章 系统分析与设计 8 3.1系统说明 8 3.2系统可行性分析…...

Google Brain新提出的优化器“Lion”,效果要比Adam(W)更好

Google Brain新提出的优化器“Lion”&#xff0c;效果要比Adam(W)更好 论文地址&#xff1a;https://arxiv.org/abs/2302.06675代码地址&#xff1a;https://github.com/google/automl/blob/master/lion/lion_pytorch.py 1 简单、内存高效、运行速度更快 与 AdamW 和各种自适…...

慢雾:Discord 私信钓鱼手法分析

事件背景 5 月 16 日凌晨&#xff0c;当我在寻找家人的时候&#xff0c;从项目官网的邀请链接加入了官方的 Discord 服务器。在我加入服务器后立刻就有一个"机器人"(Captcha.bot)发来私信要我进行人机验证。这一切看起来相当的合理。我也点击了这个验证链接进行查看…...

2023-2-25 刷题情况

交换字符使得字符串相同 题目描述 有两个长度相同的字符串 s1 和 s2&#xff0c;且它们其中 只含有 字符 “x” 和 “y”&#xff0c;你需要通过「交换字符」的方式使这两个字符串相同。 每次「交换字符」的时候&#xff0c;你都可以在两个字符串中各选一个字符进行交换。 …...

【数据结构】双向链表的接口实现(附图解和源码)

双向链表的接口实现&#xff08;附图解和源码&#xff09; 文章目录双向链表的接口实现&#xff08;附图解和源码&#xff09;前言一、定义结构体二、接口实现&#xff08;附图解源码&#xff09;1.初始化双向链表2.开辟新空间3.尾插数据4.尾删数据5.打印双向链表中数据6.头插数…...

数据结构与算法之[把数字翻译成字符串]动态规划

前言&#xff1a;最近在刷动态规划的算法题目&#xff0c;感觉这一类题目还是有一点难度的&#xff0c;但是不放弃也还是能学好的&#xff0c;今天给大家分享的是牛客网中的编程题目[把数字翻译成字符串]&#xff0c;这是一道经典的面试题目&#xff0c;快手&#xff0c;字节跳…...

java 面向对象三大特性之多态 万字详解(超详细)

目录 前言 : 一、为什么需要多态 : 1.白璧微瑕 : 2.举栗&#xff08;请甘雨,刻晴,钟离吃饭&#xff09;: 3.代码 : 4.问题 : 二、什么是多态 : 1.定义 : 2.多态的实现步骤&#xff08;重要&#xff09; : 三、多态的使用 : 1.多态中成员方法的使用&#xff08;重要…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...