Bean 的作用域

2018-05-10  本文已影响11人  A文艺钦年

作用域(Scope)

Sping 提供了六种作用域,其中四种必须是 web-aware Spring ApplicationContext,我的理解是 实现了 org.springframework.web.context.WebApplicationContextApplicationContext
Sping bean 强大且灵活的作用域特性避免了用户直接修改类,只需要简单的配置即可

Scope 描述
singleton 所有 bean 默认都是单例的
prototype 原型,从容器中每一次获取都是新的对象
request bean 实例的生命周期即是 request 的生命周期,即一个请求内的bean 实例都是相同的,不过容器必须是web-aware Spring ApplicationContext
session 同理 bean 实例的生命周期即是 session 的生命周期, 一样必须是 web-aware Spring ApplicationContext
webSocket 同理 bean 实例的生命周期即是 WebSocket 的生命周期, 一样必须是 web-aware Spring ApplicationContext
application 同理 bean 实例的生命周期即是 ServletContext 的生命周期, 一样必须是 web-aware Spring ApplicationContext

从 spring 3.0 开始,增加了 thread 的 scope,不过 这个 scope 默认是没有注册到 AppplicationContext 中。详细见 SimpleThreadScope

当然也可以定制 scope, 详细见 Using a custom scope

单例作用域(The singleton scope)

所有的请求 和所有的引用都使用的是同一实例的bean

image.png

值得一提的是,Sping bean 的单例 和 四人帮的单例不一样,四人帮的单例指的是 实例创建于每一次类加载,而Spring 的 bean 单例 可以描述为:一个容器 一个 bean 实例。

下面两种方式都是定义单例的 bean

<bean id="accountService" class="com.foo.DefaultAccountService"/>

<!-- the following is equivalent, though redundant (singleton scope is the default) -->
<bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/>

原型作用域(The prototype scope)

原型作用域上面也介绍过了,每一次 调用 getBean() 方法返回的都是新的实例
那么何时使用原型,何时使用单例呢?原则:有状态的 bean 使用原型,无状态的 bean 使用单例。

有一点要说明的是,DAO 一般情况下不实用原型作用域,因为 DAO 都是无状态的,这里作者为了画图方便所以使用了原型。


image.png

定义一个原型作用域的 bean

<bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/>

虽然 bean 初始化的生命周期回调与作用域无关,
但是原型作用域与其他作用域在销毁生命周期回调有很大的不同,因为原型作用域与的销毁生命周期回调是不会被执行的。
如果你的 bean 持有的资源比较大的话,是必须要释放的,当然spring 这点也考虑上了,Spring提供了一个 bean post-processor 可以帮你很轻易的做到这点。

bean 生命周期的管理还是交给客户端处理了,这是一句废话了。。。

单例bean和原型bean的依赖

一个单例的 bean 依赖了原型的bean的话,原型 bean 只有一个实例
如果一定要返回不同的实例,可以通过 Method injection 解决,这里就不展开了

上一篇下一篇

猜你喜欢

热点阅读