.Bean的作用域外文翻译资料

 2022-08-14 14:27:35

1.5. Bean Scopes

When you create a bean definition, you create a recipe for creating actual instances of the class defined by that bean definition. The idea that a bean definition is a recipe is important, because it means that, as with a class, you can create many object instances from a single recipe.

You can control not only the various dependencies and configuration values that are to be plugged into an object that is created from a particular bean definition but also control the scope of the objects created from a particular bean definition. This approach is powerful and flexible, because you can choose the scope of the objects you create through configuration instead of having to bake in the scope of an object at the Java class level. Beans can be defined to be deployed in one of a number of scopes. The Spring Framework supports six scopes, four of which are available only if you use a web-aware ApplicationContext. You can also create a custom scope.

The following table describes the supported scopes:

Table 3. Bean scopes

Scope

Description

singleton

(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.

prototype

Scopes a single bean definition to any number of object instances.

request

Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.

session

Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.

application

Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.

websocket

Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

1.5.1. The Singleton Scope

Only one shared instance of a singleton bean is managed, and all requests for beans with an ID or IDs that match that bean definition result in that one specific bean instance being returned by the Spring container.

To put it another way, when you define a bean definition and it is scoped as a singleton, the Spring IoC container creates exactly one instance of the object defined by that bean definition. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object.

Springrsquo;s concept of a singleton bean differs from the singleton pattern as defined in the Gang of Four (GoF) patterns book. The GoF singleton hard-codes the scope of an object such that one and only one instance of a particular class is created per ClassLoader. The scope of the Spring singleton is best described as being per-container and per-bean. This means that, if you define one bean for a particular class in a single Spring container, the Spring container creates one and only one instance of the class defined by that bean definition. The singleton scope is the default scope in Spring. To define a bean as a singleton in XML, you can define a bean as shown in the following example:

lt;bean id='accountService' class='com.something.DefaultAccountService'/gt;

lt;!-- the following is equivalent, though redundant (singleton scope is the default) --gt;

lt;bean id='accountService' class='com.something.DefaultAccountService' scope='singleton'/gt;

1.5.2. The Prototype Scope

The non-singleton prototype scope of bean deployment results in the creation of a new bean instance every time a request for that specific bean is made. That is, the bean is injected into another bean or you request it through a getBean() method call on the container. As a rule, you should use the prototype scope for all stateful beans and the singleton scope for stateless beans.

The following example defines a bean as a prototype in XML:

lt;bean id='accountService' class='com.something.DefaultAccountService' scope='prototype'/gt;

In contrast to the other scopes, Spring does not manage the complete lifecycle of a prototype bean. The container instantiates, configures, and otherwise assembles a prototype object and hands it to the client, with no further record of that prototype instance. Thus, although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped objects and release expensive resources that the prototype beans hold. To get the Spring container to release resources held by prototype-scoped beans, try using a custom bean post-processor, which holds a reference to beans that need to be cleaned up.

In some respects, the Spring containerrsquo;s role in regard to a prototype-scoped bean is a replacement for the Java new operator. All lifecycle management past that point must be handled by the client. (For details on the lifecycle of a bean in the Spring container, see Lifecycle Callbacks.)

1.5.3. Singleton Beans with Prototype-bean Dependencies

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.

However, suppose

剩余内容已隐藏,支付完成后下载完整资料


1.5.Bean的作用域

当你创建一个bean的定义时,你其实是创建一个配方,该配方是通过该bean定义的类的实例创建的。把bean的定义看成是一个配方的想法很重要,因为这意味着就像一个类一样,你可以从一个单独的配方创建许多的对象实例。

你不仅可以控制被注入到由特定的bean定义的对象的各种各样的依赖和配置值,还可以控制由特定bean定义的对象的作用域。这样的方法既有用又简洁灵活,因为你可以通过配置信息选择对象的作用域,而不必一定在Java的类层面上定义作用域。Beans可以定义部署在许多作用域的其中一个。Spring Framework可以支持6种作用域,其中的4种只能通过使用网络感知的应用上下文而获得。你也可以创建一个自定义的作用域。

以下表格描述了支持的作用域:

表格3.Bean的作用域

作用域

描述

singleton

(默认)一个bean对应Spring IoC容器中的一个实例对象。

prototype

一个bean对应多个实例对象。

request

一个bean对应一次HTTP请求中的实例对象。也就是说,每次HTTP请求都各自拥有自己的实例对象。只有在Spring ApplicationContext下才有效。

session

一个bean对应一个HTTP回话的实例对象。只有在Spring ApplicationContext下才有效。

application

一个bean对应一个ServletContext的实例对象。只有在Spring ApplicationContext下才有效。

websocket

一个bean对应一个WebSocket的实例对象。只有在Spring ApplicationContext下才有效。

1.5.1.Singleton的作用域

如果一个共享的实例bean被定义了,并且所有对beans的请求,请求的ID编号和特定的bean实例相同,则将会由Spring容器返回同一个bean实例。

换句话说,就是当你定义bean作用域是singleton时,Spring IoC容器只会创建一个该bean的实例对象。这个单例会存储在单例缓存中,并且指向该bean的随后所有的请求和引用都会返回缓存中的对象。

Spring层面的singleton bean概念和四人帮(GoF)模式一书中的不同。GoF对对象的作用域进行硬编码,以便有且只有一个特定的类被一个ClassLoader创建。Spring中的singleton最好的描述是一个容器对应一个bean。也就是说,如果你在单独的Spring容器中为一个特定的类定义一个bean,Spring容器会创建一个且仅一个由该bean对应的类实例。在Spring中Singleton是默认的作用域。如果你想在XML中定义Singleton,你可以像以下的例子一样:

lt;bean id='accountService' class='com.something.DefaultAccountService'/gt;

lt;!-- the following is equivalent, though redundant (singleton scope is the default) --gt;

lt;bean id='accountService' class='com.something.DefaultAccountService' scope='singleton'/gt;

1.5.2.Prototype的作用域

非单例的Prototype bean作用域会在每次请求创建该bean时创建一个新的bean。也就是说,那个bean已经被注入另外的bean或者你通过容器的getBean()方法请求bean。作为规则,你应该对有状态的beans使用prototype,对无状态的beans使用singleton。

在XML中可以像如下方法配置prototype :

lt;bean id='accountService' class='com.something.DefaultAccountService' scope='prototype'/gt;

和其他作用域不同,Spring不负责管理prototype bean的整个生命周期。容器的初始化,配置,创建prototype的对象然后将它交给客户端,以后再也不会有prototype的对象的记录。因此,虽然不管在何种作用域下都会调用初始化生命周期回调方法,但是对于prototype来说,配置好的析构生命周期回调方法不会被调用。客户端代码必须清除prototype作用域的对象并且释放bean拥有的昂贵的资源。为了使Spring容器释放prototype bean持有的资源,尝试使用bean后处理器,该处理器拥有需要被清除的beans引用。

在某些方面,Spring容器的角色可以看作Java new操作的替代者。所有超过该时间点的生命周期管理都由客户端处理。

1.5.3.Singleton Beans和Prototype-bean的依赖

当你使用依赖prototype beans的singleton-scoped beans时,请注意依赖在bean初始化时已经被解决。因此,如果你把一个prototype-scoped bean依赖注入一个singleton-scoped bean时,一个新的prototype bean被初始化了,然后依赖注入singleton 的bean。

然而,假设你想在程序运行期间让singleton-scoped bean不断获得一个新的 prototype-scoped bean实例,你不能将prototype-scoped bean依赖注入你的singleton bean中,因为当Spring容器初始化singleton bean并且解决了依赖注入后注入只发生一次。如果你需要在程序运行期间生成不止一个的prototype bean时,参考方法注入。

1.5.4.Request,Session,Application,和WebSocket的作用域

Request,Session,Application,和WebSocket的作用域只能通过网络感知的Spring ApplicationContext 实现(例如XmlWebApplicationContext)。如果你在常规的Spring IoC容器,例如ClassPathXmlApplicationContext里使用,一个包含未知bean作用域信息的IllegalStateException异常将会抛出。

初始化web配置

为了request,session,application,和websocket水平上(网络作用域的beans)的作用域能够使用,你需要在定义beans之前做少量初始化配置的工作、(标准作用域singleton和prototype并不需要初始化配置。)

怎样完成这一初始化配置工作需要根据你的特定servlet环境进行。

如果你实际是用Spring Web MVC访问定义了作用域的beans,即Spring DispatcherServlet完成请求,没有另外的配置是需要的。DispatcherServlet早就已经暴露了所有的相关状态。

如果你使用Springrsquo;s DispatcherServlet以外的Servlet 2.5 web容器请求时(例如使用JSF或者Struts),你需要添加注册信息org.springframework.web.context.request.RequestContextListener ServletRequestListener。对于Servlet 3.0 ,这样可以使用WebApplicationInitializer以编程方式完成。或者,对于更加古老的容器,在web.xml文件下添加以下声明:

lt;web-appgt;

...

lt;listenergt;

lt;listener-classgt;

org.springframework.web.context.request.RequestContextListener

lt;/listener-classgt;

lt;/listenergt;

lt;/web-appgt;

或者,如果有问题存在你的listener配置,你可以考虑使用Springrsquo;s RequestContextFilter。过滤映射取决于周围的web应用配置,所以你需要适当地改变它。以下列表展示了web应用的filter部分:

lt;web-appgt;

...

lt;filtergt;

lt;filter-namegt;requestContextFilterlt;/filter-namegt;

lt;filter-classgt;org.springframework.web.filter.RequestContextFilterlt;/filter-classgt;

lt;/filtergt;

lt;filter-mappinggt;

lt;filter-namegt;requestContextFilterlt;/filter-namegt;

lt;url-patterngt;/*lt;/url-patterngt;

lt;/filter-mappinggt;

...

lt;/web-appgt;

DispatcherServlet,RequestContextListener,和RequestContextFilter其实全部都是在做同样的工作,将HTTP请求对象绑定到服务该请求的Thread。这使得具有request和session作用域的beans可以在以后的链接中可获得。

Request作用域

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

lt;bean id='loginAction' class='com.something.LoginAction' scope='request'/gt;

Spring容器通过使用针对当前HTTP请求的loginAction bean定义创建一个新的LoginAction bean实例。也就是,loginAction bean在HTTP请求的层面上被确定作用域。你可以根据你的需要改变已经创建的实例的内部状态,因为其他由相同loginAction bean定义的实例看不见这些改变的状态。对于某个请求这些实例也是特定的。当请求完成处理时,请求作用域下的bean也会被销毁。

当使用注解驱动组件或者Java配置时,@RequestScope注解可以被用来声明请求作用域的组件。以下例子示范如何使用:

@RequestScope

@Component

public class LoginAction {

// ...

}

Session作用域

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

lt;bean id='userPreferences' class='com.something.UserPreferences' scope='session'/gt;

Spring容器通过使用针对当前单独HTTP会话生命周期的userPreferences bean定义创建一个新的UserPreferences bean实例。换句话说,userPreferences bean在HTTP会话的层面上被有效地确定作用域。正如request-scoped beans一样,你可以根据你的需要改变已经创建的实例的内部状态,于此同时,其他由相同userPreferences bean定义的实例看不见这些改变的状态,因为对于某个HTTP会话这些实例也是特定的。当HTTP会话完成处理时,会话作用域下的bean也会被销毁。

当使用注解驱动组件或者Java配置时,@SessionScope注解可以被用来声明会话作用域的组件。

@SessionScope

@Component

public class UserPreferences {

// ...

}

应用作用域

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

lt;bean id='appPreferences' class='com.something.AppPreferences' scope='application'/gt;

Spring容器通过使用在整个web应用只定义一次的appPreferences bean定义创建一个新的AppPreferences bean实例。也就是,appPreferences bean在ServletC

剩余内容已隐藏,支付完成后下载完整资料


资料编号:[235622],资料为PDF文档或Word文档,PDF文档可免费转换为Word

原文和译文剩余内容已隐藏,您需要先支付 30元 才能查看原文和译文全部内容!立即支付

以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。