banner



What Is Included In Spring Clean Up

iv.4 Bean scopes

When yous create a bean definition what you lot are really creating is a recipe for creating actual instances of the course defined by that bean definition. The idea that a bean definition is a recipe is important, because it means that, just like a class, y'all tin potentially have many object instances created from a single recipe.

You lot tin can control not just the various dependencies and configuration values that are to be plugged into an object that is created from a detail bean definition, only as well the scope of the objects created from a item bean definition. This approach is very powerful and gives you the flexibility to choose the scope of the objects you create through configuration instead of having to 'bake in' the telescopic of an object at the Java class level. Beans can exist defined to exist deployed in one of a number of scopes: out of the box, the Leap Framework supports exactly five scopes (of which iii are bachelor merely if y'all are using a spider web-aware ApplicationContext).

The scopes supported out of the box are listed below:

Tabular array 4.4. Edible bean scopes

Scope Clarification

singleton

Scopes a unmarried edible bean definition to a single object instance per Spring IoC container.

image

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 and every HTTP request volition have its own instance of a edible bean created off the back of a single bean definition. Just valid in the context of a web-aware Jump ApplicationContext.

session

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

global session

Scopes a single edible bean definition to the lifecycle of a global HTTP Session. Typically but valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.


iv.4.1 The singleton scope

When a bean is a singleton, only 1 shared instance of the edible bean will exist managed, and all requests for beans with an id or ids matching that bean definition volition effect in that ane specific bean instance beingness returned by the Spring container.

To put information technology another fashion, when you define a bean definition and it is scoped every bit a singleton, so the Jump IoC container will create exactly one instance of the object defined by that bean definition. This single example volition be stored in a cache of such singleton beans, and all subsequent requests and references for that named bean will result in the cached object being returned.

Please be aware that Spring's concept of a singleton bean is quite different from the Singleton design equally defined in the seminal Gang of Iv (GoF) patterns volume. The GoF Singleton difficult codes the scope of an object such that one and merely i instance of a particular form will ever be created per ClassLoader . The scope of the Spring singleton is best described every bit per container and per bean . This ways that if you define one bean for a item course in a unmarried Spring container, then the Spring container will create one and only one case of the form defined by that bean definition. The singleton scope is the default telescopic in Bound . To define a bean equally a singleton in XML, you would write configuration like so:

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

4.four.ii The epitome scope

The non-singleton, paradigm telescopic of edible bean deployment results in the cosmos of a new bean case every time a asking for that specific bean is made (that is, it is injected into another edible bean or it is requested via a programmatic getBean() method call on the container). Every bit a rule of pollex, y'all should use the epitome scope for all beans that are stateful, while the singleton scope should be used for stateless beans.

The following diagram illustrates the Bound prototype scope. Please note that a DAO would not typically exist configured every bit a prototype, since a typical DAO would not hold any conversational state; information technology was just easier for this author to reuse the cadre of the singleton diagram.

To define a bean equally a paradigm in XML, you would write configuration like so:

<> <bean            id="accountService"            class="com.foo.DefaultAccountService"            telescopic="epitome"/>  <> <edible bean            id="accountService"            class="com.foo.DefaultAccountService"            singleton="false"/>

There is 1 quite important thing to exist aware of when deploying a bean in the epitome telescopic, in that the lifecycle of the bean changes slightly. Jump does non manage the consummate lifecycle of a prototype bean: the container instantiates, configures, decorates and otherwise assembles a epitome object, hands it to the client and then has no farther cognition of that image instance. This means that while initialization lifecycle callback methods will be called on all objects regardless of scope, in the case of prototypes, any configured destruction lifecycle callbacks will not exist called. It is the responsibility of the client code to make clean upwardly prototype scoped objects and release any expensive resources that the image edible bean(s) are property onto. (Ane possible way to get the Bound container to release resources used by prototype-scoped beans is through the use of a custom bean post-processor which would hold a reference to the beans that need to exist cleaned up.)

In some respects, you lot can recollect of the Spring containers office when talking about a prototype-scoped bean as somewhat of a replacement for the Java 'new' operator. All lifecycle aspects past that point have to be handled by the client. (The lifecycle of a bean in the Bound container is further described in the section entitled Section 4.five.one, "Lifecycle callbacks".)

4.4.3 Singleton beans with paradigm-bean dependencies

When using singleton-scoped beans that have dependencies on beans that are scoped as prototypes, delight exist aware that dependencies are resolved at instantiation fourth dimension . This ways that if you dependency inject a image-scoped bean into a singleton-scoped bean, a brand new image edible bean volition be instantiated so dependency injected into the singleton edible bean... but that is all . That exact same paradigm example will be the sole instance that is ever supplied to the singleton-scoped bean, which is fine if that is what y'all want.

However, sometimes what you actually want is for the singleton-scoped bean to be able to larn a brand new instance of the prototype-scoped bean again and over again and again at runtime. In that case it is no utilize just dependency injecting a paradigm-scoped edible bean into your singleton edible bean, because as explained above, that only happens in one case when the Spring container is instantiating the singleton edible bean and resolving and injecting its dependencies. If you lot are in the scenario where yous need to get a brand new instance of a (prototype) bean again and again and once again at runtime, you are referred to the section entitled Section 4.three.7, "Method Injection"

[Note] Backwards compatibility annotation: specifying the lifecycle scope in XML

If you are referencing the 'spring-beans.dtd' DTD in a bean definition file(s), and yous are being explicit almost the lifecycle scope of your beans you must utilize the "singleton" attribute to express the lifecycle telescopic (remembering that the singleton lifecycle scope is the default). If y'all are referencing the 'spring-beans-2.0.dtd' DTD or the Bound two.0 XSD schema, and then you will need to use the "scope" attribute (because the "singleton" attribute was removed from the definition of the new DTD and XSD files in favor of the "scope" aspect).

To exist totally clear about this, this ways that if you use the "singleton" attribute in an XML bean definition then you must be referencing the 'spring-beans.dtd' DTD in that file . If y'all are using the "scope" attribute and so y'all must be referencing either the 'spring-beans-2.0.dtd' DTD or the 'spring-beans-2.5.xsd' XSD in that file .

iv.iv.4 The other scopes

The other scopes, namely asking, session, and global session are for utilise only in web-based applications (and can be used irrespective of which particular spider web awarding framework you are using, if indeed whatsoever). In the involvement of keeping related concepts together in one place in the reference documentation, these scopes are described here.

[Note] Annotation

The scopes that are described in the following paragraphs are only available if y'all are using a web-aware Spring ApplicationContext implementation (such as XmlWebApplicationContext). If you try using these next scopes with regular Spring IoC containers such as the XmlBeanFactory or ClassPathXmlApplicationContext, you will get an IllegalStateException complaining well-nigh an unknown bean scope.

4.4.four.1 Initial web configuration

In society to support the scoping of beans at the request, session, and global session levels (web-scoped beans), some small-scale initial configuration is required before yous tin can fix about defining your bean definitions. Please annotation that this extra setup is not required if you only desire to apply the 'standard' scopes (namely singleton and prototype).

Now as things stand, there are a couple of means to consequence this initial setup depending on your item Servlet environs...

If yous are accessing scoped beans within Spring Web MVC, i.e. within a asking that is processed by the Spring DispatcherServlet, or DispatcherPortlet, and then no special setup is necessary: DispatcherServlet and DispatcherPortlet already expose all relevant state.

When using a Servlet 2.four+ web container, with requests processed outside of Spring's DispatcherServlet (e.yard. when using JSF or Struts), yous demand to add together the following javax.servlet.ServletRequestListener to the declarations in your spider web application's 'web.xml' file.

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

If you are using an older web container (Servlet 2.3), you will demand to use the provided javax.servlet.Filter implementation. Find below a snippet of XML configuration that has to be included in the 'web.xml' file of your web awarding if you want to have access to spider web-scoped beans in requests outside of Spring's DispatcherServlet on a Servlet 2.3 container. (The filter mapping depends on the surrounding web application configuration so you will take to change it as appropriate.)

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

That'southward it. DispatcherServlet, RequestContextListener and RequestContextFilter all practise exactly the same thing, namely bind the HTTP request object to the Thread that is servicing that request. This makes beans that are asking- and session-scoped bachelor further downwardly the call concatenation.

4.four.4.two The request scope

Consider the following bean definition:

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

With the above bean definition in place, the Spring container will create a brand new example of the LoginAction bean using the 'loginAction' bean definition for each and every HTTP asking. That is, the 'loginAction' bean will be effectively scoped at the HTTP request level. You can change or dirty the internal state of the instance that is created as much as you want, safe in the knowledge that other requests that are also using instances created off the back of the same 'loginAction' bean definition volition not be seeing these changes in state since they are particular to an individual request. When the request is finished processing, the bean that is scoped to the request will be discarded.

four.four.4.three The session scope

Consider the following bean definition:

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

With the above bean definition in place, the Spring container will create a brand new instance of the UserPreferences bean using the 'userPreferences' bean definition for the lifetime of a single HTTP Session. In other words, the 'userPreferences' bean will be effectively scoped at the HTTP Session level. Just similar asking-scoped beans, y'all can alter the internal state of the example that is created as much as you want, safe in the knowledge that other HTTP Session instances that are also using instances created off the dorsum of the aforementioned 'userPreferences' bean definition will not be seeing these changes in country since 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 will besides be discarded.

4.4.iv.4 The global session telescopic

Consider the following bean definition:

<bean              id="userPreferences"              class="com.foo.UserPreferences"              scope="globalSession"/>

The global session telescopic is similar to the standard HTTP Session telescopic (described immediately to a higher place), and actually only makes sense in the context of portlet-based web applications. The portlet specification defines the notion of a global Session that is shared amongst all of the various portlets that brand upwardly a single portlet web application. Beans divers at the global session telescopic are scoped (or bound) to the lifetime of the global portlet Session.

Please note that if you are writing a standard Servlet-based web application and you lot ascertain one or more beans as having global session scope, the standard HTTP Session scope will be used, and no fault will exist raised.

iv.4.4.5 Scoped beans as dependencies

Being able to define a bean scoped to a HTTP asking or Session (or indeed a custom scope of your own devising) is all very well, but one of the primary value-adds of the Leap IoC container is that it manages non only the instantiation of your objects (beans), but also the wiring up of collaborators (or dependencies). If yous want to inject a (for example) HTTP asking scoped bean into some other edible bean, you volition need to inject an AOP proxy in place of the scoped bean. That is, y'all need to inject a proxy object that exposes the aforementioned public interface as the scoped object, simply that is smart plenty to be able to recollect the real, target object from the relevant scope (for case a HTTP request) and delegate method calls onto the real object.

[Note] Note

You practise not demand to utilise the <aop:scoped-proxy/> in conjunction with beans that are scoped as singletons or prototypes. It is an mistake to try to create a scoped proxy for a singleton bean (and the resulting BeanCreationException will certainly fix you direct in this regard).

Let's look at the configuration that is required to effect this; the configuration is non hugely complex (it takes merely one line), just it is important to sympathise the "why" every bit well as the "how" behind it.

<?xml version="one.0" encoding="UTF-viii"?> <beans              xmlns="http://www.springframework.org/schema/beans"              xmlns:xsi="http://www.w3.org/2001/XMLSchema-example"              xmlns:aop="http://www.springframework.org/schema/aop"              xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/jump-beans-three.0.xsd            http://world wide web.springframework.org/schema/aop             http://world wide web.springframework.org/schema/aop/spring-aop-3.0.xsd">      <>     <bean              id="userPreferences"              class="com.foo.UserPreferences"              scope="session">                      <>           <aop:scoped-proxy/>     </bean>          <>     <edible bean              id="userService"              form="com.foo.SimpleUserService">              <>         <belongings              name="userPreferences"              ref="userPreferences"/>      </bean> </beans>            

To create such a proxy, you need but to insert a child <aop:scoped-proxy/> element into a scoped bean definition (you lot may also need the CGLIB library on your classpath so that the container can effect class-based proxying; yous volition likewise need to exist using Appendix A, XML Schema-based configuration). And then, just why do you demand this <aop:scoped-proxy/> element in the definition of beans scoped at the request, session, globalSession and ' insert your custom scope here ' level? The reason is all-time explained by picking autonomously the post-obit bean definition (please notation that the following 'userPreferences' bean definition as it stands is incomplete ):

<edible bean              id="userPreferences"              class="com.foo.UserPreferences"              scope="session"/>  <bean              id="userManager"              class="com.foo.UserManager">     <property              name="userPreferences"              ref="userPreferences"/> </bean>

From the above configuration it is evident that the singleton bean 'userManager' is being injected with a reference to the HTTP Session-scoped bean 'userPreferences'. The salient signal here is that the 'userManager' bean is a singleton... it will be instantiated exactly once per container, and its dependencies (in this example only one, the 'userPreferences' bean) will also just exist injected (once!). This ways that the 'userManager' will (conceptually) only ever operate on the verbal same 'userPreferences' object, that is the ane that it was originally injected with. This is non what you want when you inject a HTTP Session-scoped bean as a dependency into a collaborating object (typically). Rather, what nosotros exercise want is a single 'userManager' object, and and then, for the lifetime of a HTTP Session, we want to see and employ a 'userPreferences' object that is specific to said HTTP Session.

Rather what you need then is to inject some sort of object that exposes the exact aforementioned public interface as the UserPreferences course (ideally an object that is a UserPreferences case) and that is smart plenty to exist able to go off and fetch the real UserPreferences object from whatsoever underlying scoping mechanism we have called (HTTP request, Session, etc.). Nosotros tin then safely inject this proxy object into the 'userManager' bean, which will be blissfully unaware that the UserPreferences reference that information technology is belongings onto is a proxy. In the instance of this instance, when a UserManager instance invokes a method on the dependency-injected UserPreferences object, it is actually invoking a method on the proxy... the proxy will then become off and fetch the real UserPreferences object from (in this instance) the HTTP Session, and delegate the method invocation onto the retrieved real UserPreferences object.

That is why yous demand the following, correct and complete, configuration when injecting asking-, session-, and globalSession-scoped beans into collaborating objects:

<bean              id="userPreferences"              class="com.foo.UserPreferences"              scope="session">     <aop:scoped-proxy/> </bean>  <bean              id="userManager"              class="com.foo.UserManager">     <belongings              name="userPreferences"              ref="userPreferences"/> </edible bean>

Choosing the type of proxy created

By default, when the Spring container is creating a proxy for a bean that is marked upwardly with the <aop:scoped-proxy/> element, a CGLIB-based class proxy volition exist created . This means that you need to have the CGLIB library on the classpath of your application.

Note: CGLIB proxies will only intercept public method calls! Do non call non-public methods on such a proxy; they will not exist delegated to the scoped target object.

You can choose to have the Spring container create 'standard' JDK interface-based proxies for such scoped beans by specifying 'false' for the value of the 'proxy-target-class' aspect of the <aop:scoped-proxy/> element. Using JDK interface-based proxies does mean that you don't need any additional libraries on your awarding's classpath to effect such proxying, but information technology does mean that the class of the scoped edible bean must implement at least i interface, and all of the collaborators into which the scoped bean is injected must be referencing the bean via one of its interfaces.

<> <bean                id="userPreferences"                form="com.foo.DefaultUserPreferences"                telescopic="session">     <aop:scoped-proxy                proxy-target-class="simulated"/> </bean>  <edible bean                id="userManager"                class="com.foo.UserManager">     <property                proper noun="userPreferences"                ref="userPreferences"/> </bean>

The section entitled Section viii.6, "Proxying mechanisms" may also be of some interest with regard to agreement the nuances of choosing whether form-based or interface-based proxying is correct for you lot.

4.4.5 Custom scopes

As of Spring two.0, the bean scoping mechanism in Spring is extensible. This ways that you are not express to simply the bean scopes that Spring provides out of the box; you can define your own scopes, or even redefine the existing scopes (although that last one would probably be considered bad practice - please annotation that you cannot override the built-in singleton and prototype scopes).

4.iv.5.1 Creating your own custom scope

Scopes are defined past the org.springframework.beans.factory.config.Scope interface. This is the interface that you will need to implement in social club to integrate your own custom scope(south) into the Spring container, and is described in particular below. You may wish to look at the Scope implementations that are supplied with the Jump Framework itself for an idea of how to go nearly implementing your own. The Telescopic Javadoc explains the chief grade to implement when you lot need your own telescopic in more item also.

The Telescopic interface has four methods dealing with getting objects from the scope, removing them from the scope and allowing them to exist 'destroyed' if needed.

The offset method should return the object from the underlying scope. The session scope implementation for instance will return the session-scoped bean (and if it does not be, return a new instance of the bean, later having bound it to the session for futurity reference).

Object get(String name, ObjectFactory objectFactory)

The second method should remove the object from the underlying telescopic. The session scope implementation for example, removes the session-scoped edible bean from the underlying session. The object should be returned (you are allowed to render null if the object with the specified name wasn't establish)

Object remove(String proper noun)

The 3rd method is used to register callbacks the scope should execute when it is destroyed or when the specified object in the scope is destroyed. Please refer to the Javadoc or a Spring scope implementation for more information on destruction callbacks.

              void              registerDestructionCallback(String proper noun, Runnable destructionCallback)

The last method deals with obtaining the conversation identifier for the underlying scope. This identifier is dissimilar for each scope. For a session for example, this tin be the session identifier.

String getConversationId()

iv.4.5.2 Using a custom scope

After y'all have written and tested one or more custom Scope implementations, you then need to make the Spring container aware of your new telescopic(south). The central method to register a new Telescopic with the Jump container is declared on the ConfigurableBeanFactory interface (implemented by well-nigh of the concrete BeanFactory implementations that ship with Jump); this fundamental method is displayed beneath:

              void              registerScope(String scopeName, Telescopic telescopic);

The first argument to the registerScope(..) method is the unique name associated with a scope; examples of such names in the Spring container itself are 'singleton' and 'prototype'. The second argument to the registerScope(..) method is an actual instance of the custom Telescopic implementation that you wish to annals and use.

Permit's presume that you lot accept written your own custom Scope implementation, and you have registered it like so:

                Scope customScope =              new              ThreadScope(); beanFactory.registerScope("thread", customScope);

You can then create bean definitions that adhere to the scoping rules of your custom Scope like so:

<bean              id="..."              class="..."              scope="thread"/>

If yous accept your own custom Scope implementation(s), you are not merely express to just programmatic registration of the custom telescopic(s). You lot can also exercise the Scope registration declaratively, using the CustomScopeConfigurer class.

The declarative registration of custom Telescopic implementations using the CustomScopeConfigurer class is shown beneath:

<?xml version="1.0" encoding="UTF-8"?> <beans              xmlns="http://www.springframework.org/schema/beans"              xmlns:xsi="http://world wide web.w3.org/2001/XMLSchema-case"              xmlns:aop="http://world wide web.springframework.org/schema/aop"              xsi:schemaLocation="http://world wide web.springframework.org/schema/beans             http://world wide web.springframework.org/schema/beans/spring-beans-iii.0.xsd            http://world wide web.springframework.org/schema/aop             http://www.springframework.org/schema/aop/bound-aop-three.0.xsd">      <bean              course="org.springframework.beans.factory.config.CustomScopeConfigurer">         <belongings              proper noun="scopes">             <map>                 <entry              primal="thread">                     <edible bean              class="com.foo.ThreadScope"/>                 </entry>             </map>         </belongings>     </edible bean>      <bean              id="bar"              form="x.y.Bar"              telescopic="thread">         <property              name="name"              value="Rick"/>         <aop:scoped-proxy/>     </bean>      <bean              id="foo"              class="x.y.Foo">         <property              name="bar"              ref="bar"/>     </bean>  </beans>
[Note] Annotation

Annotation that, when placing a <aop:scoped-proxy/> in a FactoryBean implementation, it is the manufacturing plant bean itself that is scoped, non the object returned from getObject().

Source: https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html

Posted by: carmichaelshad1981.blogspot.com

0 Response to "What Is Included In Spring Clean Up"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel