方法实现原理_Spring Bean Scope的使用方法、实现原理以及自定义Scope

我们在使用XML或注解定义Bean的时候,Spring并不是拿着这些配置信息直接去生成相应的Bean,而是先生成一个对应的BeanDefinition,等到合适的时候再去创建Bean,这种做法是相当明智的。

因为有了BeanDefinition,Spring就可以通过同一个定义中创建任意多个Bean实例了,甚至BeanDefinition还可以继承使用。

通过BeanDefinition我们不仅仅可以控制Bean的依赖和属性,还可以控制Bean的作用域(Scope)。

今天就来仔细分析一下Spring Bean Scope相关的事情。本主要包括的内容:

  1. Bean Scope的类型
  2. 如何使用Bean Scope
  3. Bean Scope实现的原理
  4. 如何实现一个自定义的Scope类型

Bean Scope有哪几种

b9e43b671e80fd446e97707769e22626.png

上面简单的列出了Spring框架目前默认支持的6种Scope类型。除了这6种,Spring还定义了两种类型:

SimpleThreadScope和SimpleTransactionScope,但是这两种Scope默认是不启用的,需要我们手动注册到BeanFactory上去。

Singleton Scope

singleton类型的Scope是我们平时开发过程中使用最多的一种,在我们不指定Bean的Scope类型的时候Spring默认采用的就是singleton类型。下图展示了Spring管理Singleton Scope Bean的基本形式:

fc67dc30440f68926d250b9024bb53b3.png

Prototype Scope

每次从容器中获取Prototype Scope类型的Bean,容器都会为我们重写创建一个新的。基本形式如小图所示:

f132aa49b3ccfd10e4b77ed77e470f39.png

其它几种Scope

其它几种Scope大体可以描述为:处于同一个过程中的共用同一个Bean,新的过程会创建新的Bean实例。我们以request类型为例,可以描述为下图:

bacd83a9ea6ec7e9c6e1535bd596ee49.png

Bean Scope是如何使用的

Bean Scope使用上是非常简单的,我们只需要在定义的时候添加上scope属性即可,如下面代码所示:

e7370f8a046454c328dd04a4f21f514c.png

这小段代码就定义了一个scope类型为prototype的Bean,使用的时候正常注入就能够得到Bean的实例了。

大作用域的Bean依赖了小作用域的Bean的时候该如何处理呢?比如:singleton类型的Bean依赖了prototype类型的Bean。

我们知道Bean依赖的属性会在它创建的时候注入进去,一个Bean的生命周期内属性注入只会有一次,这就导致实际注入的属性后续就不会变化了,很多时候这并不是我们想要的。那如何能让singleton bean中注入的prototype每次使用的时候都拿到最新的呢?一般有以下几种处理办法:

  • 使用进行代理。
  • 直接从ApplicationContext中获取,这样每次拿到的肯定都是最新的。
  • 使用lookup-method功能。

由于篇幅所限,这里只给出了几种解决办法,每一种处理办法的代码以及实现原理这里就先不分析了,后续会单独进行详细的分析。

Bean Scope的实现原理

看完了Scope的用法,那么接下来就要看看Spring中是如何实现Scope的。我们进入org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法,就能找到如下的代码:

cda66afffea57800de21e371229872e4.png

从代码中我们可以看到:

  • 对于singleton,会先判断是否已经有实例了,如果有就不会调用创建方法,如果没有就会去创建。
  • 对于prototype,则会直接创建bean。
  • 对于其它方式,会根据scope名称去查找注册的scope,如果找到就调用scope的get方法获取bean,是新建还是不新建,就是scope实现的事情了,Spring容器就不会管的。

自定义Scope是如何实现的

看了上面根据Scope创建Bean的方式,我们知道除了singleton和prototype这两个,其它的scope都是使用的相同的实现原理的:继承Scope接口,然后注册实现的scope类型。

Spring框架中已经实现的Scope的类图:

914a13e4f80708b0ec54dedce9d101bc.png

注册scope:

626381794a835b8d2abb2b8be291ddb4.png

相关阅读:

Autowired注解都会用,那么你知道它实现自动注入的原理吗

Spring Bean初始化回调的各种用法你真的懂吗?快来看看吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值