spring-具有原型bean依赖关系的单例bean

Singleton Beans with Prototype-bean Dependencies

具有原型bean依赖关系的单例bean

When you use singleton-scoped beans with dependencies on prototype beans, be aware that dependencies are resolved at instantiation time. Thus, if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-injected into the singleton bean. The prototype instance is the sole instance that is ever supplied to the singleton-scoped bean.

当您使用单例范围的bean时,要注意依赖关系是在实例化时解析的。因此,如果依赖关系将原型范围的bean注入到单例范围的bean中,则会实例化一个新的原型bean,然后将依赖关系注入到单例bean中。原型实例是提供给单例范围bean的唯一实例。

However, suppose you want the singleton-scoped bean to acquire a new instance of the prototype-scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into your singleton bean, because that injection occurs only once, when the Spring container instantiates the singleton bean and resolves and injects its dependencies. If you need a new instance of a prototype bean at runtime more than once, see Method Injection

但是,假设您希望singleton范围的bean在运行时反复获取原型范围bean的新实例。不能将原型范围的bean通过依赖关系注入到singleton bean中,因为这种注入只发生一次,当Spring容器实例化singleton bean并解析和注入它的依赖项时。如果在运行时多次需要原型bean的新实例,请参见方法注入

1.5.4. Request, Session, Application, and WebSocket Scopes

请求、会话、应用程序和WebSocket作用域

The request, session, application, and websocket scopes are available only if you use a web-aware Spring ApplicationContext implementation (such as XmlWebApplicationContext). If you use these scopes with regular Spring IoC containers, such as the ClassPathXmlApplicationContext, an IllegalStateException that complains about an unknown bean scope is thrown.

只有使用支持web的Spring ApplicationContext实现(如XmlWebApplicationContext), request, session, application, and websocket 作用域才可用。如果您将这些作用域与常规springioc容器(例如ClassPathXmlApplicationContext)一起使用,则会抛出一个illeglStasteException,该异常抱怨未知的bean作用域。

Initial Web Configuration

初始Web配置

To support the scoping of beans at the request, session, application, and websocket levels (web-scoped beans), some minor initial configuration is required before you define your beans. (This initial setup is not required for the standard scopes: singleton and prototype.)

为了在request, session, application, and websocket级别(web范围的bean)支持bean的作用域,在定义bean之前,需要一些小的初始配置。(对于标准作用域:singleton和prototype,不需要这种初始设置。)

How you accomplish this initial setup depends on your particular Servlet environment.

如何完成初始设置取决于特定的Servlet环境。

If you access scoped beans within Spring Web MVC, in effect, within a request that is processed by the Spring DispatcherServlet, no special setup is necessary. DispatcherServlet already exposes all relevant state.

如果您在spring web mvc中访问作用域bean,实际上是在spring dispatcherservlet处理的请求中,那么不需要进行特殊设置。DispatcherServlet已公开所有相关状态。

If you use a Servlet 2.5 web container, with requests processed outside of Spring’s DispatcherServlet (for example, when using JSF or Struts), you need to register the org.springframework.web.context.request.RequestContextListener ServletRequestListener. For Servlet 3.0+, this can be done programmatically by using the WebApplicationInitializer interface. Alternatively, or for older containers, add the following declaration to your web application’s web.xml file:

如果您使用Servlet2.5Web容器,并在Spring的DispatcherServlet之外处理请求(例如,在使用JSFStruts时),则需要注册org.springframework.web.context.request.RequestContextListener ServletRequestListener。对于Servlet3.0+,这可以通过使用WebApplicationInitializer接口以编程方式完成。或者,对于较旧的容器,将以下声明添加到web应用程序的web.xml文件文件:

<web-app>
    ...
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    ...
</web-app>

Alternatively, if there are issues with your listener setup, consider using Spring’s RequestContextFilter. The filter mapping depends on the surrounding web application configuration, so you have to change it as appropriate. The following listing shows the filter part of a web application:

或者,如果侦听器设置有问题,可以考虑使用Spring的RequestContextFilter。过滤器映射取决于周围的web应用程序配置,因此您必须根据需要对其进行更改。下表显示了web应用程序的过滤器部分:

<web-app>
    ...
    <filter>
        <filter-name>requestContextFilter</filter-name>
        <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>requestContextFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    ...
</web-app>

DispatcherServlet, RequestContextListener, and RequestContextFilter all do exactly the same thing, namely bind the HTTP request object to the Thread that is servicing that request. This makes beans that are request- and session-scoped available further down the call chain.

DispatcherServletRequestContextListenerRequestContextFilter都执行相同的操作,即将HTTP请求对象绑定到为该请求提供服务的线程。这使得请求和会话作用域的bean在调用链的下一级可用。

Request scope

Consider the following XML configuration for a bean definition:

考虑一下bean定义的以下XML配置:

<bean id="loginAction" class="com.something.LoginAction" scope="request"/>

The Spring container creates a new instance of the LoginAction bean by using the loginAction bean definition for each and every HTTP request. That is, the loginAction bean is scoped at the HTTP request level. You can change the internal state of the instance that is created as much as you want, because other instances created from the same loginAction bean definition do not see these changes in state. They are particular to an individual request. When the request completes processing, the bean that is scoped to the request is discarded.

Spring容器通过为每个HTTP请求使用loginactionbean定义来创建loginactionbean的新实例。也就是说,loginactionbean的作用域是在HTTP请求级别。您可以随意更改创建的实例的内部状态,因为从同一个LoginActionBean定义创建的其他实例在状态中看不到这些更改。它们是针对单个请求的。当请求完成处理时,将丢弃该请求范围内的bean。

When using annotation-driven components or Java configuration, the @RequestScope annotation can be used to assign a component to the request scope. The following example shows how to do so:

当使用注释驱动的组件或Java配置时,@RequestScope注释可用于将组件分配给 request scope。下面的示例演示如何执行此操作:

Java

@RequestScope
@Component
public class LoginAction {
    // ...
}
Session Scope

Consider the following XML configuration for a bean definition:

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

The Spring container creates a new instance of the UserPreferences bean by using the userPreferences bean definition for the lifetime of a single HTTP Session. In other words, the userPreferences bean is effectively scoped at the HTTP Session level. As with request-scoped beans, you can change the internal state of the instance that is created as much as you want, knowing that other HTTP Session instances that are also using instances created from the same userPreferences bean definition do not see these changes in state, because they are particular to an individual HTTP Session. When the HTTP Session is eventually discarded, the bean that is scoped to that particular HTTP Session is also discarded.

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

When using annotation-driven components or Java configuration, you can use the @SessionScope annotation to assign a component to the session scope.

使用注释驱动的组件或Java配置时,可以使用@SessionScope注释将组件分配给session scope。

Java

@SessionScope
@Component
public class UserPreferences {
    // ...
}
Application Scope

Consider the following XML configuration for a bean definition:

<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>

The Spring container creates a new instance of the AppPreferences bean by using the appPreferences bean definition once for the entire web application. That is, the appPreferences bean is scoped at the ServletContext level and stored as a regular ServletContext attribute. This is somewhat similar to a Spring singleton bean but differs in two important ways: It is a singleton per ServletContext, not per Spring 'ApplicationContext' (for which there may be several in any given web application), and it is actually exposed and therefore visible as a ServletContext attribute.

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

When using annotation-driven components or Java configuration, you can use the @ApplicationScope annotation to assign a component to the application scope. The following example shows how to do so:

Java

@ApplicationScope
@Component
public class AppPreferences {
    // ...
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容