Spring是如何实现scope作用域支持

众所周知在Spring的Bean当中是存在两种作用域的,即单例模式与多例模式,可通过scope来指定

下面就是注册一个多例Bean

java 复制代码
<bean id="people" class="org.qlspringframework.beans.ioc.bean.People" scope="prototype">  
    <property name="name" value="derek"/>  
</bean>

那么什么是单例模式什么是多例模式呢?说白了其实就是与是否通过Spring的完整生命周期有关,对于单例模式的Bean,会通过完整的生命周期来创建,同时也会将Bean加入到Spring的缓存当中,再次获取会从缓存当中拿。那么多例模式就不会产生这种情况,每一次通过get()方法获取 Bean的时候都是重新创建。

下面看一下如何实现scope作用域支持

首先Bean的作用域是通过BeanDefinition定义的,那我们就需要在其中定义相关属性,除此之外Bean的默认作用域是单例,也就是说在用户未指定的情况下应保持singleton。

BeanDefinition

java 复制代码
public static String SCOPE_SINGLETON = "singleton";  
  
public static String SCOPE_PROTOTYPE = "prototype";  
  
private String scope = SCOPE_SINGLETON;

  
// 单列模式  
private boolean singleton = true;  
  
// 多列模式  
private boolean prototype = false;  
  
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;  
}

之后就是对XML的解析过程

XmlBeanDefinitionReader

复制代码
```java
String beanScope = bean.attributeValue(SCOPE_ATTRIBUTE);  
  
beanDefinition.setDestroyMethodName(destroyMethodName);  
if (StrUtil.isNotEmpty(beanScope)) {  
    beanDefinition.setScope(beanScope);  
}

这样我们的基础准备就完毕了,剩下的是对执行Bean生命周期的过程进行修改

首先就是多例Bean在创建完毕后不需要加入缓存

AbstractAutowireCapableBeanFactory

java 复制代码
// 创建完毕后加入缓存  
if (beanDefinition.isSingleton()){  
    super.addSingletonBean(beanName, bean);  
}

其次对于多例Bean不需要提前初始化

DefaultListableBeanFactory

java 复制代码
/**  
 * 提前实例化所有单例Bean。  
 */  
@Override  
public void preInstantiateSingletons() {  
    beanDefinitionMap.forEach((key,value) -> {  
        if (value.isSingleton()){  
            super.getBean(key);  
        }  
    });  
}
相关推荐
月明长歌1 分钟前
【码道初阶】【Leetcode606】二叉树转字符串:前序遍历 + 括号精简规则,一次递归搞定
java·数据结构·算法·leetcode·二叉树
原来是好奇心2 分钟前
深入Spring Boot源码(八):高级特性与扩展点深度解析
java·源码·springboot
oioihoii6 分钟前
C++共享内存小白入门指南
java·c++·算法
用户99045017780099 分钟前
ruoyi-vue2集成flowable6.7.2后端篇
后端
@淡 定11 分钟前
线程安全的日期格式化:避免 SimpleDateFormat 并发问题
java
qq_124987075313 分钟前
基于springboot框架的小型饮料销售管理系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·spring·毕业设计
我命由我1234519 分钟前
Python Flask 开发:在 Flask 中返回字符串时,浏览器将其作为 HTML 解析
服务器·开发语言·后端·python·flask·html·学习方法
IT_陈寒28 分钟前
JavaScript 性能优化:5个被低估的V8引擎技巧让你的代码提速50%
前端·人工智能·后端
CodeAmaz36 分钟前
JVM一次完整GC流程详解
java·jvm·gc流程
想用offer打牌40 分钟前
数据库大事务有什么危害(面试版)
数据库·后端·架构