5、Spring之bean的作用域和生命周期
5.1、bean的作用域
5.1.1、单例(默认且常用)
5.1.1.1、配置bean

注意:当bean不配置scope属性时,默认是singleton(单例)
<?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="student" class="org.rain.spring.pojo.Student"></bean>
</beans>
5.1.1.2、测试

由控制台日志可知,此时ioc获取到的两个bean本质上是同一个对象
@Test
public void testScope() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-scope.xml");
Student student1 = applicationContext.getBean(Student.class);
Student student2 = applicationContext.getBean(Student.class);
System.out.println(student1 == student2);
}
5.1.2、多例
5.1.2.1、配置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">
<!--
scope属性:设置bean的作用域
当属性值为singleton时,在IOC容器中这个bean的对象始终为单实例;且创建对象的时机是IOC容器初始化时
当属性值为prototype时,在IOC容器中这个bean的对象有多个实例;且创建对象的时机是获取bean时
-->
<bean id="student" class="org.rain.spring.pojo.Student" scope="prototype"></bean>
</beans>
5.1.2.2、测试

由控制台日志可知,此时ioc获取到的两个bean本质上是不同的对象
5.1.3、其他作用域
如果是在WebApplicationContext环境下还会有另外两个作用域(但不常用):
request:在一个请求范围内有效
session:在一个会话范围内有效
5.2、bean的生命周期
5.2.1、创建User类

package org.rain.spring.pojo;
/**
* @author liaojy
* @date 2023/8/3 - 23:59
*/
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
public User() {
System.out.println("生命周期1:创建对象");
}
public User(Integer id, String username, String password, Integer age) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
System.out.println("生命周期2:依赖注入");
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void initMethod(){
System.out.println("生命周期3:初始化");
}
public void destroyMethod(){
System.out.println("生命周期4:销毁");
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
'}';
}
}
5.2.2、配置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">
<!--
init-method属性:指定初始化方法
destroy-method属性:指定销毁方法
-->
<bean id="user" class="org.rain.spring.pojo.User" init-method="initMethod" destroy-method="destroyMethod">
<property name="id" value="1"></property>
<property name="username" value="张三"></property>
<property name="password" value="123"></property>
<property name="age" value="11"></property>
</bean>
</beans>
5.2.3、测试

@Test
public void testLifecycle(){
//ConfigurableApplicationContext是ApplicationContext子接口,扩展了刷新和关闭容器的方法
ConfigurableApplicationContext ioc = new ClassPathXmlApplicationContext("spring-lifecycle.xml");
User user = ioc.getBean(User.class);
System.out.println(user);
ioc.close();
}
5.3、作用域对生命周期的影响
5.3.1、作用域为单例时
5.3.1.1、配置bean

<bean id="user" class="org.rain.spring.pojo.User" init-method="initMethod" destroy-method="destroyMethod">
<property name="id" value="1"></property>
<property name="username" value="张三"></property>
<property name="password" value="123"></property>
<property name="age" value="11"></property>
</bean>
5.3.1.2、测试

由控制台日志可知,当bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
@Test
public void testLifecycle(){
//ConfigurableApplicationContext是ApplicationContext子接口,扩展了刷新和关闭容器的方法
ConfigurableApplicationContext ioc = new ClassPathXmlApplicationContext("spring-lifecycle.xml");
}
5.3.2、作用域为多例时
5.3.2.1、配置bean

<bean id="user" class="org.rain.spring.pojo.User" init-method="initMethod" destroy-method="destroyMethod" scope="prototype">
<property name="id" value="1"></property>
<property name="username" value="张三"></property>
<property name="password" value="123"></property>
<property name="age" value="11"></property>
</bean>
5.3.2.2、测试

由控制台日志可知,当bean的作用域为多例时,生命周期的前三个步骤会在获取bean时执行
@Test
public void testLifecycle(){
//ConfigurableApplicationContext是ApplicationContext子接口,扩展了刷新和关闭容器的方法
ConfigurableApplicationContext ioc = new ClassPathXmlApplicationContext("spring-lifecycle.xml");
User user = ioc.getBean(User.class);
}
5.4、bean的后置处理器
5.4.1、创建bean的后置处理器

注意:自定义的bean后置处理器,需要实现BeanPostProcessor接口
package org.rain.spring.process;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @author liaojy
* @date 2023/8/4 - 23:52
*/
public class MyBeanProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanProcessor-->后置处理器postProcessBeforeInitialization");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanProcessor-->后置处理器postProcessAfterInitialization");
return bean;
}
}
5.4.2、配置bean的后置处理器

注意:bean后置处理器不是单独针对某一个bean生效,而是针对IOC容器中所有bean都会执行
<!-- bean的后置处理器要放入IOC容器才能生效 -->
<bean id="myBeanPostProcessor" class="org.rain.spring.process.MyBeanProcessor"></bean>
5.4.3、测试

由控制台日志可知,bean的后置处理器会在生命周期的初始化前后添加额外的操作
@Test
public void testLifecycle(){
//ConfigurableApplicationContext是ApplicationContext子接口,扩展了刷新和关闭容器的方法
ConfigurableApplicationContext ioc = new ClassPathXmlApplicationContext("spring-lifecycle.xml");
User user = ioc.getBean(User.class);
System.out.println(user);
ioc.close();
}
5.5、具体的生命周期过程
bean对象创建(调用无参构造器)
给bean对象设置属性
bean对象初始化之前操作(由bean的后置处理器负责)
bean对象初始化(需在配置bean时指定初始化方法)
bean对象初始化之后操作(由bean的后置处理器负责)
bean对象就绪可以使用
bean对象销毁(需在配置bean时指定销毁方法)
IOC容器关闭
5、Spring之bean的作用域和生命周期的更多相关文章
- 详解Spring中Bean的作用域与生命周期
摘要:在利用Spring进行IOC配置时,关于bean的配置和使用一直都是比较重要的一部分,同时如何合理的使用和创建bean对象,也是小伙伴们在学习和使用Spring时需要注意的部分,所以这一篇文章我 ...
- Spring中Bean的作用域、生命周期
Bean的作用域.生命周期 Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).protot ...
- Spring之Bean的作用域与生命周期
在前面博客中提到容器启动获得BeanDefinition对象中有一个scope 属性.该属性控制着bean对象的作用域.本章节介绍Bean的作用域及生命周期,了解bean是怎么来的又怎么没的. 一.B ...
- Spring中bean的作用域与生命周期
在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean.简单地讲,bean 就是由 IOC 容器初始化.装配及管理的对象,除此之外,bean 就与 ...
- Spring中Bean的作用域和生命周期
作用域的种类 Spring 容器在初始化一个 Bean 的实例时,同时会指定该实例的作用域.Spring3 为 Bean 定义了五种作用域,具体如下. 1)singleton 单例模式,使用 sing ...
- Spring bean的作用域和生命周期
bean的作用域 1.singleton,prototype, web环境下:request,session,gloab session 2.通过scope="" 来进行配置 3. ...
- Spring框架系列(三)--Bean的作用域和生命周期
Bean的作用域 Spring应用中,对象实例都是在Container中,负责创建.装配.配置和管理生命周期(new到finalize()) Spring Container分为两种: 1.BeanF ...
- Spring bean的作用域以及生命周期
一.request与session的区别 request简介 request范围较小一些,只是一个请求. request对象的生命周期是针对一个客户端(说确切点就是一个浏览器应用程序)的一次请求,当请 ...
- Spring ( 三 ) Spring的Bean的装配与生命周期、专用测试
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.对象的生命周期 1.IOC之Bean的生命周期 创建带有生命周期方法的bean public cla ...
- bean的作用域和生命周期
一.Bean作用域 二.生命周期 其中,这个类实现各种接口重写各种方法,会按bean的声明周期按序执行: 其中,自定义的初始化和自定义销毁的方法不是实现接口重写,而是成员方法,并且在装配bean即在x ...
随机推荐
- 2022-01-06:N个结点之间,表世界存在双向通行的道路,里世界存在双向通行的传送门. 若走表世界的道路,花费一分钟. 若走里世界的传送门,不花费时间,但是接下来一分钟不能走传送门. 输入: T为
2022-01-06:N个结点之间,表世界存在双向通行的道路,里世界存在双向通行的传送门. 若走表世界的道路,花费一分钟. 若走里世界的传送门,不花费时间,但是接下来一分钟不能走传送门. 输入: T为 ...
- django视图中使用return redirect(reverse('')) 没有传参出现题:Reverse for ‘‘ with no arguments no arguments not
redirect 的作用是跳转 reverse的作用是反向解析 当无法反向解析的时候要确认urls.py中的path参数,name参数是否一直
- 「P3」试下1个半月能不能水出个毕设
前言 虽然说标题上写的时间是1个半月,但是实际上,真正开始行动的时间应该1个月都没有.之前都是在公司上班没活的时候干的.现在请了个长假,专门来做毕业设计:预计5月前能做完整个毕业设计,然后劳动节放假期 ...
- vue3+vite2+element-plus+ts搭建一个项目
花了几天用 vue3+ vite2+ element-plus+ ts 搭了个 极简版骨架型数据管理系统,使用静态数据模拟动态路由,路由拦截,登录页面鉴权等,使用了iconify字体图标,整合了ces ...
- flutter填坑之旅(widget原理篇)
Flutter 的跨平台思路快速让他成为"新贵",连跨平台界的老大哥 "JS" 语言都"视而不见",大胆的选择 Dart 也让 Flutte ...
- 代码随想录算法训练营Day23 二叉树
代码随想录算法训练营 代码随想录算法训练营Day23 二叉树|669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树 总结篇 669. 修剪二叉搜索树 题目链接 ...
- 百度飞桨(PaddlePaddle) - PP-OCRv3 文字检测识别系统 基于 Paddle Serving快速使用(服务化部署 - CentOS 7)
目录 Paddle Serving服务化部署实战 准备预测数据和部署环境 环境准备 安装 PaddlePaddle 2.0 安装 PaddleOCR 准备PaddleServing的运行环境, 模型转 ...
- 「AntV」X6开发实践:踩过的坑与解决方案
长期更新版文档请移步语雀(「AntV」X6开发实践:踩过的坑与解决方案 (yuque.com)) ️ | 如何自定义拖拽源? 相信你们在开发中更多的需求是需要自定义拖拽源,毕竟自定义的功能扩展性高一些 ...
- MQ系列13:消息大量堆积如何为解决
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...
- 曲线艺术编程 coding curves 第八章 贝赛尔曲线(Bézier Curves)
贝赛尔曲线(Bézier Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(s ...