Spring官方文档 1.5 SpringBean作用域 基于Spring5.2.9

文章由Spring官方文档翻译而来,地址:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans

一 bean的作用域

创建bean definition时,将创建一个配方来创建该bean definition所定义的类的实例。 bean definition是配方的想法很重要,因为它意味着与类一样,您可以从一个配方中创建许多对象实例。

您不仅可以控制从bean definition创建出的对象的各种依赖项和配置,还可以控制从bean definition创建的对象的范围。 这种方法功能强大且灵活,因为您可以通过配置在创建对象时指定作用域,而不必在Java Class定义作用域。
在这里插入图片描述
仅当您使用可感知Web的Spring ApplicationContext实现(例如XmlWebApplicationContext)时,request, session, application, websocket才可用。 如果将这些作用域与常规的Spring IoC容器(例如ClassPathXmlApplicationContext)一起使用,则会抛出一个IllegalStateException异常,该错误抱怨未知的bean作用域。

1.singleton——唯一 bean 实例

当一个 bean 的作用域为 singleton,那么Spring IoC容器中只会存在一个共享的 bean 实例,并且所有对 bean 的请求,只要 id 与该 bean 定义相匹配,则只会返回bean的同一实例。换句话说,当您定义一个bean definition并且其作用域为单例时,Spring IoC容器将为该bean definition所定义的对象创建一个实例。 该实例存储在缓存中,并且对该命名bean的所有后续请求和引用都返回缓存中的对象。
下图显示了单例作用域如何工作
在这里插入图片描述

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

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

2.prototype——每次请求都会创建一个新的 bean 实例

当一个bean的作用域为 prototype,表示一个 bean 定义对应多个对象实例。 prototype 作用域的 bean 会导致在每次对该 bean 请求(将其注入到另一个 bean 中,或者以程序的方式调用容器的 getBean() 方法)时都会创建一个新的 bean 实例。prototype 是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的 bean 应该使用 prototype 作用域,而对无状态的 bean 则应该使用 singleton 作用域。
下图显示了prototype作用域如何工作
在这里插入图片描述
(A data access object (DAO) is not typically configured as a prototype, because a typical DAO does not hold any conversational state. It was easier for us to reuse the core of the singleton diagram.)

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

与其他作用域相反, Spring不能管理Prototype Bean的完整生命周期。容器将实例化,配置或组装原型对象,然后将其交给客户端,而无需对该prototype 实例的进一步记录。 因此,尽管在不考虑作用域的情况下在所有对象上都调用了初始化生命周期回调方法, 对于prototype实例,不调用已配置的销毁生命周期回调。客户端代码必须清除作用域为prototype的对象,并释放prototype Bean拥有的昂贵资源。要使Spring容器释放prototype bean所拥有的资源,请尝试使用自定义bean post-processor,,该处理器包含对待需要清除的bean的引用。

在某种程度,Spring容器在prototype bean方面的角色是Java new运算符的替代。超过Spring容器管理的所有生命周期必须由客户端处理。

3.request——每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效

request只适用于Web程序,每一次 HTTP 请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束。 在 XML 中将 bean 定义成 request ,可以这样配置:

<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>

4.session——每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效
使用以下的XML配置:

<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>

Spring容器通过在单个HTTP会话的生存期内使用userPreferences bean定义来创建UserPreferences bean的新实例。换句话说,userPreferences bean有效地作用在HTTP会话级别。 与使用request作用域bean一样,您可以根据需要更改实例的内部状态,因为其他HTTP会话实例也使用从相同userPreferences bean definition创建的实例,因为它们特定于单个HTTP会话。 当HTTP会话最终被丢弃时,作用于该特定HTTP会话的bean也将被丢弃。

  1. Application Scope
    使用以下的XML配置:
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>

Spring容器通过对整个Web应用程序使用一次appPreferences bean definition来创建AppPreferences bean的新实例。也就是说,appPreferences bean的作用域位于ServletContext级别,并存储为常规ServletContext属性。 这有点类似于Spring单例bean,但有两个重要的区别:它是每个ServletContext的单例,而不是Spring’ApplicationContext’的单例(在任何给定的Web应用程序中可能都有多个),并且它实际上是公开的,因此可见为ServletContext属性。

可以使用@ApplicationScope注释将组件分配给应用程序范围。 以下示例显示了如何执行此操作:

@ApplicationScope
@Component
public class AppPreferences {
    // ...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值