[源码系列:手写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不同,后者是像一个单一的实例化对象,由容器管理其生命周期。

prototype作用域
可见prototype类型的bean并不受spring容器的管理,你需要自己负责销毁或释放这些Bean实例,以防止内存泄漏。
代码分支
核心代码
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的支持的更多相关文章
- Spring源码分析 手写简单IOC容器
Spring的两大特性就是IOC和AOP. IOC Container,控制反转容器,通过读取配置文件或注解,将对象封装成Bean存入IOC容器待用,程序需要时再从容器中取,实现控制权由程序员向程序的 ...
- 《四 spring源码》手写springioc框架
手写SpringIOCXML版本 /** * 手写Spring专题 XML方式注入bean * * * */ public class ClassPathXmlApplicationContext { ...
- 从零开始手写 spring ioc 框架,深入学习 spring 源码
IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过 ...
- 框架源码系列六:Spring源码学习之Spring IOC源码学习
Spring 源码学习过程: 一.搞明白IOC能做什么,是怎么做的 1. 搞明白IOC能做什么? IOC是用为用户创建.管理实例对象的.用户需要实例对象时只需要向IOC容器获取就行了,不用自己去创建 ...
- 《四 spring源码》手写springmvc
手写SpringMVC思路 1.web.xml加载 为了读取web.xml中的配置,我们用到ServletConfig这个类,它代表当前Servlet在web.xml中的配置信息.通过web.xml ...
- Spring源码 20 手写模拟源码
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- 利用递归,反射,注解等,手写Spring Ioc和Di 底层(分分钟喷倒面试官)了解一下
再我们现在项目中Spring框架是目前各大公司必不可少的技术,而大家都知道去怎么使用Spring ,但是有很多人都不知道SpringIoc底层是如何工作的,而一个开发人员知道他的源码,底层工作原理,对 ...
- Spring源码剖析3:Spring IOC容器的加载过程
本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https ...
- 源码分析 | 手写mybait-spring核心功能(干货好文一次学会工厂bean、类代理、bean注册的使用)
作者:小傅哥 博客:https://bugstack.cn - 汇总系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言介绍 一个知识点的学习过程基本分为:运行helloworld ...
- Spring源码剖析2:Spring IOC容器的加载过程
spring ioc 容器的加载流程 1.目标:熟练使用spring,并分析其源码,了解其中的思想.这篇主要介绍spring ioc 容器的加载 2.前提条件:会使用debug 3.源码分析方法:In ...
随机推荐
- Datawhale AI 夏令营-天池Better Synth多模态大模型数据合成挑战赛-task3持续上分(更新中)
在大数据.大模型时代,随着大模型发展,互联网数据渐尽且需大量处理标注,为新模型训练高效合成优质数据成为新兴问题."天池 Better Synth - 多模态大模型数据合成挑战赛"应 ...
- G1原理—2.G1是如何提升分配对象效率
大纲 1.G1的对象分配原理是怎样的 2.深入分析TLAB机制原理 3.借助TLAB分配对象的实现原理是什么 4.什么是快速分配 + 什么是慢速分配 5.大对象分配的过程 + 与TLAB的关系 6.救 ...
- 在shell脚本中为日志添加颜色
在 Shell 脚本中,可以通过添加 ANSI 转义序列来为日志输出添加颜色.以下是一个完整的 Shell 脚本示例,包含日志颜色定义.日志函数封装以及使用示例: 完整脚本:colored_logs. ...
- Golang-反射10
http://c.biancheng.net/golang/reflect/ Go语言反射(reflection)简述 反射(reflection)是在 Java 出现后迅速流行起来的一种概念,通过反 ...
- runoob-scala
https://www.runoob.com/scala/scala-tutorial.html Scala 简介 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成 ...
- 一篇关于c语言的大补帖
一晃今年又开始了,作为一个失意的中年技术男,现在的心境真的是五味杂陈.赶紧写一篇吧,我怕过了这个点,今年就在没有那个心情去写了. 因为是基础嘛,从事软件开发以来c或者c++相关的东西断断续续 也刷了差 ...
- VMware的快照原理
本文分享自天翼云开发者社区<VMware的快照原理>,作者:m****n VMware的快照是基于数据块的快照.快照也是以一个文件方式存在的,缺省位置和虚拟机在同一目录下,它是一个Delt ...
- mysql之增删改
编写配置文件[db.properties]: driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/jdbcStudy?useUni ...
- P2730 [USACO3.2] 魔板 Magic Squares 题解
一些废话 夜深人静的夜晚,我开了这道题.看起来,完成它是一件轻而易举的事.我想了想,打开Dev-C++,开始写代码. 然而,那时的我还不知道,我踏入了深渊...... 咳咳,中二病犯了,前面的文字请忽 ...
- python进行大乐透和双色球选号(LSTM预测和随机选号)
文章仅供参考学习 1.LSTM预测 首先去爬取数据 这个是爬取大乐透的,从07年爬到最新一期 import requests from bs4 import BeautifulSoup import ...
https://github.com/yihuiaa/little-spring