为了帮助大家更深入的理解bean的作用域,特意将BeanDefinition的双例支持留到本章节中,创建Bean,相关Reader读取等逻辑都有所改动。

内容介绍

在Spring中,Bean的作用域(Scope)定义了Bean的生命周期和可见性。包括单例和原型,在本章节中我们将为Bean添加多例的支持,下面是Prototype作用域的几个特征介绍:

1. 多例(Prototype): Bean的prototype作用域表示每次从容器中获取该Bean时都会创建一个新的实例。每个请求或依赖注入都会导致创建一个全新的Bean对象。

2. 不受Spring容器管理: prototype作用域的Bean实例不受Spring容器的管理,容器在创建Bean之后不会再跟踪它。这意味着Spring容器不会负责释放或销毁prototype作用域的Bean。一旦Bean被创建并交给调用者,调用者负责Bean的生命周期,包括销毁。

3. 适用场景: prototype作用域适用于那些每次获取实例时都需要全新状态的Bean,例如,HTTP请求的处理器或线程池中的任务。这样可以确保每次获取的Bean都是独立的,不会影响其他实例。

这里设计到设计模式中的原型模式,形象地说,可以将prototype作用域的Bean比喻为一个不断复制的模具。每次你需要一个新的Bean实例时,Spring容器会根据模具再次制作一个全新的Bean。这个模具本身不受容器管理,而是由你自己管理它的生命周期。这与singleton作用域的Bean不同,后者是像一个单一的实例化对象,由容器管理其生命周期。


prototype作用域

可见prototype类型的bean并不受spring容器的管理,你需要自己负责销毁或释放这些Bean实例,以防止内存泄漏。

代码分支

GitHub - yihuiaa/little-spring: 剖析Spring源码,包括常见特性IOC、AOP、三级缓存等...剖析Spring源码,包括常见特性IOC、AOP、三级缓存等... Contribute to yihuiaa/little-spring development by creating an account on GitHub.https://github.com/yihuiaa/little-spring

核心代码

BeanDefinition

    private String scope = SCOPE_SINGLETON;
private boolean singleton = true;
private boolean prototype = false;
public static String SCOPE_SINGLETON = "singleton";
public static String SCOPE_PROTOTYPE = "prototype"; public void setScope(String scope) {
this.scope = scope;
this.singleton = SCOPE_SINGLETON.equals(scope);
this.prototype = SCOPE_PROTOTYPE.equals(scope);
} public boolean isSingleton() {
return this.singleton;
}
public boolean isPrototype() {
return this.prototype;
}

AbstractAutowireCapableBeanFactory#doCreateBean()

...
protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) {
Object bean = null;
try {
bean = createBeanInstance(beanDefinition);
//为bean填充属性
applyPropertyValues(beanName, bean, beanDefinition);
//执行bean的初始化方法和BeanPostProcessor的前置和后置处理方法
initializeBean(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed", e);
} //注册有销毁方法的bean
registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); if (beanDefinition.isSingleton()) {
addSingleton(beanName, bean);
}
return bean;
}
...

AbstractAutowireCapableBeanFactory#registerDisposableBeanIfNecessary()

	/**
* 注册有销毁方法的bean,即bean继承自DisposableBean或有自定义的销毁方法
*
* @param beanName
* @param bean
* @param beanDefinition
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition) {
//只有singleton类型bean会执行销毁方法
if (beanDefinition.isSingleton()) {
if (bean instanceof DisposableBean || StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())) {
registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, beanDefinition));
}
}
}

测试

prototype-bean.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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <bean id="car" class="bean.Car" scope="prototype">
<property name="name" value="Rolls-Royce"/>
</bean> </beans>

单元测试

public class PrototypeBeanTest {
@Test
public void testPrototype() throws Exception {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:prototype-bean.xml"); Car car1 = applicationContext.getBean("car", Car.class);
Car car2 = applicationContext.getBean("car", Car.class);
System.out.println(car1 == car2);;
}
}

测试结果

false
Process finished with exit code 0

[源码系列:手写spring] IOC第十三节:Bean作用域,增加prototype的支持的更多相关文章

  1. Spring源码分析 手写简单IOC容器

    Spring的两大特性就是IOC和AOP. IOC Container,控制反转容器,通过读取配置文件或注解,将对象封装成Bean存入IOC容器待用,程序需要时再从容器中取,实现控制权由程序员向程序的 ...

  2. 《四 spring源码》手写springioc框架

    手写SpringIOCXML版本 /** * 手写Spring专题 XML方式注入bean * * * */ public class ClassPathXmlApplicationContext { ...

  3. 从零开始手写 spring ioc 框架,深入学习 spring 源码

    IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过 ...

  4. 框架源码系列六:Spring源码学习之Spring IOC源码学习

    Spring 源码学习过程: 一.搞明白IOC能做什么,是怎么做的  1. 搞明白IOC能做什么? IOC是用为用户创建.管理实例对象的.用户需要实例对象时只需要向IOC容器获取就行了,不用自己去创建 ...

  5. 《四 spring源码》手写springmvc

    手写SpringMVC思路 1.web.xml加载  为了读取web.xml中的配置,我们用到ServletConfig这个类,它代表当前Servlet在web.xml中的配置信息.通过web.xml ...

  6. Spring源码 20 手写模拟源码

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  7. 利用递归,反射,注解等,手写Spring Ioc和Di 底层(分分钟喷倒面试官)了解一下

    再我们现在项目中Spring框架是目前各大公司必不可少的技术,而大家都知道去怎么使用Spring ,但是有很多人都不知道SpringIoc底层是如何工作的,而一个开发人员知道他的源码,底层工作原理,对 ...

  8. Spring源码剖析3:Spring IOC容器的加载过程

    本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https ...

  9. 源码分析 | 手写mybait-spring核心功能(干货好文一次学会工厂bean、类代理、bean注册的使用)

    作者:小傅哥 博客:https://bugstack.cn - 汇总系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言介绍 一个知识点的学习过程基本分为:运行helloworld ...

  10. Spring源码剖析2:Spring IOC容器的加载过程

    spring ioc 容器的加载流程 1.目标:熟练使用spring,并分析其源码,了解其中的思想.这篇主要介绍spring ioc 容器的加载 2.前提条件:会使用debug 3.源码分析方法:In ...

随机推荐

  1. 2020-2024 IDEA安装+激活

    一.下载 1. IDEA各版本官方下载入口 IDEA官网下载地址 2. 选择左边,然后点击[20xx.x.x-Windows(exe)] PS: 如需下载特定版本,可以往下拉,都是选择[202x.x- ...

  2. Diary -「PKUSC 2022」浅谈一类 emo 文学在 OI 游记中的运用

      我突然发现这是我第一次完成这样一篇游记--   一篇记录了绝对意义上"爆炸"的游记.   SC 的前几天,我被一些奇怪的理由说服停课.省选已经过去了吧,机房里除了我全是省队.不 ...

  3. w3cschool-Python3 教程

    https://www.w3cschool.cn/python3/ Python 特点 1.易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单. 2.易于阅读: ...

  4. 深入理解第二范式(2NF):提升数据库设计的有效性与灵活性

    title: 深入理解第二范式(2NF):提升数据库设计的有效性与灵活性 date: 2025/1/16 updated: 2025/1/16 author: cmdragon excerpt: 数据 ...

  5. 如何分析jmeter性能测试数据

    1.jmeter插件 https://blog.csdn.net/weixin_39430584/article/details/80947093 http://www.doc88.com/p-214 ...

  6. JVM:java虚拟机栈

  7. Q: 导出的照片时,批量修改创建时间和修改时间。

    使用PowerShell脚本批量修改目录下所有照片(包括但不限于.jpg, .jpeg, .png等格式)的创建时间和最后修改时间,你可以采用以下脚本.这个脚本将遍历指定目录及其子目录下的所有支持的照 ...

  8. 单用户模式启动 CentOS/RHEL 7/8 的三种方法

    单用户模式启动 CentOS/RHEL 7/8 的三种方法   单用户模式,也被称为维护模式,超级用户可以在此模式下恢复/修复系统问题. 通常情况下,这类问题在多用户环境中修复不了.系统可以启动但功能 ...

  9. 定制化训练DeepSeek模型:LoAR、COT推理与SFT技术应用

    DeepSeek-R1 模型微调系列 DeepSeek-R1 模型微调系列一. 前言介绍本文内容:1.1 项目背景1.2 LoRA和 QLoRA 简介1.3 LLaMA 架构和 Qwen 架构LLaM ...

  10. 通过virtual-install安装

    命令行 [root@kvm1 ~]# qemu-img create -f qcow2 centos6.10b.qcow2 10G Formatting 'vm1-disk1.qcow2', fmt= ...