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

         为了帮助大家更深入的理解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不同,后者是像一个单一的实例化对象,由容器管理其生命周期。
 

当前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.icon-default.png?t=N7T8https://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);}//注册有销毁方法的beanregisterDisposableBeanIfNecessary(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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://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 {@Testpublic 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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

短剧解说小程序搭建,短剧解说小程序源码

短剧解说小程序搭建&#xff0c;短剧解说小程序源码 可定制开发小程序&#xff0c;H5&#xff0c;APP等系统 有需要可定制可出源码&#xff0c;这个是啥你懂的(VVVVVVVVVVV)&#xff1a;二五四九七八九零五九 需要源码或搭建可看上面的数字信息 短剧解说小程序搭建 小程序使用…

【案例教学】华为云API图像搜索ImageSearch的快捷性—AI帮助您快速归类图片

云服务、API、SDK&#xff0c;调试&#xff0c;查看&#xff0c;我都行 阅读短文您可以学习到&#xff1a;人工智能AI同类型的相片合并归类 1 IntelliJ IDEA 之API插件介绍 API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts IDE&#xff0c;基于华为云…

R5F5210BBDFB#10-ASEMI代理瑞萨芯片R5F5210BBDFB#10

编辑&#xff1a;ll R5F5210BBDFB#10-ASEMI代理瑞萨芯片R5F5210BBDFB#10 型号&#xff1a;R5F5210BBDFB#10 品牌&#xff1a;瑞萨&#xff08;Renesas) 封装&#xff1a;LFQFP-144 R5F5210BBDFB#10描述&#xff1a; R5F5210BBDFB#10具有1.62V至5.5V的宽工作电压范围&…

Linux内核4.14版本——drm框架分析(11)——DRM_IOCTL_MODE_ADDFB2(drm_mode_addfb2)

目录 1. drm_mode_addfb2 2. drm_internal_framebuffer_create 3. drm_fb_cma_create->drm_gem_fb_create->drm_gem_fb_create_with_funcs 4. drm_gem_fb_alloc 4.1 drm_helper_mode_fill_fb_struct 4.2 drm_framebuffer_init 5. 调用流程图 书接上回&#xff0c;使…

USB接口针式打印机

1 针式打印机原理 - 针式打印机16针是纵向排列&#xff0c;每次打印垂直的16bit&#xff0c;然后右移一bit&#xff0c;继续下列打印&#xff1b;字节的MSB表示最上面的点&#xff0c;字节LSB表示最下面的点 - 由于汉字字模的点阵是横向排列的&#xff0c;而提供给打印头的信息…

看板管理:以可视化方式确定任务优先级

确定工作的优先级是我们今天都要面对的挑战。若处理不当&#xff0c;我们就可能试图一心多用&#xff0c;从而严重损害工作效率。 使用看板方法来设定工作优先级是一种非常直观、快速的方法。 确定工作优先级的看板方法 看板工作流程管理方法的核心在于工作可视化。工作被划…

Docker基础入门

文章目录 前言一、什么是DockerDocker 安装Docker 镜像Docker 容器Docker 安装nginx 前言 在Linux上安装软件有三种方式&#xff1a; 在redhat系列下的发行版通过rpm包安装或者是在debian系列下的发行版通过deb包安装&#xff1b;通过工具安装&#xff0c;在redhat系列下的发…

Mybatis中动态SQL标签和内置参数介绍

Mybatis中动态SQL标签和内置参数 一、MyBatis动态SQL 1.1、sql标签 sql标签用于抽取公用的SQL代码&#xff0c;定义sql标签的时候需要通过【id】属性设置唯一标识。 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-…

【FAQ】视频监控管理平台/视频汇聚平台EasyCVR安全检查相关问题及解决方法3.0

智能视频监控系统/视频云存储/集中存储/视频汇聚平台EasyCVR具备视频融合汇聚能力&#xff0c;作为安防视频监控综合管理平台&#xff0c;它支持多协议接入、多格式视频流分发&#xff0c;视频监控综合管理平台EasyCVR支持海量视频汇聚管理&#xff0c;可应用在多样化的场景上&…

DHT11 温湿度传感器

目录 1.DHT11 温湿度传感器概述 2.检测DHT11温湿度传感器模块是否存在 3.通过编写代码读取温湿度数据​编辑 4.将读取到的温湿度数据通过串口上传 1.DHT11 温湿度传感器概述 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;应用领域&am…

【资源推荐】一站式机器学习学习资料

我之前向大家推荐了许多关于人工智能数学原理与应用的资料&#xff0c;其中包括线性代数、机器学习和深度学习等方面的内容。 交互式线性代数学习网站 沉浸式线性代数学习网站 Kaggle大神教你机器学习 今天我将继续向大家推荐一个一站式学习机器学习的绝佳资源&#xff1a;《…

《TCP/IP网络编程》阅读笔记--多线程服务器端的实现

1--多线程的优点 多进程服务器的缺点&#xff1a; ① 创建进程的过程会带来一定的开销&#xff1b; ② 为了完成进程间的数据交换&#xff0c;需要特殊的 IPC 技术&#xff1b; ③ 进程间的上下文切换是创建进程时的最大开销&#xff1b; 多线程的优点&#xff1a; ① 线程的创…

C#类与类库调用注意事项

类 创建一个类文件&#xff0c;myfunction.cs //静态类&#xff1a;直接引用、无需实例化 static public int jiafa(int V) //普通类&#xff1a;引用时需要实例化 public int jiafa(int V)using System; using System.Collections.Generic; using System.Diagnostics; using …

无涯教程-JavaScript - ISNA函数

描述 如果指定的值为Excel&#xff03;N/A错误值,或者表达式返回Excel&#xff03;N/A错误,则ISNA函数将返回逻辑值TRUE。否则返回FALSE。当值不可用于您的公式时,将发生Excel&#xff03;N/A错误。 语法 ISNA (value)争论 Argument描述Required/OptionalvalueValue or exp…

《算法竞赛·快冲300题》每日一题:“点灯游戏”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 点…

vue cli 打包、生产环境http-proxy-middleware代理

结构树 版本 1、创建vue.config.js const path require(path); const UglifyJsPlugin require(uglifyjs-webpack-plugin) //压缩 const CompressionWebpackPlugin require(compression-webpack-plugin) const isProduction process.env.NODE_ENV ! development;module.exp…

请求与响应以及REST风格

目录 请求与响应请求参数参数传递 五种类型参数传递普通参数POJO数据类型嵌套POJO类型参数数组类型参数集合类型参数 JSON数据传输参数JSON普通数组JSON对象数据JSON对象数组知识点1&#xff1a;EnableWebMvc知识点2&#xff1a;RequestBodyRequestBody与RequestParam区别日期类…

[SICTF 2023] webmisc

文章目录 webBaby_PHP涉及知识点 我全都要RCE你能跟得上我的speed吗 miscPixel_art攻破这个压缩包&#xff01; web Baby_PHP 涉及知识点 php解析特性apache换行解析漏洞无参RCE 源代码 <?php highlight_file(__FILE__); error_reporting(0);$query $_SERVER[QUERY_ST…

OpenCV Series : Target Box Outline Border

角点 P1 (255, 000, 000) P2 (000, 255, 000) P3 (000, 000, 255) P4 (000, 000, 000)垂直矩形框 rect cv2.minAreaRect(cnt)targetColor roi_colortargetThickness 1targetColor (255, 255, 255)if lineVerbose:if True:cv2.line(ph…

做机器视觉工程师,其实挺没意思的

3.康耐视VisionPro高级脚本系列教程-3.脚本编辑错误和运行错误调试方法&#xff0c;break和Contitinuee的差别_哔哩哔哩_bilibili 其实人生就是“有时有意思&#xff0c;有时没意思”。 心里有太多的不甘心&#xff0c;太多的苦水&#xff0c;是没法再吃学习的苦&#xff0c…