From 9696c665178f4c29ae4603465af22b3905edcd1f Mon Sep 17 00:00:00 2001 From: Mark Pollack Date: Wed, 22 Jul 2009 04:53:58 +0000 Subject: [PATCH] Finished applying Beverly's edits --- spring-framework-reference/src/beans.xml | 3735 +++++++++++----------- 1 file changed, 1832 insertions(+), 1903 deletions(-) diff --git a/spring-framework-reference/src/beans.xml b/spring-framework-reference/src/beans.xml index 81b15d5d213..692d36b8c0c 100644 --- a/spring-framework-reference/src/beans.xml +++ b/spring-framework-reference/src/beans.xml @@ -11,15 +11,28 @@ Inversion of Control (IoC) See the section entitled - principle. + principle. IoC is also known as dependency + injection (DI). It is a process whereby objects define their + dependencies, that is, the other objects they work with, only through + constructor arguments, arguments to a factory method, or properties that + are set on the object instance after it is constructed or returned from a + factory method. The container then injects those + dependencies when it creates the bean. This process is fundamentally the + inverse, hence the name Inversion of Control (IoC), + of the bean itself controlling the instantiation or location of its + dependencies by using direct construction of classes, or a mechanism such + as the Service Locator pattern. + + The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework's IoC container. The BeanFactory + url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/BeanFactory.html">BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext + url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/ApplicationContext.html">ApplicationContext is a sub-interface of BeanFactory. It adds easier integration with Spring's AOP features; message resource handling (for use in internationalization), event publication; and @@ -43,7 +56,7 @@ are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. - Beans, and the dependencies between them, are + Beans, and the dependencies among them, are reflected in the configuration metadata used by a container. @@ -68,10 +81,11 @@ url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/support/ClassPathXmlApplicationContext.html">ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. - While XML has been the traditional format for defining configuration - metadata you instruct the container to use Java annotations or code as the + + While XML has been the traditional format for defining configuration + metadata you can instruct the container to use Java annotations or code as the metadata format by providng a small amount of XML configuration to - declaratively enable support for using these additional metadata + declaratively enable support for these additional metadata formats. In most application scenarios, explicit user code is not required to @@ -145,6 +159,7 @@ Spring configuration consists of at least one and typically more + than one bean definition that the container must manage. XML-based configuration metadata shows these beans configured as <bean/> elements inside a top-level <beans/> element. @@ -160,7 +175,7 @@ load domain objects. However, you can use Spring's integration with AspectJ to configure objects that have been created outside the control of an IoC container. See Using - AspectJ to dependency inject domain objects with Spring. + AspectJ to dependency-inject domain objects with Spring. The following example shows the basic structure of XML-based configuration metadata: @@ -210,8 +225,8 @@ know more about Spring's Resource abstraction, as described in , which provides a convenient mechanism for reading an InputSream from - locations defined in a URI syntax. In particular, the use of - Resource paths to construct applications + locations defined in a URI syntax. In particular, + Resource paths are used to construct applications contexts as described in . @@ -239,7 +254,7 @@ The following example shows the data access objects - (daos.xml) configuration file: + daos.xml) file: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -328,10 +343,8 @@ "classpath:/config/services.xml". However, be aware that you are coupling your application's configuration to specific absolute locations. It is generally preferable to keep an indirection for - such absolute locations, for example, through property - placeholders, "${...}", that are resolved against externally - defined properties at runtime. + such absolute locations, for example, through "${...}" placeholders + that are resolved against JVM system properties at runtime. @@ -408,8 +421,7 @@ List userList service.getUsernameList(); This metadata translates to a set of properties that make up each - bean definition. The following table lists some of - these properties, with links to documentation + bean definition. The bean definition @@ -514,10 +526,7 @@ List userList service.getUsernameList(); registerSingleton(..) and registerBeanDefinition(..). However, typical applications work solely with beans defined through metadata bean - definitions. For more information on the relationship between a - BeanFactory and the - ApplicationContext see . + definitions.
Naming beans @@ -541,7 +550,7 @@ List userList service.getUsernameList(); (,), semicolon (;), or white space. - You are not required to specify a name or id for a bean. If no + You are not required to supply a name or id for a bean. If no name or id is supplied explicitly, the container generates a unique name for that bean. However, if you want to refer to that bean by name, through the use of the ref element or In this case, a bean in the same container which is named fromName, may also after the use of this alias definition, be referred to as toName. - + For example, the configuration metadata for subsystem A may refer to a DataSource via the name 'subsystemA-dataSource. The configuration metadata for subsystem B may refer to a DataSource via @@ -677,9 +686,8 @@ List userList service.getUsernameList(); classes are usable by and compatible with Spring. That is, the class being developed does not need to implement any specific interfaces or to be coded in a specific fashion. Simply specifying the bean class should - suffice. However, depending on what type of IoC you are going to use - for that specific bean, you may need a default (empty) - constructor. + suffice. However, depending on what type of IoC you use for that + specific bean, you may need a default (empty) constructor. The Spring IoC container can manage virtually any class you want it to manage; it is not @@ -795,7 +803,7 @@ List userList service.getUsernameList();
Dependency injection - + Dependency injection (DI) is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a @@ -804,7 +812,7 @@ List userList service.getUsernameList(); injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself - controlling the instantiating or location of its dependencies on its own + controlling the instantiation or location of its dependencies on its own by using direct construction of classes, or the Service Locator pattern. @@ -883,7 +891,7 @@ public class Foo { </bean> <bean id="bar" class="x.y.Bar"/> - <bean id="baz class="x.y.Baz"/> + <bean id="baz" class="x.y.Baz"/> </beans> @@ -974,6 +982,19 @@ public class ExampleBean { // business logic that actually 'uses' the injected MovieFinder is omitted... } + + The ApplicationContext supports + constructor- and setter-based DI for the beans it manages. It also + supports setter-based DI after some dependencies are already injected + through the constructor approach. You configure the dependencies in + the form of a BeanDefinition, which you + use with PropertyEditor instances to + convert properties from one format to another. However, most Spring + users do not work with these classes directly (programmatically), but + rather with an XML definition file that is then converted internally + into instances of these classes, and used to load an entire Spring IoC + container instance. + Constructor-based or setter-based DI? @@ -1010,7 +1031,7 @@ public class ExampleBean { The container performs bean dependency resolution as follows: - + The ApplicationContext is @@ -1325,7 +1346,7 @@ public class ExampleBean { The idref element is simply an error-proof way to pass the id (string value - not a - reference)of another bean in the container to a + reference) of another bean in the container to a <constructor-arg/> or <property/> element. @@ -1383,11 +1404,11 @@ public class ExampleBean {
References to other beans (collaborators) - The ref element is the final element allowed + The ref element is the final element inside a <constructor-arg/> or <property/> definition element. Here you - set the value of the specified property of a bean to to be a reference to another - bean (a collaborator) managed by the container. The referenced bean is + set the value of the specified property of a bean to be a reference to another + bean (a collaborator) managed by the container. The referenced bean is a dependency of the bean whose property will be set, and it is initialized on demand as needed before the property is set. (If the collaborator is a singleton bean, it may be initialized already by the container.) All @@ -2132,7 +2153,7 @@ support=support@example.co.uk
Checking for dependencies - + The Spring IoC container can check for unresolved dependencies of a bean deployed into the container. When enabling checking for unresolved dependencies all JavaBean properties of the bean must have explicit values set for them in the bean @@ -2221,14 +2242,12 @@ support=support@example.co.uk A solution is to forego some inversion of control. You can make bean A aware of the container by implementing the - ApplicationContextFactoryAware interface, + ApplicationContextAware interface, and by making a getBean("B") call to the container ask for (a typically new) bean B instance every - time bean A needs it. The following is a contrived example of this - approach: - - - + time bean A needs it. The following is an example of this + approach: + // a class that uses a stateful Command-style class to perform some processing package fiona.apple; @@ -2446,26 +2465,27 @@ public class ReplacementComputeValue implements MethodReplacer {
Bean scopes - When you create a bean definition what you are actually creating is - a recipe for creating actual instances of the class + 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, just like a class, you can - potentially have many object instances created from a single - recipe. + 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 the scope of - the objects created from a particular 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 scope of an object at the Java class level. Beans - can be defined to be deployed in one of a number of scopes: out of the - box, the Spring Framework supports exactly five scopes (of which three are - available only if you are using a web-aware - ApplicationContext). + the objects created from a particular bean definition. This approach + powerful and flexible in that 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: out of the box, the + Spring Framework supports five scopes, three of which are available only + if you use a web-aware + ApplicationContext. - The scopes supported out of the box are listed below: + The following scopes are supported out of the box. You can also + create a custom + scope.
Bean scopes @@ -2504,8 +2524,8 @@ public class ReplacementComputeValue implements MethodReplacer { Scopes a single bean definition to the lifecycle of a - single HTTP request; that is each and every HTTP request will have - its own instance of a bean created off the back of a single bean + 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. @@ -2539,19 +2559,18 @@ public class ReplacementComputeValue implements MethodReplacer {
The singleton scope - When a bean is a singleton, only one shared - instance of the bean will be managed, and all requests for beans with an - id or ids matching that bean definition will result - in that one specific bean instance being returned by the Spring - container. + Only one shared instance of a singleton bean + is managed, and all requests for beans with an id or ids matching 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, then the Spring IoC container will create + scoped as a singleton, the Spring IoC container creates exactly one instance of the object defined by that - bean definition. This single instance will be stored in a cache of such + bean definition. This single instance is 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. + references for that named bean return the cached + object. @@ -2565,19 +2584,18 @@ public class ReplacementComputeValue implements MethodReplacer { - Please be aware that Spring's concept of a singleton bean is quite - different from the Singleton pattern as defined in the seminal 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 will ever be created per - ClassLoader. The scope of the Spring - singleton is best described as per container and per + Spring'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 per container and per bean. This means that if you define one bean for a particular - class in a single Spring container, then the Spring container will - create 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 would write configuration like so: + class in a single Spring container, then 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 would + write, for example: <bean id="accountService" class="com.foo.DefaultAccountService"/> @@ -2593,18 +2611,17 @@ public class ReplacementComputeValue implements MethodReplacer { 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, it is injected into - another bean or it is requested via a programmatic - getBean() method call on the container). As a rule of - thumb, you should use the prototype scope for all beans that are - stateful, while the singleton scope should be used for stateless - beans. + 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, + use the prototype scope for all stateful beans and the singleton scope + for stateless beans. The following diagram illustrates the Spring prototype scope. - Please note that a DAO would not typically be configured as a - prototype, since a typical DAO would not hold any conversational state; + A data access object (DAO) is not typically configured as a + prototype, because a typical DAO does not hold any conversational state; it was just easier for this author to reuse the core of the singleton - diagram. + diagram. @@ -2618,8 +2635,7 @@ public class ReplacementComputeValue implements MethodReplacer { - To define a bean as a prototype in XML, you would write - configuration like so: + The following example defines a bean as a prototype in XML: <!-- using spring-beans-2.0.dtd --> <bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/> @@ -2627,124 +2643,102 @@ public class ReplacementComputeValue implements MethodReplacer { <!-- the following is equivalent and preserved for backward compatibility in spring-beans.dtd --> <bean id="accountService" class="com.foo.DefaultAccountService" singleton="false"/> - There is one quite important thing to be aware of when deploying a - bean in the prototype scope, in that the lifecycle of the bean changes - slightly. Spring does not manage the complete lifecycle of a prototype - bean: the container instantiates, configures, decorates and otherwise - assembles a prototype object, hands it to the client and then has no - further knowledge of that prototype instance. This means that while - initialization lifecycle callback methods will be + 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, - any configured destruction lifecycle callbacks will - not be called. It is the responsibility of the - client code to clean up prototype scoped objects and release any - expensive resources that the prototype bean(s) are holding onto. (One - possible way to get the Spring 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 be cleaned up.) + configured destruction lifecycle callbacks are + not called. The client code must clean up + prototype-scoped objects and release expensive resources that the + prototype bean(s) are holding. 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, you can think of the Spring containers role 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 Spring container is further described in the section entitled In some respects, the Spring container'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 .)
Singleton beans with prototype-bean dependencies - When using singleton-scoped beans that have dependencies on beans - that are scoped as prototypes, please be aware that - dependencies are resolved at instantiation time. - This means that if you dependency inject a prototype-scoped bean into a - singleton-scoped bean, a brand new prototype bean will be instantiated - and then dependency injected into the singleton bean... but - that is all. That exact same prototype instance will be the - sole instance that is ever supplied to the singleton-scoped bean, which - is fine if that is what you want. + 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, sometimes what you actually want is for the - singleton-scoped bean to be able to acquire a brand new instance of the - prototype-scoped bean again and again and again at runtime. In that case - it is no use just dependency injecting a prototype-scoped bean into your - singleton bean, because as explained above, that only happens - once when the Spring container is instantiating the - singleton bean and resolving and injecting its dependencies. If you are - in the scenario where you need to get a brand new instance of a - (prototype) bean again and again and again at runtime, you are referred - to the section entitled 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 is instantiating the singleton bean and resolving + and injecting its dependencies. If you need a new instance of a + prototype bean at runtime more than once, see - Backwards compatibility note: specifying the lifecycle scope in + <title>Backwards compatibility and specifying the lifecycle scope in XML - If you are referencing the - 'spring-beans.dtd' DTD in a bean definition - file(s), and you are being explicit about the lifecycle scope of your - beans you must use the "singleton" attribute to - express the lifecycle scope (remembering that the If you reference the spring-beans.dtd DTD + in a bean definition file, and you are explicit about the lifecycle + scope of your beans, you must use the singleton + attribute to express the lifecycle scope. The singleton lifecycle - scope is the default). If you are referencing the - 'spring-beans-2.0.dtd' DTD or the Spring 2.0 XSD - schema, 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" attribute). + scope is the default. If you reference the + spring-beans-2.0.dtd DTD or the Spring 2.0 XSD + schema, you must 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 attribute. - To be totally clear about this, this means 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 you are using the "scope" - attribute then you must be referencing either the - 'spring-beans-2.0.dtd' DTD or the - 'spring-beans-3.0.xsd' XSD in that + This means that if you use the singleton + attribute in an XML bean definition, you must + reference the spring-beans.dtd DTD in + that file. If you use the scope + attribute, you must reference either the + spring-beans-2.0.dtd DTD or the + spring-beans-3.0.xsd XSD in that file.
- The other scopes + Request, session, and global session scopes - The other scopes, namely request, - session, and global session are - for use only in web-based applications (and can be used irrespective of - which particular web application framework you are using, if indeed - any). In the interest of keeping related concepts together in one place - in the reference documentation, these scopes are described here. - - - The scopes that are described in the following paragraphs are - only available if you 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 - ClassPathXmlApplicationContext, you - will get an - IllegalStateException complaining about an - unknown bean scope. - + The request, session, and + global session scopes are only + available 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, you get an + IllegalStateException complaining about an + unknown bean scope.
Initial web configuration - In order to support the scoping of beans at the + To support the scoping of beans at the request, session, and global session levels (web-scoped beans), some - minor initial configuration is required before you can set about - defining your bean definitions. Please note that this extra setup is - not required if you just want to use the - 'standard' scopes (namely singleton and prototype). + minor initial configuration is required before you define your beans. + (This initial setup is not required for the + standard scopes, singleton and prototype.) - Now as things stand, there are a couple of ways to effect this - initial setup depending on your particular Servlet - environment... + How you accomplish this initial setup depends on your particular + Servlet environment.. - If you are accessing scoped beans within Spring Web MVC, i.e. + If you access scoped beans within Spring Web MVC, in effect, within a request that is processed by the Spring DispatcherServlet, or DispatcherPortlet, then no special setup is @@ -2752,12 +2746,12 @@ public class ReplacementComputeValue implements MethodReplacer { DispatcherPortlet already expose all relevant state. - When using a Servlet 2.4+ web container, with requests processed - outside of Spring's DispatcherServlet (e.g. when using JSF or Struts), - you need to add the following + If you use a Servlet 2.4+ web container, with requests processed + outside of Spring's DispatcherServlet (for example, when using JSF or + Struts), you need to add the following javax.servlet.ServletRequestListener to - the declarations in your web application's - 'web.xml' file. + the declarations in your web applications web.xml + file: <web-app> ... @@ -2767,15 +2761,14 @@ public class ReplacementComputeValue implements MethodReplacer { ... </web-app> - If you are using an older web container (Servlet 2.3), you will - need 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 application if you - want to have access to 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 and - so you will have to change it as appropriate.) + If you use an older web container (Servlet 2.3), use the + provided javax.servlet.Filter + implementation. The following snippet of XML configuration must be + included in the web.xml file of your web + application if you want to access 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 must change it as appropriate.) <web-app> .. @@ -2790,7 +2783,7 @@ public class ReplacementComputeValue implements MethodReplacer { ... </web-app> - That's it. DispatcherServlet, + DispatcherServlet, RequestContextListener and RequestContextFilter all do exactly the same thing, namely bind the HTTP request object to the @@ -2800,56 +2793,51 @@ public class ReplacementComputeValue implements MethodReplacer {
- The request scope + 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 instance of the - LoginAction bean using the - 'loginAction' bean definition for each and every - HTTP request. 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 will 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. + 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 + will 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.
- The session scope + 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 like request-scoped beans, you can - change the internal state of the instance 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 back of the same - 'userPreferences' bean definition will not be - seeing these changes in state since they are particular to an - individual HTTP Session. When the HTTP + 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 will also be discarded. + Session is also discarded.
- The global session scope + Global session scope Consider the following bean definition: @@ -2857,54 +2845,50 @@ public class ReplacementComputeValue implements MethodReplacer { The global session scope is similar to the standard HTTP Session scope (described immediately - above), and really 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 make up a single - portlet web application. Beans defined at the global - session scope are scoped (or bound) to the lifetime of the - global portlet Session. + linkend="beans-factory-scopes-session">described above), and + applies only in the context of portlet-based web applications. The + portlet specification defines the notion of a global + Session that is shared among all + portlets that make up a single portlet web application. Beans defined + at the global session scope 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 define one or more beans as having global - session scope, the standard HTTP - Session scope will be used, and no - error will be raised. + If you write a standard Servlet-based web application and you + define one or more beans as having global session + scope, the standard HTTP Session scope + is used, and no error is raised.
Scoped beans as dependencies - Being able to define a bean scoped to an HTTP request or - Session (or indeed a custom scope of your - own devising) is all very well, but one of the main value-adds of the - Spring IoC container is that it manages not only the instantiation of + The Spring IoC container manages not only the instantiation of your objects (beans), but also the wiring up of collaborators (or dependencies). If you want to inject (for example) an HTTP request - scoped bean into another bean, you will need to inject an AOP proxy in - place of the scoped bean. That is, you need to inject a proxy object - that exposes the same public interface as the scoped object but that - is smart enough to be able to retrieve the real, target object from - the relevant scope (for example an HTTP request) and delegate method - calls onto the real object. + scoped bean into another bean, you must inject an AOP proxy in place + of the scoped bean. That is, you need to inject a proxy object that + exposes the same public interface as the scoped object but that can + also retrieve the real, target object from the relevant scope (for + example, an HTTP request) and delegate method calls onto the real + object. You do not need to use the <aop:scoped-proxy/> in conjunction with beans that are scoped as singletons or - prototypes. It is an error to try to create a - scoped proxy for a singleton bean (and the resulting - BeanCreationException will certainly - set you straight in this regard). + prototypes. If you try to create a scoped proxy + for a singleton bean, the + BeanCreationException is + raised. - Let's look at the configuration that is required to effect this; - the configuration is not hugely complex (it takes just one line), but + The configuration in the following example is only one line, but it is important to understand the why as well as the how behind it. + + <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" @@ -2925,26 +2909,27 @@ public class ReplacementComputeValue implements MethodReplacer { <!-- a singleton-scoped bean injected with a proxy to the above bean --> <bean id="userService" class="com.foo.SimpleUserService"> - <!-- a reference to the proxied 'userPreferences' bean --> + <!-- a reference to the proxied userPreferences bean --> <property name="userPreferences" ref="userPreferences"/> </bean> </beans> - To create such a proxy, you need only to insert a child + To create such a proxy, you insert a child <aop:scoped-proxy/> element into a scoped - bean definition (you may also need the CGLIB library on your classpath - so that the container can effect class-based proxying; you will also - need to be using ). So, just why do you - need 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 best explained by picking apart the following bean definition - (please note that the following 'userPreferences' - bean definition as it stands is - incomplete): + bean definition. (If + you choose class-based proxying, you also need the CGLIB library in + your classpath. See and .) Why do definitions of beans scoped at the + request, session, + globalSession and custom-scope levels require the + <aop:scoped-proxy/> element ? Let's examine + the following singleton bean definition and contrast it with what you + need to define for the aforementioned scopes. (The following + userPreferences bean definition as it stands is + incomplete.) <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/> @@ -2952,51 +2937,48 @@ public class ReplacementComputeValue implements MethodReplacer { <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 point here is - that the 'userManager' bean is a singleton... it - will be instantiated exactly once per container, - and its dependencies (in this case only one, the - 'userPreferences' bean) will also only be injected - (once!). This means that the 'userManager' will - (conceptually) only ever operate on the exact same - 'userPreferences' object, that is the one that it - was originally injected with. This is not what - you want when you inject an HTTP - Session-scoped bean as a dependency - into a collaborating object (typically). Rather, what we - do want is a single - 'userManager' object, and then, for the lifetime of - an HTTP Session, we want to see and use - 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 same public interface as the + In the preceding example, the singleton bean + userManager is injected with a reference to the + HTTP Session-scoped bean + userPreferences. The salient point here is that the + userManager bean is a singleton: it will be + instantiated exactly once per container, and its + dependencies (in this case only one, the + userPreferences bean) are also injected only once. + This means that the userManager bean will only + operate on the exact same userPreferences object, + that is, the one that it was originally injected with. + + + + This is not the behavior you want when injecting + a shorter-lived scoped bean into a longer-lived scoped bean, for + example injecting an HTTP Session-scoped collaborating + bean as a dependency into singleton bean. Rather, you need a single + userManager object, and for the lifetime of an HTTP + Session, you need a + userPreferences object that is specific to said + HTTP Session. Thus the container creates + an object that exposes the exact same public interface as the UserPreferences class (ideally an object that is a UserPreferences - instance) and that is smart enough to be able to go off and fetch the - real - UserPreferences object from whatever underlying - scoping mechanism we have chosen (HTTP request, - Session, etc.). We can then safely - inject this proxy object into the 'userManager' - bean, which will be blissfully unaware that the - UserPreferences reference that it is holding - onto is a proxy. In the case of this example, when a - UserManager instance invokes a method - on the dependency-injected UserPreferences - object, it is really invoking a method on the proxy... the proxy will - then go off and fetch the real UserPreferences - object from (in this case) the HTTP - Session, and delegate the method + instance) which can fetch the real + UserPreferences object from the scoping + mechanism (HTTP request, Session, + etc.). The container injects this proxy object into the + userManager bean, which is unaware that this + UserPreferences reference is a proxy. In this + example, when a UserManager instance + invokes a method on the dependency-injected + UserPreferences object, it actually is invoking + a method on the proxy. The proxy then fetches the real + UserPreferences object from (in this case) the + HTTP Session, and delegates the method invocation onto the retrieved real UserPreferences object. - That is why you need the following, correct and complete, - configuration when injecting request-, + Thus you need the following, correct and complete, configuration + when injecting request-, session-, and globalSession-scoped beans into collaborating objects: @@ -3010,31 +2992,30 @@ public class ReplacementComputeValue implements MethodReplacer { </bean>
- Choosing the type of proxy created + Choosing the type of proxy to create - By default, when the Spring container is creating a proxy for - a bean that is marked up with the + By default, when the Spring container creates a proxy for a + bean that is marked up with the <aop:scoped-proxy/> element, a - CGLIB-based class proxy will be created. This means that - you need to have the CGLIB library on the classpath of your + CGLIB-based class proxy is created. This means that you + need to have the CGLIB library in the classpath of your application. - Note: CGLIB proxies will only intercept public - method calls! Do not call non-public methods on such a - proxy; they will not be delegated to the scoped target - object. + Note: CGLIB proxies only intercept public method + calls! Do not call non-public methods on such a proxy; + they will not be 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' attribute of the + Alternatively, you can configure the Spring container to + create standard JDK interface-based proxies for such scoped beans, + by specifying false for the value of the + proxy-target-class attribute of the <aop:scoped-proxy/> element. Using JDK - interface-based proxies does mean that you don't need any additional - libraries on your application's classpath to effect such proxying, - but it does mean that the class of the scoped bean must implement at - least one interface, and all of the - collaborators into which the scoped bean is injected must be - referencing the bean via one of its interfaces. + interface-based proxies means that you do not need additional + libraries in your application classpath to effect such proxying. + However, it also means that the class of the scoped bean must + implement at least one interface, and that all + collaborators into which the scoped bean is injected must reference + the bean through one of its interfaces. <!-- DefaultUserPreferences implements the UserPreferences interface --> <bean id="userPreferences" class="com.foo.DefaultUserPreferences" scope="session"> @@ -3045,10 +3026,9 @@ public class ReplacementComputeValue implements MethodReplacer { <property name="userPreferences" ref="userPreferences"/> </bean> - The section entitled may also - be of some interest with regard to understanding the nuances of - choosing whether class-based or interface-based proxying is right - for you. + For more detailed information about choosing class-based or + interface-based proxying, see .
@@ -3056,60 +3036,56 @@ public class ReplacementComputeValue implements MethodReplacer {
Custom scopes - As of Spring 2.0, the bean scoping mechanism in Spring is - extensible. This means that you are not limited to just 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 note that you + As of Spring 2.0, the bean scoping mechanism is extensible. You + can define your own scopes, or even redefine existing scopes, although + the latter is considered bad practice and you cannot override the built-in singleton and prototype - scopes). + scopes.
- Creating your own custom scope + Creating a custom scope - Scopes are defined by the + To integrate your custom scope(s) into the Spring container, you + need to implement the org.springframework.beans.factory.config.Scope - interface. This is the interface that you will need to implement in - order to integrate your own custom scope(s) into the Spring container, - and is described in detail below. You may wish to look at the + interface, which is described in this section. For an idea of how to + implement your own scopes, see the Scope implementations that are supplied - with the Spring Framework itself for an idea of how to go about - implementing your own. The Scope - Javadoc explains the main class to implement when you need - your own scope in more detail too. + with the Spring Framework itself and the Scope + Javadoc, which explains the methods you need to implement in more detail. - The Scope interface has four methods dealing - with getting objects from the scope, removing them from the scope and - allowing them to be 'destroyed' if needed. + The Scope interface has four methods to get + objects from the scope, remove them from the scope, and allow them to + be destroyed. - The first method should return the object from the underlying - scope. The session scope implementation, for example, will return the - session-scoped bean (and if it does not exist, return a new instance - of the bean, after having bound it to the session for future - reference). + The following method returns the object from the underlying + scope. The session scope implementation, for example, returns the + session-scoped bean (and if it does not exist, the method returns a + new instance of the bean, after having bound it to the session for + future reference). Object get(String name, ObjectFactory objectFactory) - The second method should remove the object from the underlying + The following method removes the object from the underlying scope. The session scope implementation for example, removes the session-scoped bean from the underlying session. The object should be - returned (you are allowed to return null if the object with the - specified name wasn't found) + returned, but you can return null if the object with the specified + name is not found. Object remove(String name) - The third method is used to register callbacks the scope should + The following method registers the 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. + is destroyed. Refer to the Javadoc or a Spring scope implementation + for more information on destruction callbacks. void registerDestructionCallback(String name, Runnable destructionCallback) - The last method deals with obtaining the conversation identifier - for the underlying scope. This identifier is different for each scope. - For a session for example, this can be the session identifier. + The following method obtains the conversation identifier for the + underlying scope. This identifier is different for each scope. For a + session scoped implementation, this identifier can be the session identifier. String getConversationId()
@@ -3117,53 +3093,45 @@ public class ReplacementComputeValue implements MethodReplacer {
Using a custom scope - After you have written and tested one or more custom - Scope implementations, you then need to - make the Spring container aware of your new scope(s). The central - method to register a new Scope with the - Spring container is declared on the - ConfigurableBeanFactory interface - (implemented by most of the concrete - BeanFactory implementations that ship - with Spring); this central method is displayed below: + After you write and test one or more custom + Scope implementations, you need to make + the Spring container aware of your new scope(s). The central method to + register a new Scope with the Spring + container. void registerScope(String scopeName, Scope scope); - + This method is declared on the ConfigurableBeanFactory interface, + which is available on most of the concrete ApplicationContext implementations that ship + with Spring via the BeanFactory property. 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 + container itself are singleton and + prototype. The second argument to the registerScope(..) method is an actual instance of the custom Scope implementation that you wish to register and use. - Let's assume that you have written your own custom - Scope implementation, and you have - registered it like so: + Suppose that you write your custom + Scope implementation, and then register + it as follows: // note: the ThreadScope class does not ship with the Spring Framework 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: + You then create bean definitions that adhere to the scoping + rules of your custom Scope: <bean id="..." class="..." scope="thread"/> - If you have your own custom Scope - implementation(s), you are not just limited to only programmatic - registration of the custom scope(s). You can also do the - Scope registration declaratively, using - the CustomScopeConfigurer class. - - The declarative registration of custom - Scope implementations using the - CustomScopeConfigurer class is shown - below: + With a custom Scope + implementation, you are not limited to programmatic registration of + the scope. You can also do the Scope + registration declaratively, using the + CustomScopeConfigurer class: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -3196,7 +3164,7 @@ beanFactory.registerScope("thread", customScope </beans> - Note that, when placing a <aop:scoped-proxy/> in a + When you place <aop:scoped-proxy/> in a FactoryBean implementation, it is the factory bean itself that is scoped, not the object returned from getObject(). @@ -3210,50 +3178,46 @@ beanFactory.registerScope("thread", customScope
Lifecycle callbacks - - The Spring Framework provides several callback interfaces to - change the behavior of your bean in the container; they include - InitializingBean and - DisposableBean. Implementing these - interfaces will result in the container calling - afterPropertiesSet() for the former and - destroy() for the latter to allow the bean to - perform certain actions upon initialization and destruction. + + To interact with the container's management of the bean lifecycle, + you can implement the Spring InitializingBean and + DisposableBean interfaces. The + container calls afterPropertiesSet() for the + former and destroy() for the latter to allow the bean to + perform certain actions upon initialization and destruction of your beans. + You can also achieve the same integration with the container without coupling your + classes to Spring interfaces though the use of init-method and destroy method object definition + metadata. Internally, the Spring Framework uses BeanPostProcessor implementations to process any callback interfaces it can find and call the appropriate methods. If you need custom features or other lifecycle behavior Spring - doesn't offer out-of-the-box, you can implement a - BeanPostProcessor yourself. More - information about this can be found in the section entitled . + does not offer out-of-the-box, you can implement a + BeanPostProcessor yourself. For more + information, see . - All the different lifecycle callback interfaces are described - below. In one of the appendices, you can find diagrams that show how - Spring manages beans, how those lifecycle features change the nature of - your beans, and how they are managed. + The lifecycle callback interfaces are described in this section.
Initialization callbacks - Implementing the + The org.springframework.beans.factory.InitializingBean interface allows a bean to perform initialization work after all necessary properties on the bean have been set by the container. The InitializingBean interface specifies - exactly one method: + a single method: void afterPropertiesSet() throws Exception; - Generally, the use of the - InitializingBean interface can be - avoided and is actually discouraged since it unnecessarily couples the - code to Spring. As an alternative, bean definitions provide support - for a generic initialization method to be specified. In the case of - XML-based configuration metadata, this is done using the - 'init-method' attribute. For example, the following - definition: + It is recommended that you do not use the + InitializingBean interface because it + unnecessarily couples the code to Spring. Alternatively, specify a POJO + initialization method. In the case of XML-based configuration metadata, you use the + init-method attribute to specify the name of the method that has a void no-argument signature. + For example, the following definition: <bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/> @@ -3290,13 +3254,12 @@ beanFactory.registerScope("thread", customScope void destroy() throws Exception; - Generally, the use of the - DisposableBean callback interface can - be avoided and is actually discouraged since it unnecessarily couples - the code to Spring. As an alternative, bean definitions provide - support for a generic destroy method to be specified. When using - XML-based configuration metadata this is done via the - 'destroy-method' attribute on the + It is recommended that you do not use the + DisposableBean callback interface + because it unnecessarily couples the code to Spring. Alternatively, + specify a generic method that is supported by bean definitions. With + XML-based configuration metadata, you use the + destroy-method attribute on the <bean/>. For example, the following definition: @@ -3324,38 +3287,34 @@ beanFactory.registerScope("thread", customScope
- Default initialization & destroy methods + Default initialization and destroy methods - When writing initialization and destroy method callbacks that do - not use the Spring-specific + When you write initialization and destroy method callbacks that + do not use the Spring-specific InitializingBean and - DisposableBean callback interfaces, one - typically finds oneself writing methods with names such as - init(), initialize(), - dispose(), etc. The names of such lifecycle - callback methods are (hopefully!) standardized across a project so - that all developers on a team use the same method names and thus - ensure some level of consistency. + DisposableBean callback interfaces, you + typically write methods with names such as init(), + initialize(), dispose(), and so + on. Ideally, the names of such lifecycle callback methods are + standardized across a project so that all developers use the same + method names and ensure consistency. - The Spring container can be configured to - 'look' for named initialization and destroy - callback method names on every bean. This means - that you, as an application developer, can simply write your - application classes, use a convention of having an initialization - callback called init(), and then (without having to - configure each and every bean with, in the case of XML-based - configuration, an 'init-method="init"' attribute) - be safe in the knowledge that the Spring IoC container - will call that method when the bean is being - created (and in accordance with the standard lifecycle callback - contract described previously). + You can configure the Spring container to + look for named initialization and destroy callback + method names on every bean. This means that you, + as an application developer, can write your application classes and + use an initialization callback called init(), + without having to configure an init-method="init" + attribute with each bean definition. The Spring IoC container calls that method + when the bean is created (and in accordance with the standard + lifecycle callback contract described previously). This feature also + enforces a consistent naming convention for initialization and destroy + method callbacks. - Let's look at an example to make the use of this feature - completely clear. For the sake of the example, let us say that one of - the coding conventions on a project is that all initialization - callback methods are to be named init() and that - destroy callback methods are to be called - destroy(). This leads to classes like so... + Suppose that your initialization callback methods are named + init() and destroy callback methods are named + destroy(). Your class will resemble the class in + the following example. public class DefaultBlogService implements BlogService { @@ -3381,52 +3340,42 @@ beanFactory.registerScope("thread", customScope </beans> - Notice the use of the 'default-init-method' - attribute on the top-level <beans/> element. - The presence of this attribute means that the Spring IoC container - will recognize a method called 'init' on beans as - being the initialization method callback, and when a bean is being - created and assembled, if the bean's class has such a method, it will - be invoked at the appropriate time. + The presence of the default-init-method + attribute on the top-level <beans/> element + attribute causes the Spring IoC container to recognize a method called + init on beans as the initialization method + callback. When a bean is created and assembled, if the beans class has + such a method, it is invoked at the appropriate time. - Destroy method callbacks are configured similarly (in XML that - is) using the 'default-destroy-method' attribute on - the top-level <beans/> element. + You configure destroy method callbacks similarly (in XML, that + is) by using the default-destroy-method attribute + on the top-level <beans/> element. - The use of this feature can save you the (small) housekeeping - chore of specifying an initialization and destroy method callback on - each and every bean, and it is great for enforcing a consistent naming - convention for initialization and destroy method callbacks, as - consistency is something that should always be aimed for. + Where existing bean classes already have callback methods that + are named at variance with the convention, you can override the + default by specifying (in XML, that is) the method name using the + init-method and destroy-method attributes on the <bean/> itself. + - Consider the case where you have some existing beans where the - underlying classes already have initialization callback methods that - are named at variance with the convention. You can - always override the default by specifying (in XML - that is) the method name using the 'init-method' - and 'destroy-method' attributes on the - <bean/> element itself. - - Finally, please be aware that the Spring container guarantees - that a configured initialization callback is called immediately after - a bean has been supplied with all of its dependencies. This means that - the initialization callback will be called on the raw bean reference, - which means that any AOP interceptors or suchlike that will ultimately - be applied to the bean will not yet be in place. A target bean is - fully created first, then an - AOP proxy (for example) with its interceptor chain is applied. Note - that, if the target bean and the proxy are defined separately, your - code can even interact with the raw target bean, bypassing the proxy. - Hence, it would be very inconsistent to apply the interceptors to the - init method, since that would couple the lifecycle of the target bean - with its proxy/interceptors and leave strange semantics when talking - to the raw target bean directly. + The Spring container guarantees that a configured initialization + callback is called immediately after a bean is supplied with all + dependencies. Thus the initialization callback is called on the raw + bean reference, which means that AOP interceptors and so forth are not + yet applied to the bean. A target bean is fully created + first, then an AOP proxy + (for example) with its interceptor chain is applied. If the target + bean and the proxy are defined separately, your code can even interact + with the raw target bean, bypassing the proxy. Hence, it would be + inconsistent to apply the interceptors to the init method, because + doing so would couple the lifecycle of the target bean with its + proxy/interceptors and leave strange semantics when your code + interacts directly to the raw target bean.
- Combining lifecycle mechanisms + Combining lifecycle mechanisms - As of Spring 2.5, there are three options for controlling bean + As of Spring 2.5, you have three options for controlling bean lifecycle behavior: the InitializingBean and thread", customScope callback interfaces; custom init() and destroy() methods; and the @PostConstruct - and @PreDestroy - annotations. + and @PreDestroy annotations. You + can combine these mechanisms to control a given bean. - When combining different lifecycle mechanisms - for example, in - a class hierarchy in which various lifecycle mechanisms are in use - - developers should be aware of the order in which these mechanisms are - applied. The following is the ordering for initialization - methods: + + If multiple lifecycle mechanisms are configured for a bean, + and each mechanism is configured with a different method name, then + each configured method is executed in the order listed below. + However, if the same method name is configured - for example, + init() for an initialization method - for more + than one of these lifecycle mechanisms, that method is executed + once, as explained in the preceding section. + + + Multiple lifestyle mechanisms configured for the same bean, + with different initialization methods, are called as follows: @@ -3479,16 +3435,6 @@ beanFactory.registerScope("thread", customScope method - - - If multiple lifecycle mechanisms are configured for a given - bean, and each mechanism is configured with a different method name, - then each configured method will be executed in the order listed - above; however, if the same method name is configured - for example, - init() for an initialization method - for more - than one of the aforementioned lifecycle mechanisms, that method - will only be executed once. -
@@ -3496,29 +3442,24 @@ beanFactory.registerScope("thread", customScope applications - This next section does not apply to web applications (in case - the title of this section did not make that abundantly clear). - Spring's web-based ApplicationContext - implementations already have code in place to handle shutting down - the Spring IoC container gracefully when the relevant web - application is being shutdown. + This section applies only to non-web applications. Spring's + web-based ApplicationContext + implementations already have code in place to shut down the Spring + IoC container gracefully when the relevant web application is shut + down. If you are using Spring's IoC container in a non-web application - environment, for example in a rich client desktop environment, and you - want the container to shutdown gracefully and call the relevant - destroy callbacks on your singleton beans, you will need to register a - shutdown hook with the JVM. This is quite easy to do (see below), and - will ensure that your Spring IoC container shuts down gracefully and - that all resources held by your singletons are released. Of course it - is still up to you to both configure the destroy callbacks for your - singletons and implement such destroy callbacks correctly. + environment; for example, in a rich client desktop environment; you + register a shutdown hook with the JVM. Doing so ensures a graceful + shutdown and calls the relevant destroy methods on your singleton + beans so that all resources are released. Of course, you must still + configure and implement these destroy callbacks correctly. - So to register a shutdown hook that enables the graceful - shutdown of the relevant Spring IoC container, you simply need to call - the registerShutdownHook() method that is + To register a shutdown hook, you call the + registerShutdownHook() method that is declared on the AbstractApplicationContext - class. To wit... + class: import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -3541,101 +3482,88 @@ public final class Boot {
- Knowing who you are + <interfacename>ApplicationContextAware</interfacename> and + <interfacename>BeanNameAware</interfacename> -
- <interfacename>ApplicationContextAware</interfacename> + When an ApplicationContext creates + a class that implements the + org.springframework.contxt.ApplicationContextAware + interface, the class is provided with a reference to that + ApplicationContext. - A class which implements the - org.springframework.contxt.ApplicationContextAware - interface is provided with a reference to the - ApplicationContext that created it, - when it is created by that - ApplicationContext. - - public interface ApplicationContextAware { + public interface ApplicationContextAware { void setApplicationContext(ApplicationContext applicationContext) throws BeansException; } - This allows beans to manipulate the - ApplicationContext that created them - programmatically, through the - ApplicationContext interface, or by - casting the reference to a known subclass of this which exposes - additional functionality, for example - ConfigurableApplicationContext. One use would - be the programmatic retrieval of other beans. While there are cases - when this capability is useful, it should generally be avoided, since - it couples the code to Spring and does not follow the Inversion of - Control style, where collaborators are provided to beans as - properties. Other methods on the ApplicationContext provide access to - file resources, publishing application events, or accessing a - MessageSource. These additional features are described in the section - + Thus beans can manipulate programmatically the + ApplicationContext that created them, + through the ApplicationContext interface, + or by casting the reference to a known subclass of this interface, such + as ConfigurableApplicationContext, which exposes + additional functionality. One use would be the programmatic retrieval of + other beans. Sometimes this capability is useful; however, in general + you should avoid it, because it couples the code to Spring and does not + follow the Inversion of Control style, where collaborators are provided + to beans as properties. Other methods of the ApplicationContext provide + access to file resources, publishing application events, and accessing a + MessageSource. These additional features are described in - As of Spring 2.5, you can rely upon autowiring of the - ApplicationContext as yet another - alternative to implementing the - ApplicationContextAware interface. The - "traditional" constructor and - byType autowiring modes (as described in the - section entitled ) are now - capable of providing a dependency of type - ApplicationContext for either a - constructor argument or setter method parameter respectively. For more - flexibility (including the ability to autowire fields and multiple - parameter methods), consider using the new annotation-based autowiring - features. In that case, the - ApplicationFactory will be autowired - into a field, constructor argument, or method parameter that is - expecting the BeanFactory type as long - as the field, constructor, or method in question carries the - @Autowired annotation. For more - information, see the section entitled . -
+ As of Spring 2.5, autowiring is another alternative + to obtain reference to the ApplicationContext. + The "traditional" constructor and + byType autowiring modes (as described in ) can provide a dependency of type + ApplicationContext for a constructor + argument or setter method parameter, respectively. For more flexibility, + including the ability to autowire fields and multiple parameter methods, + use the new annotation-based autowiring features. If you do, the + ApplicationFactory is autowired into a + field, constructor argument, or method parameter that is expecting the + BeanFactory type if the field, + constructor, or method in question carries the + @Autowired annotation. For more + information, see the section entitled . -
- <interfacename>BeanNameAware</interfacename> + When an ApplicationContext creates a class that implements the + org.springframework.beans.factory.BeanNameAware + interface, the class is provided with a reference to the name defined in + its associated object definition. + public interface BeanNameAware { - If a bean implements the - org.springframework.beans.factory.BeanNameAware - interface the and is deployed in a - ApplicationContext will call the bean - through this interface to inform the bean of the - name it was deployed under. The callback will be - invoked after population of normal bean properties but before an - initialization callback like - InitializingBean's - afterPropertiesSet or a custom - init-method. -
+ void setBeanName(string name) throws BeansException; +} + + The callback is invoked after population of normal bean properties but + before an initialization callback such as + InitializingBeans + afterPropertiesSet or a custom init-method.
Bean definition inheritance - A bean definition potentially contains a large amount of - configuration information, including container specific information (for - example initialization method, static factory method name, and so forth) - and constructor arguments and property values. A child bean definition is - a bean definition that inherits configuration data from a parent - definition. It is then able to override some values, or add others, as - needed. Using parent and child bean definitions can potentially save a lot - of typing. Effectively, this is a form of templating. + A bean definition can contain a lot of configuration information, + including constructor arguments, property values, and container-specific + information such as initialization method, static factory method name, and + so on. A child bean definition inherits configuration data from a parent + definition. The child definition can override some values, or add others, + as needed. Using parent and child bean definitions can save a lot of + typing. Effectively, this is a form of templating. - When working with a - ApplicationContext programmatically, child - bean definitions are represented by the - ChildBeanDefinition class. Most users will never - work with them on this level, instead configuring bean definitions + If you work with an + ApplicationContext interface + programmatically, child bean definitions are represented by the + ChildBeanDefinition class. Most users do not work + with them on this level, instead configuring bean definitions declaratively in something like the - ClassPathXmlApplicationContext. When using - XML-based configuration metadata a child bean definition is indicated - simply by using the 'parent' attribute, specifying the - parent bean as the value of this attribute. + ClassPathXmlApplicationContext. When you use + XML-based configuration metadata, you indicate a child bean definition by + using the parent attribute, specifying the parent bean + as the value of this attribute. <bean id="inheritedTestBean" abstract="true" class="org.springframework.beans.TestBean"> @@ -3652,28 +3580,27 @@ public final class Boot { </bean> - A child bean definition will use the bean class from the parent + A child bean definition uses the bean class from the parent definition if none is specified, but can also override it. In the latter - case, the child bean class must be compatible with the parent, that is it + case, the child bean class must be compatible with the parent, that is, it must accept the parent's property values. - A child bean definition will inherit constructor argument values, - property values and method overrides from the parent, with the option to - add new values. If any init-method, destroy-method and/or - static factory method settings are specified, they will + A child bean definition inherits constructor argument values, + property values, and method overrides from the parent, with the option to + add new values. Any initialization method, destroy method, and/or + static factory method settings that you specify will override the corresponding parent settings. - The remaining settings will always be taken - from the child definition: depends on, - autowire mode, dependency check, + The remaining settings are always taken from + the child definition: depends on, autowire + mode, dependency check, singleton, scope, lazy init. - Note that in the example above, we have explicitly marked the parent - bean definition as abstract by using the abstract - attribute. In the case that the parent definition does not specify a - class, and so explicitly marking the parent bean definition as - abstract is required: + The preceding example explicitly marks the parent bean definition as + abstract by using the abstract attribute. If the parent + definition does not specify a class, explicitly marking the parent bean + definition as abstract is required, as follows: <bean id="inheritedTestBeanWithoutClass" abstract="true"> <property name="name" value="parent"/> @@ -3686,25 +3613,25 @@ public final class Boot { <!-- age will inherit the value of 1 from the parent bean definition--> </bean> - The parent bean cannot get instantiated on its own since it is + The parent bean cannot be instantiated on its own because it is incomplete, and it is also explicitly marked as - abstract. When a definition is defined to be - abstract like this, it is usable only as a pure - template bean definition that will serve as a parent definition for child - definitions. Trying to use such an abstract parent bean - on its own (by referring to it as a ref property of another bean, or doing - an explicit getBean() call with the parent bean - id), will result in an error. Similarly, the container's internal - preInstantiateSingletons() method will completely - ignore bean definitions which are defined as abstract. + abstract. When + a definition is abstract like this, it is usable only + as a pure template bean definition that serves as a parent definition for + child definitions. Trying to use such an abstract + parent bean on its own, by referring to it as a ref property of another + bean or doing an explicit getBean() call with the + parent bean id, returns an error. Similarly, the container's internal + preInstantiateSingletons() method ignores bean + definitions that are defined as abstract. - ApplicationContexts will by default - pre-instantiate all singletons. Therefore it is important (at least for + ApplicationContext pre-instantiates all + singletons by default. Therefore, it is important (at least for singleton beans) that if you have a (parent) bean definition which you intend to use only as a template, and this definition specifies a class, - you must make sure to set the 'abstract' attribute - to 'true', otherwise the application context will + you must make sure to set the abstract attribute to + true, otherwise the application context will actually (attempt to) pre-instantiate the abstract bean. @@ -3713,91 +3640,84 @@ public final class Boot {
Container extension points - The IoC component of the Spring Framework has been designed for - extension. There is typically no need for an application developer to - subclass any of the various + Typically, an application developer does not need to subclass any ApplicationContext implementation classes. - The Spring IoC container can be infinitely extended by plugging in + You can extend The Spring IoC container infinitely by plugging in implementations of special integration interfaces. The next few sections - are devoted to detailing all of these various integration - interfaces. + describe these integration interfaces.
- Customizing beans using - <literal>BeanPostProcessors</literal> + Customizing beans using the + <interfacename>BeanPostProcessor</interfacename> Interface <literal> + </literal> - The first extension point that we will look at is the - BeanPostProcessor interface. This - interface defines a number of callback methods - that you as an application developer can implement in order to provide - your own (or override the containers default) instantiation logic, - dependency-resolution logic, and so forth. If you want to do some custom - logic after the Spring container has finished instantiating, configuring - and otherwise initializing a bean, you can plug in one or more - BeanPostProcessor implementations. + The BeanPostProcessor interface + defines callback methods that you can implement + to provide your own (or override the container's default) instantiation + logic, dependency-resolution logic, and so forth. If you want to + implement some custom logic after the Spring container finishes + instantiating, configuring, and otherwise initializing a bean, you can + plug in one or more BeanPostProcessor + implementations. - You can configure multiple BeanPostProcessors - if you wish. You can control the order in which these - BeanPostProcessors execute by setting the - 'order' property (you can only set this property if - the BeanPostProcessor implements the + You can configure multiple BeanPostProcessor + interfaces. You can control the order in which these + BeanPostProcessor interfaces execute by setting the + order property. You can set this property only if the + BeanPostProcessor implements the Ordered interface; if you write your own BeanPostProcessor you should consider - implementing the Ordered interface too); - consult the Javadoc for the + implementing the Ordered interface too. + For more details, consult the Javadoc for the BeanPostProcessor and - Ordered interfaces for more - details. + Ordered interfaces. - BeanPostProcessors operate on bean (or - object) instances; that is to say, the Spring IoC - container will have instantiated a bean instance for you, and - then BeanPostProcessors get a - chance to do their stuff. + BeanPostProcessors operate on bean + (or object) instances; that is to say, the Spring + IoC container instantiates a bean instance and + then BeanPostProcessor + interfaces do their work. - If you want to change the actual bean definition (that is the - recipe that defines the bean), then you rather need to use a - BeanFactoryPostProcessor (described - below in the section entitled . - - Also, BeanPostProcessors are scoped + BeanPostProcessor interfaces are scoped per-container. This is only relevant if you are using container hierarchies. If you define a BeanPostProcessor in one container, it - will only do its stuff on the beans in that - container. Beans that are defined in another container will not be - post-processed by BeanPostProcessors in another + will only do its work on the beans in that + container. Beans that are defined in one container are not + post-processed by a BeanPostProcessor in another container, even if both containers are part of the same hierarchy. + + To change the actual bean definition (that is, the recipe that + defines the bean), you instead need to use a + BeanFactoryPostProcessor, described + below in . The org.springframework.beans.factory.config.BeanPostProcessor interface consists of exactly two callback methods. When such a class is - registered as a post-processor with the container (see below for how - this registration is effected), for each bean instance that is created - by the container, the post-processor will get a callback from the - container both before any container initialization - methods (such as afterPropertiesSet and any - declared init method) are called, and also afterwards. The - post-processor is free to do what it wishes with the bean instance, - including ignoring the callback completely. A bean post-processor will - typically check for callback interfaces, or do something such as wrap a - bean with a proxy; some of the Spring AOP infrastructure classes are - implemented as bean post-processors and they do this proxy-wrapping - logic. + registered as a post-processor with the container, for each bean + instance that is created by the container, the post-processor gets a + callback from the container both before container + initialization methods (such as afterPropertiesSet + and any declared init method) are called, and also afterwards. The + post-processor can take any action with the bean instance, including + ignoring the callback completely. A bean post-processor typically checks + for callback interfaces, or may wrap a bean with a proxy. Some Spring + AOP infrastructure classes are implemented as bean post-processors and + they do this proxy-wrapping logic. - It is important to note that an - ApplicationContext will - automatically detect any beans which are defined in - the configuration metadata which is supplied to it that implement the - BeanPostProcessor interface, and register - them as post-processors, to be then called appropriately by the - container on bean creation. Nothing else needs to be done other than - deploying the post-processors in a similar fashion to any other - bean. + An ApplicationContext + automatically detects any beans that are defined in + the configuration metadata it receives that implement the + BeanPostProcessor interface. The + ApplicationContext registers these beans + as post-processors, to be then called appropriately by the container + upon bean creation. You can then deploy the post-processors as you would + any bean. <interfacename>BeanPostProcessors</interfacename> and AOP @@ -3807,25 +3727,24 @@ public final class Boot { <interfacename>BeanPostProcessor</interfacename> interface are <emphasis>special</emphasis>, and so they are treated differently by the container. All <interfacename>BeanPostProcessors</interfacename> - <emphasis>and their directly referenced beans</emphasis> will be + <emphasis>and their directly referenced beans</emphasis> are instantiated on startup, as part of the special startup phase of the - <interfacename>ApplicationContext</interfacename>, - <emphasis>then</emphasis> all those - <interfacename>BeanPostProcessors</interfacename> will be registered - in a sorted fashion - and applied to all further beans. Since AOP + <interfacename>ApplicationContext</interfacename>. Next, all those + <interfacename>BeanPostProcessors</interfacename> are registered in a + sorted fashion - and applied to all further beans. Because AOP auto-proxying is implemented as a <interfacename>BeanPostProcessor</interfacename> itself, no <interfacename>BeanPostProcessors</interfacename> or directly - referenced beans are eligible for auto-proxying (and thus will not - have aspects 'woven' into them.</para> + referenced beans are eligible for auto-proxying, and thus do not have + aspects woven into them.</para> <para>For any such bean, you should see an info log message: - <emphasis><quote>Bean 'foo' is not eligible for getting processed by - all BeanPostProcessors (for example: not eligible for + <emphasis><quote>Bean foo is not eligible for getting processed by all + BeanPostProcessor interfaces (for example: not eligible for auto-proxying)</quote>.</emphasis></para> </note> - <para>Find below some examples of how to write, register, and use + <para>The following examples show how to write, register, and use <literal>BeanPostProcessors</literal> in the context of an <interfacename>ApplicationContext</interfacename>.</para> @@ -3833,14 +3752,11 @@ public final class Boot { <title>Example: Hello World, <interfacename>BeanPostProcessor</interfacename>-style - This first example is hardly compelling, but serves to - illustrate basic usage. All we are going to do is code a custom - BeanPostProcessor implementation that - simply invokes the toString() method of each + This first example illustrates basic usage. The example shows a + custom BeanPostProcessor implementation + that invokes the toString() method of each bean as it is created by the container and prints the resulting string - to the system console. Yes, it is not hugely useful, but serves to get - the basic concepts across before we move into the second example which - is actually useful. + to the system console. Find below the custom BeanPostProcessor implementation class @@ -3879,7 +3795,7 @@ public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor </lang:groovy> <!-- - when the above bean ('messenger') is instantiated, this custom + when the above bean (messenger) is instantiated, this custom BeanPostProcessor implementation will output the fact to the system console --> <bean class="scripting.InstantiationTracingBeanPostProcessor"/> @@ -3888,14 +3804,14 @@ public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor Notice how the InstantiationTracingBeanPostProcessor is simply - defined; it doesn't even have a name, and because it is a bean it can - be dependency injected just like any other bean. (The above - configuration also just so happens to define a bean that is backed by - a Groovy script. The Spring 2.0 dynamic language support is detailed - in the chapter entitled .) + defined. It does not even have a name, and because it is a bean it can + be dependency-injected just like any other bean. (The preceding + configuration also defines a bean that is backed by a Groovy script. + The Spring 2.0 dynamic language support is detailed in the chapter + entitled .) - Find below a small driver script to exercise the above code and - configuration; + The following small driver script executes the preceding code + and configuration: import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -3910,8 +3826,8 @@ public final class Boot { } } - The output of executing the above program will be (something - like) this: + The output of the preceding execution resembles the + following: Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961 org.springframework.scripting.groovy.GroovyMessenger@272961 @@ -3923,9 +3839,8 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 Using callback interfaces or annotations in conjunction with a custom BeanPostProcessor implementation - is a common means of extending the Spring IoC container. This next - example is a bit of a cop-out, in that you are directed to the section - entitled which + is a common means of extending the Spring IoC container. An example is + shown in the section entitled which demonstrates the usage of a custom BeanPostProcessor implementation that ships with the Spring distribution which ensures that JavaBean @@ -3936,29 +3851,32 @@ org.springframework.scripting.groovy.GroovyMessenger@272961
Customizing configuration metadata with - <literal>BeanFactoryPostProcessors</literal> + BeanFactoryPostProcessor interface + The next extension point that we will look at is the org.springframework.beans.factory.config.BeanFactoryPostProcessor. The semantics of this interface are similar to the BeanPostProcessor, with one major - difference: BeanFactoryPostProcessors operate on the - bean configuration metadata; that is, the Spring - IoC container will allow BeanFactoryPostProcessors to - read the configuration metadata and potentially change it - before the container has actually instantiated any - other beans. + difference: BeanFactoryPostProcessors + operate on the bean configuration metadata; that + is, the Spring IoC container allows + BeanFactoryPostProcessors to read the configuration + metadata and potentially change it before the + container instantiates any beans other than BeanFactoryPostProcessors. + + You can configure multiple - BeanFactoryPostProcessors if you wish. You can - control the order in which these - BeanFactoryPostProcessors execute by setting the - 'order' property (you can only set this property if - the BeanFactoryPostProcessor implements - the Ordered interface; if you write your - own BeanFactoryPostProcessor you should + BeanFactoryPostProcessors. You can control the order + in which these BeanFactoryPostProcessors execute by + setting the order property. However, you can only set + this property if the + BeanFactoryPostProcessor implements the + Ordered interface. If you write your own + BeanFactoryPostProcessor, you should consider implementing the Ordered - interface too); consult the Javadoc for the + interface too; consult the Javadoc for the BeanFactoryPostProcessor and Ordered interfaces for more details. @@ -3966,7 +3884,7 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 If you want to change the actual bean instances (the objects that are created from the - configuration metadata), then you rather need to use a + configuration metadata), then you instead need to use a BeanPostProcessor (described above in the section entitled . @@ -3982,58 +3900,58 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 even if both containers are part of the same hierarchy. - A bean factory post-processor is executed automatically when - declared inside of an ApplicationContext - to apply changes of some sort to the configuration metadata that defines - a container. Spring includes a number of pre-existing bean factory + A bean factory post-processor is executed automatically when it is + declared inside of an ApplicationContext, + in order to apply changes to the configuration metadata that defines a + container. Spring includes a number of pre-existing bean factory post-processors, such as PropertyOverrideConfigurer and PropertyPlaceholderConfigurer. A custom - BeanFactoryPostProcessor can also be used - to register custom property editors, for example. + BeanFactoryPostProcessor can also be + used, for example, to register custom property editors. - An ApplicationContext will detect - any beans which are deployed into it which implement the - BeanFactoryPostProcessor interface, and - automatically use them as bean factory post-processors, at the - appropriate time. Nothing else needs to be done other than deploying - these post-processor in a similar fashion to any other bean. + An ApplicationContext detects any + beans that are deployed into it and that implement the + BeanFactoryPostProcessor interface. It + automatically uses these beans as bean factory post-processors, at the + appropriate time. You can then deploy these post-processor beans as you + would any other bean. - Just as in the case of BeanPostProcessors, - you typically don't want to have - BeanFactoryPostProcessors marked as being - lazily-initialized. If they are marked as such, then the Spring - container will never instantiate them, and thus they won't get a - chance to apply their custom logic. If you are using the - 'default-lazy-init' attribute on the declaration of - your <beans/> element, be sure to mark your - various BeanFactoryPostProcessor bean - definitions with 'lazy-init="false"'. + As with BeanPostProcessors, you typically do + not want BeanFactoryPostProcessors marked as + lazy-initialized. If they are marked as such, the Spring container + never instantiates them, and thus they cannot apply their custom + logic. If you use the default-lazy-init attribute + on the declaration of your <beans/> element, + be sure to mark your various + BeanFactoryPostProcessor bean + definitions with lazy-init="false".
Example: the <interfacename>PropertyPlaceholderConfigurer</interfacename> - The PropertyPlaceholderConfigurer - is used to externalize property values from a bean definition into - another separate file in the standard Java - Properties format. This is useful to allow the - person deploying an application to customize environment-specific - properties (for example database URLs, usernames and passwords), - without the complexity or risk of modifying the main XML definition - file or files for the container. - + You use the + PropertyPlaceholderConfigurer to + externalize property values from a bean definition into another + separate file in the standard Java Properties + format. Doing so enables the person deploying an application to + customize environment-specific properties such as database URLs and + passwords, without the complexity or risk of modifying the main XML + definition file or files for the container. + Consider the following XML-based configuration metadata fragment, where a DataSource with - placeholder values is defined. We will configure some properties from - an external Properties file, and at runtime, we - will apply a PropertyPlaceholderConfigurer to - the metadata which will replace some properties of the - DataSource: + placeholder values is defined. The example shows properties configured + from an external Properties file. At runtime, a + PropertyPlaceholderConfigurer is applied to the + metadata that will replace some properties of the DataSource. + The values to replace are specified as 'placeholders' of the form ${property-name} + which follows the Ant / Log4J / JSP EL style. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations" value="classpath:com/foo/jdbc.properties"/> @@ -4055,35 +3973,41 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 jdbc.url=jdbc:hsqldb:hsql://production:9002 jdbc.username=sa jdbc.password=root - + Therefore, the string ${jdbc.username} is replaced at runtime with the + value 'sa' and similarly for other placeholder values that match to keys in the + property file. The PropertyPlaceholderConfigurer checks for placeholders in most + locations of a bean definition and the placeholder prefix and suffix can be customized. + With the context namespace introduced in Spring 2.5, it is possible to configure property placeholders with a - dedicated configuration element. Multiple locations may be provided as - a comma-separated list for the location + dedicated configuration element. You can provide multiple locations as + a comma-separated list in the location attribute. <context:property-placeholder location="classpath:com/foo/jdbc.properties"/> - The PropertyPlaceholderConfigurer doesn't - only look for properties in the Properties file - you specify, but also checks against the Java + The PropertyPlaceholderConfigurer does + not look for properties only in the Properties + file you specify, but also checks against the Java System properties if it cannot find a property - you are trying to use. This behavior can be customized by setting the + you are trying to use. You can customize this behavior by setting the systemPropertiesMode property of the configurer. It - has three values, one to tell the configurer to always override, one - to let it never override and one to let it - override only if the property cannot be found in the properties file - specified. Please consult the Javadoc for the + has three values that specify configurer behavior: always override, + never override, and override only if the property + is not found in the properties file specified. + + + Consult the Javadoc for the PropertyPlaceholderConfigurer for more information. Class name substitution - The PropertyPlaceholderConfigurer can - be used to substitute class names, which is sometimes useful when - you have to pick a particular implementation class at runtime. For - example: + You can use the + PropertyPlaceholderConfigurer to substitute + class names, which is sometimes useful when you have to pick a + particular implementation class at runtime. For example: <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> @@ -4096,12 +4020,11 @@ jdbc.password=root <bean id="serviceStrategy" class="${custom.strategy.class}"/> - If the class is unable to be resolved at runtime to a valid - class, resolution of the bean will fail once it is about to be - created (which is during the - preInstantiateSingletons() phase of an - ApplicationContext for a - non-lazy-init bean.) + If the class cannot be resolved at runtime to a valid class, + resolution of the bean fails when it is about to be created, which + is during the preInstantiateSingletons() + phase of an ApplicationContext for a + non-lazy-init bean.
@@ -4110,52 +4033,54 @@ jdbc.password=root PropertyOverrideConfigurer The PropertyOverrideConfigurer, another - bean factory post-processor, is similar to the - PropertyPlaceholderConfigurer, but in - contrast to the latter, the original definitions can have default - values or no values at all for bean properties. If an overriding + bean factory post-processor, resembles the + PropertyPlaceholderConfigurer, but + unlike the latter, the original definitions can have default values or + no values at all for bean properties. If an overriding Properties file does not have an entry for a certain bean property, the default context definition is used. - Note that the bean factory definition is + Note that the bean definition is not aware of being overridden, so it is not - immediately obvious when looking at the XML definition file that the - override configurer is being used. In case that there are multiple + immediately obvious from the XML definition file that the + override configurer is used. In case of multiple PropertyOverrideConfigurer instances that - define different values for the same bean property, the last one will - win (due to the overriding mechanism). + define different values for the same bean property, the last one wins, + due to the overriding mechanism. - Properties file configuration lines are expected to be in the - format: + Properties file configuration lines take this format: beanName.property=value - An example properties file might look like this: + For example: dataSource.driverClassName=com.mysql.jdbc.Driver dataSource.url=jdbc:mysql:mydb - This example file would be usable against a container definition - which contains a bean called dataSource, which - has driver and url + This example file is usable against a container definition that + contains a bean called dataSource, which has + driver and url properties. - Note that compound property names are also supported, as long as - every component of the path except the final property being overridden - is already non-null (presumably initialized by the constructors). In - this example... + Compound property names are also supported, as long as every + component of the path except the final property being overridden is + already non-null (presumably initialized by the constructors). In this + example... foo.fred.bob.sammy=123 ... the sammy property of the bob property of the fred - property of the foo bean is being set to the scalar - value 123. + property of the foo bean is set to the scalar value + 123. - Note: Specified override values are always - literal values; they are not translated into bean - references. This also applies when the original value in the XML bean - definition specifies a bean reference + + Specified override values are always + literal values; they are not translated into + bean references. This convention also applies when the original + value in the XML bean definition specifies a bean + reference. + With the context namespace introduced in Spring 2.5, it is possible to configure property overriding with a @@ -4166,684 +4091,76 @@ dataSource.url=jdbc:mysql:mydb
- Customizing instantiation logic using - <literal>FactoryBeans</literal> + Customizing instantiation logic with the + <interfacename>FactoryBean</interfacename> Interface <literal> + </literal> - The + You implement the org.springframework.beans.factory.FactoryBean - interface is to be implemented by objects that are themselves + interface for objects that are themselves factories. The FactoryBean interface is a - point of pluggability into the Spring IoC containers instantiation - logic. If you have some complex initialization code that is better - expressed in Java as opposed to a (potentially) verbose amount of XML, - you can create your own FactoryBean, - write the complex initialization inside that class, and then plug your - custom FactoryBean into the - container. + point of pluggability into the Spring IoC container's instantiation + logic. If you have complex initialization code that is better expressed + in Java as opposed to a (potentially) verbose amount of XML, you can + create your own FactoryBean, write the + complex initialization inside that class, and then plug your custom + FactoryBean into the container. The FactoryBean interface provides three methods: - Object getObject(): has to return an + Object getObject(): returns an instance of the object this factory creates. The instance can - possibly be shared (depending on whether this factory returns - singletons or prototypes). + possibly be shared, depending on whether this factory returns + singletons or prototypes. - boolean isSingleton(): has to return + boolean isSingleton(): returns true if this FactoryBean returns singletons, - false otherwise + false otherwise. - Class getObjectType(): has to return - either the object type returned by the - getObject() method or - null if the type isn't known in advance + Class getObjectType(): returns the + object type returned by the getObject() + method or null if the type is not known in + advance The FactoryBean concept and - interface is used in a number of places within the Spring Framework; at - the time of writing there are over 50 implementations of the - FactoryBean interface that ship with - Spring itself. + interface is used in a number of places within the Spring Framework; + more than 50 implementations of the + FactoryBean interface ship with Spring + itself. - Finally, there is sometimes a need to ask a container for an - actual FactoryBean instance itself, not - the bean it produces. This may be achieved by prepending the bean id - with '&' (sans quotes) when calling the + When you need to ask a container for an actual + FactoryBean instance itself, not the bean + it produces, you preface the bean id with the ampersand symbol + & (without quotes) when calling the getBean method of the ApplicationContext. So for a given FactoryBean with an id of myBean, invoking getBean("myBean") - on the container will return the product of the - FactoryBean, but invoking - getBean("&myBean") will return the - FactoryBean instance itself. + on the container returns the product of the + FactoryBean, and invoking + getBean("&myBean") returns the + FactoryBean instance itself. +
-
- The <interfacename>ApplicationContext</interfacename> - - While the beans package provides basic - functionality for managing and manipulating beans, including in a - programmatic way, the context package adds the ApplicationContext - interface, which enhances BeanFactory - functionality in a more framework-oriented style. - Many users will use ApplicationContext in a - completely declarative fashion, not even having to create it - programmatically, but instead relying on support classes such as - ContextLoader to automatically instantiate an - ApplicationContext as part of the normal - startup process of a J2EE web-app. - - The basis for the context package is the - ApplicationContext interface, located in - the org.springframework.context package. Deriving from - the BeanFactory interface, it provides all - the functionality of BeanFactory. To allow - working in a more framework-oriented fashion, using layering and - hierarchical contexts, the context package also provides the following - functionality: - - - - MessageSource, providing access - to messages in i18n-style. - - - - Access to resources, such as URLs and - files. - - - - Event propagation to beans implementing the - ApplicationListener interface. - - - - Loading of multiple (hierarchical) - contexts, allowing each to be focused on one particular - layer, for example the web layer of an application. - - - -
- Internationalization using - <literal>MessageSources</literal> - - The ApplicationContext interface - extends an interface called - MessageSource, and therefore provides - messaging (i18n or internationalization) functionality. Together with - the HierarchicalMessageSource, capable of - resolving hierarchical messages, these are the basic interfaces Spring - provides to do message resolution. Let's quickly review the methods - defined there: - - - - String getMessage(String code, Object[] args, - String default, Locale loc): the basic method used to - retrieve a message from the - MessageSource. When no message is - found for the specified locale, the default message is used. Any - arguments passed in are used as replacement values, using the - MessageFormat functionality provided - by the standard library. - - - - String getMessage(String code, Object[] args, - Locale loc): essentially the same as the previous - method, but with one difference: no default message can be - specified; if the message cannot be found, a - NoSuchMessageException is thrown. - - - - String getMessage(MessageSourceResolvable - resolvable, Locale locale): all properties used in the - methods above are also wrapped in a class named - MessageSourceResolvable, which you - can use via this method. - - - - When an ApplicationContext gets - loaded, it automatically searches for a - MessageSource bean defined in the - context. The bean has to have the name - 'messageSource'. If such a bean is found, all calls - to the methods described above will be delegated to the message source - that was found. If no message source was found, the - ApplicationContext attempts to see if it - has a parent containing a bean with the same name. If so, it uses that - bean as the MessageSource. If it can't - find any source for messages, an empty - DelegatingMessageSource will be instantiated in - order to be able to accept calls to the methods defined above. - - Spring currently provides two - MessageSource implementations. These are - the ResourceBundleMessageSource and the - StaticMessageSource. Both implement - HierarchicalMessageSource in order to do - nested messaging. The StaticMessageSource is - hardly ever used but provides programmatic ways to add messages to the - source. The ResourceBundleMessageSource is more - interesting and is the one we will provide an example for: - - <beans> - <bean id="messageSource" - class="org.springframework.context.support.ResourceBundleMessageSource"> - <property name="basenames"> - <list> - <value>format</value> - <value>exceptions</value> - <value>windows</value> - </list> - </property> - </bean> -</beans> - - This assumes you have three resource bundles defined on your - classpath called format, - exceptions and windows. Using the - JDK standard way of resolving messages through ResourceBundles, any - request to resolve a message will be handled. For the purposes of the - example, lets assume the contents of two of the above resource bundle - files are... - - # in 'format.properties' -message=Alligators rock! - - # in 'exceptions.properties' -argument.required=The '{0}' argument is required. - - Some (admittedly trivial) driver code to exercise the - MessageSource functionality can be found below. - Remember that all ApplicationContext - implementations are also MessageSource - implementations and so can be cast to the - MessageSource interface. - - public static void main(String[] args) { - MessageSource resources = new ClassPathXmlApplicationContext("beans.xml"); - String message = resources.getMessage("message", null, "Default", null); - System.out.println(message); -} - - The resulting output from the above program will be... - - Alligators rock! - - So to summarize, the MessageSource is - defined in a file called 'beans.xml' (this file - exists at the root of your classpath). The - 'messageSource' bean definition refers to a number of - resource bundles via its basenames property; the - three files that are passed in the list to the - basenames property exist as files at the root of your - classpath (and are called format.properties, - exceptions.properties, and - windows.properties respectively). - - Lets look at another example, and this time we will look at - passing arguments to the message lookup; these arguments will be - converted into Strings and inserted into placeholders in the lookup - message. This is perhaps best explained with an example: - - <beans> - - <!-- this MessageSource is being used in a web application --> - <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> - <property name="basename" value="test-messages"/> - </bean> - - <!-- let's inject the above MessageSource into this POJO --> - <bean id="example" class="com.foo.Example"> - <property name="messages" ref="messageSource"/> - </bean> - -</beans> - - public class Example { - - private MessageSource messages; - - public void setMessages(MessageSource messages) { - this.messages = messages; - } - - public void execute() { - String message = this.messages.getMessage("argument.required", - new Object [] {"userDao"}, "Required", null); - System.out.println(message); - } - -} - - The resulting output from the invocation of the - execute() method will be... - - The 'userDao' argument is required. - - With regard to internationalization (i18n), Spring's various - MessageResource implementations follow the same - locale resolution and fallback rules as the standard JDK - ResourceBundle. In short, and continuing with the - example 'messageSource' defined previously, if you - want to resolve messages against the British (en-GB) locale, you would - create files called format_en_GB.properties, - exceptions_en_GB.properties, and - windows_en_GB.properties respectively. - - Locale resolution is typically going to be managed by the - surrounding environment of the application. For the purpose of this - example though, we'll just manually specify the locale that we want to - resolve our (British) messages against. - - # in 'exceptions_en_GB.properties' -argument.required=Ebagum lad, the '{0}' argument is required, I say, required. - - public static void main(final String[] args) { - MessageSource resources = new ClassPathXmlApplicationContext("beans.xml"); - String message = resources.getMessage("argument.required", - new Object [] {"userDao"}, "Required", Locale.UK); - System.out.println(message); -} - - The resulting output from the running of the above program will - be... - - Ebagum lad, the 'userDao' argument is required, I say, required. - - The MessageSourceAware interface can also - be used to acquire a reference to any - MessageSource that has been defined. Any bean - that is defined in an ApplicationContext that - implements the MessageSourceAware interface will - be injected with the application context's - MessageSource when it (the bean) is being created - and configured. - - Note: As an alternative to - ResourceBundleMessageSource, Spring also provides - a ReloadableResourceBundleMessageSource class. - This variant supports the same bundle file format but is more flexible - than the standard JDK based - ResourceBundleMessageSource - implementation. In particular, it allows for reading files - from any Spring resource location (not just from the classpath) and - supports hot reloading of bundle property files (while efficiently - caching them in between). Check out the - ReloadableResourceBundleMessageSource javadoc for - details. -
- -
- Events - - Event handling in the - ApplicationContext is provided through - the ApplicationEvent class and - ApplicationListener interface. If a bean - which implements the ApplicationListener - interface is deployed into the context, every time an - ApplicationEvent gets published to the - ApplicationContext, that bean will be - notified. Essentially, this is the standard - Observer design pattern. Spring provides the - following standard events: - -
- Built-in Events - - - - - - - - - Event - - Explanation - - - - - - ContextRefreshedEvent - - Published when the - ApplicationContext is initialized - or refreshed, e.g. using the refresh() - method on the - ConfigurableApplicationContext - interface. "Initialized" here means that all beans are loaded, - post-processor beans are detected and activated, singletons are - pre-instantiated, and the - ApplicationContext object is - ready for use. A refresh may be triggered multiple times, as - long as the context hasn't been closed - provided that the - chosen ApplicationContext - actually supports such "hot" refreshes (which e.g. - XmlWebApplicationContext does but - GenericApplicationContext - doesn't). - - - - ContextStartedEvent - - Published when the - ApplicationContext is started, - using the start() method on the - ConfigurableApplicationContext - interface. "Started" here means that all - Lifecycle beans will receive an - explicit start signal. This will typically be used for - restarting after an explicit stop, but may also be used for - starting components that haven't been configured for autostart - (e.g. haven't started on initialization already). - - - - ContextStoppedEvent - - Published when the - ApplicationContext is stopped, - using the stop() method on the - ConfigurableApplicationContext - interface. "Stopped" here means that all - Lifecycle beans will receive an - explicit stop signal. A stopped context may be restarted through - a start() call. - - - - ContextClosedEvent - - Published when the - ApplicationContext is closed, - using the close() method on the - ConfigurableApplicationContext - interface. "Closed" here means that all singleton beans are - destroyed. A closed context has reached its end of life; it - cannot be refreshed or restarted. - - - - RequestHandledEvent - - A web-specific event telling all beans that an HTTP - request has been serviced (this will be published - after the request has been finished). Note - that this event is only applicable for web applications using - Spring's DispatcherServlet. - - - -
- - Implementing custom events can be done as well. Simply call the - publishEvent() method on the - ApplicationContext, specifying a - parameter which is an instance of your custom event class implementing - ApplicationEvent. Event listeners receive events - synchronously. This means the publishEvent() - method blocks until all listeners have finished processing the event (it - is possible to supply an alternate event publishing strategy via a - ApplicationEventMulticaster - implementation). Furthermore, when a listener receives an event it - operates inside the transaction context of the publisher, if a - transaction context is available. - - Let's look at an example. First, the - ApplicationContext: - - <bean id="emailer" class="example.EmailBean"> - <property name="blackList"> - <list> - <value>black@list.org</value> - <value>white@list.org</value> - <value>john@doe.org</value> - </list> - </property> -</bean> - -<bean id="blackListListener" class="example.BlackListNotifier"> - <property name="notificationAddress" value="spam@list.org"/> -</bean> - - Now, let's look at the actual classes: - - public class EmailBean implements ApplicationContextAware { - - private List blackList; - private ApplicationContext ctx; - - public void setBlackList(List blackList) { - this.blackList = blackList; - } - - public void setApplicationContext(ApplicationContext ctx) { - this.ctx = ctx; - } - - public void sendEmail(String address, String text) { - if (blackList.contains(address)) { - BlackListEvent event = new BlackListEvent(address, text); - ctx.publishEvent(event); - return; - } - // send email... - } -} - - public class BlackListNotifier implements ApplicationListener { - - private String notificationAddress; - - public void setNotificationAddress(String notificationAddress) { - this.notificationAddress = notificationAddress; - } - - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof BlackListEvent) { - // notify appropriate person... - } - } -} - - Of course, this particular example could probably be implemented - in better ways (perhaps by using AOP features), but it should be - sufficient to illustrate the basic event mechanism. - - -
- Convenient access to low-level resources - - For optimal usage and understanding of application contexts, users - should generally familiarize themselves with Spring's - Resource abstraction, as described in the - chapter entitled . - - An application context is a - ResourceLoader, able to be used to load - Resources. A - Resource is essentially a - java.net.URL on steroids (in fact, it just wraps and - uses a URL where appropriate), which can be used to obtain low-level - resources from almost any location in a transparent fashion, including - from the classpath, a filesystem location, anywhere describable with a - standard URL, and some other variations. If the resource location string - is a simple path without any special prefixes, where those resources - come from is specific and appropriate to the actual application context - type. - - A bean deployed into the application context may implement the - special callback interface, - ResourceLoaderAware, to be automatically - called back at initialization time with the application context itself - passed in as the ResourceLoader. A bean - may also expose properties of type - Resource, to be used to access static - resources, and expect that they will be injected into it like any other - properties. The person deploying the bean may specify those - Resource properties as simple String - paths, and rely on a special JavaBean - PropertyEditor that is automatically - registered by the context, to convert those text strings to actual - Resource objects. - - The location path or paths supplied to an - ApplicationContext constructor are - actually resource strings, and in simple form are treated appropriately - to the specific context implementation ( - ClassPathXmlApplicationContext treats a simple - location path as a classpath location), but may also be used with - special prefixes to force loading of definitions from the classpath or a - URL, regardless of the actual context type. -
- -
- Convenient <interfacename>ApplicationContext</interfacename> - instantiation for web applications - - ApplicationContext instances can be - created declaratively using for example a - ContextLoader. Of course you can also create - ApplicationContext instances - programmatically using one of the - ApplicationContext implementations. - First, let's examine the ContextLoader mechanism - and its implementations. - - The ContextLoader mechanism comes in two - flavors: the ContextLoaderListener and the - ContextLoaderServlet. They both have the same - functionality but differ in that the listener version cannot be reliably - used in Servlet 2.3 containers. Since the Servlet 2.4 specification, - servlet context listeners are required to execute immediately after the - servlet context for the web application has been created and is - available to service the first request (and also when the servlet - context is about to be shut down): as such a servlet context listener is - an ideal place to initialize the Spring - ApplicationContext. It is up to you as to - which one you use, but all things being equal you should probably prefer - ContextLoaderListener; for more information on - compatibility, have a look at the Javadoc for the - ContextLoaderServlet. - - You can register an - ApplicationContext using the - ContextLoaderListener as follows: - - <context-param> - <param-name>contextConfigLocation</param-name> - <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value> -</context-param> - -<listener> - <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> -</listener> - -<!-- or use the ContextLoaderServlet instead of the above listener -<servlet> - <servlet-name>context</servlet-name> - <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> - <load-on-startup>1</load-on-startup> -</servlet> ---> - - The listener inspects the - 'contextConfigLocation' parameter. If the parameter - does not exist, the listener will use - /WEB-INF/applicationContext.xml as a default. When it - does exist, it will separate the String using - predefined delimiters (comma, semicolon and whitespace) and use the - values as locations where application contexts will be searched for. - Ant-style path patterns are supported as well: e.g. - /WEB-INF/*Context.xml (for all files whose name ends - with "Context.xml", residing in the "WEB-INF" directory) or - /WEB-INF/**/*Context.xml (for all such files in any - subdirectory of "WEB-INF"). - - The ContextLoaderServlet can be used - instead of the ContextLoaderListener. The servlet - will use the 'contextConfigLocation' parameter just - as the listener does. -
- -
- Deploying a Spring ApplicationContext as a J2EE RAR file - - Since Spring 2.5, it is possible to deploy a Spring - ApplicationContext as a RAR file, encapsulating the context and all of - its required bean classes and library JARs in a J2EE RAR deployment - unit. This is the equivalent of bootstrapping a standalone - ApplicationContext, just hosted in J2EE environment, being able to - access the J2EE server's facilities. RAR deployment is intended as a - more 'natural' alternative to the not uncommon scenario of deploying a - headless WAR file - i.e. a WAR file without any HTTP entry points, just - used for bootstrapping a Spring ApplicationContext in a J2EE - environment. - - RAR deployment is ideal for application contexts that do not need - any HTTP entry points but rather just consist of message endpoints and - scheduled jobs etc. Beans in such a context may use application server - resources such as the JTA transaction manager and JNDI-bound JDBC - DataSources and JMS ConnectionFactory instances, and may also register - with the platform's JMX server - all through Spring's standard - transaction management and JNDI and JMX support facilities. Application - components may also interact with the application's server JCA - WorkManager through Spring's TaskExecutor - abstraction. - - Check out the JavaDoc of the SpringContextResourceAdapter - class for the configuration details involved in RAR deployment. - - For simple deployment needs, all you need to do is the - following: Package all application classes into a RAR file - (which is just a standard JAR file with a different file extension), add - all required library jars into the root of the RAR archive, add a - "META-INF/ra.xml" deployment descriptor (as shown in - SpringContextResourceAdapter's JavaDoc) as well - as the corresponding Spring XML bean definition file(s) (typically - "META-INF/applicationContext.xml"), and drop the resulting RAR file into - your application server's deployment directory! - - NOTE: Such RAR deployment units are usually - self-contained; they do not expose components to the 'outside' world, - not even to other modules of the same application. Interaction with a - RAR-based ApplicationContext usually happens through JMS destinations - that it shares with other modules. A RAR-based ApplicationContext may - also - for example - schedule some jobs, reacting to new files in the - file system (or the like). If it actually needs to allow for synchronous - access from the outside, it could for example export RMI endpoints, - which of course may be used by other application modules on the same - machine as well. -
-
Annotation-based container configuration - As mentioned in the section entitled As mentioned in , using a BeanPostProcessor in conjunction with annotations is a common means of extending the Spring IoC container. For @@ -4860,11 +4177,10 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.@PostConstruct, and @PreDestroy. Use of these annotations also requires that certain BeanPostProcessors be - registered within the Spring container. As always, these can be registered + registered within the Spring container. As always, you can register them as individual bean definitions, but they can also be implicitly registered by including the following tag in an XML-based Spring configuration - (notice the inclusion of the 'context' - namespace): + (notice the inclusion of the context namespace): <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -4880,18 +4196,18 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required. (The implicitly registered post-processors include AutowiredAnnotationBeanPostProcessor, + url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html">AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, + url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.html">CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, + url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html">PersistenceAnnotationBeanPostProcessor, as well as the aforementioned RequiredAnnotationBeanPostProcessor.) + url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.html">RequiredAnnotationBeanPostProcessor.) Note that <context:annotation-config/> - only looks for annotations on beans in the same application context it - is defined in. This means that, if you put + only looks for annotations on beans in the same application context in + which it is defined. This means that, if you put <context:annotation-config/> in a WebApplicationContext for a DispatcherServlet, it only checks for @@ -4919,22 +4235,23 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required. This annotation simply indicates that the affected bean property - must be populated at configuration time: either through an explicit - property value in a bean definition or through autowiring. The container - will throw an exception if the affected bean property has not been - populated; this allows for eager and explicit failure, avoiding - NullPointerExceptions or the like later on. Note - that it is still recommended to put assertions into the bean class - itself (for example into an init method) in order to enforce those - required references and values even when using the class outside of a + must be populated at configuration time, through an explicit property + value in a bean definition or through autowiring. The container throws + an exception if the affected bean property has not been populated; this + allows for eager and explicit failure, avoiding + NullPointerExceptions or the like later on. It is + still recommended that you put assertions into the bean class itself, + for example, into an init method. Doing so enforces those required + references and values even when you use the class outside of a container.
<interfacename>@Autowired</interfacename> - As expected, the @Autowired - annotation may be applied to "traditional" setter methods: + As expected, you can apply the + @Autowired annotation to "traditional" + setter methods: public class SimpleMovieLister { @@ -4948,7 +4265,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.// ... } - The annotation may also be applied to methods with arbitrary names + You can also apply the annotation to methods with arbitrary names and/or multiple arguments: public class MovieRecommender { @@ -4966,8 +4283,8 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.// ... } - The @Autowired annotation may even - be applied on constructors and fields: + You can apply @Autowired to + constructors and fields: public class MovieRecommender { @@ -5012,7 +4329,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.// ... } - Even typed Maps may be autowired as long as the expected key type + Even typed Maps can be autowired as long as the expected key type is String. The Map values will contain all beans of the expected type, and the keys will contain the corresponding bean names: @@ -5029,7 +4346,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.// ... } - By default, the autowiring will fail whenever + By default, the autowiring fails whenever zero candidate beans are available; the default behavior is to treat annotated methods, constructors, and fields as indicating required dependencies. This behavior can @@ -5049,33 +4366,34 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required. Only one annotated constructor per-class - may be marked as required, but multiple - non-required constructors can be annotated. In that case, each will be - considered among the candidates and Spring will use the + can be marked as required, but multiple + non-required constructors can be annotated. In that case, each is + considered among the candidates and Spring uses the greediest constructor whose dependencies can be - satisfied. + satisfied, that is the constructor that has the largest number of + arguments. - Prefer the use of @Autowired's - required attribute over the + @Autowired's + required attribute is recommended over the @Required annotation. The required attribute indicates that the property is - not required for autowiring purposes, simply skipping it if it cannot - be autowired. @Required, on the other - hand, is stronger in that it enforces the property to have been set in - any of the container's supported ways; if no value has been injected, - a corresponding exception will be raised. + not required for autowiring purposes, the property is ignored if it + cannot be autowired. @Required, on the + other hand, is stronger in that it enforces the property that was set + by any means supported by the container. If no value is injected, a + corresponding exception is raised. - @Autowired may also be used for - well-known "resolvable dependencies": the - BeanFactory interface, the - ApplicationContext interface, the - ResourceLoader interface, the - ApplicationEventPublisher interface and - the MessageSource interface. These - interfaces (and their extended interfaces such as + You can also use @Autowired for + interfaces that are well-known resolvable dependencies: + BeanFactory, + ApplicationContext, + ResourceLoader, + ApplicationEventPublisher, and + MessageSource. These interfaces and their + extended interfaces, such as ConfigurableApplicationContext or - ResourcePatternResolver) will be + ResourcePatternResolver, are automatically resolved, with no special setup necessary. public class MovieRecommender { @@ -5093,13 +4411,13 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required. Fine-tuning annotation-based autowiring with qualifiers - Since autowiring by type may lead to multiple candidates, it is + Because autowiring by type may lead to multiple candidates, it is often necessary to have more control over the selection process. One way to accomplish this is with Spring's - @Qualifier annotation. This allows for - associating qualifier values with specific arguments, narrowing the set - of type matches so that a specific bean is chosen for each argument. In - the simplest case, this can be a plain descriptive value: + @Qualifier annotation. You can associate + qualifier values with specific arguments, narrowing the set of type + matches so that a specific bean is chosen for each argument. In the + simplest case, this can be a plain descriptive value: public class MovieRecommender { @@ -5129,9 +4447,9 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.// ... } - The corresponding bean definitions would look like as follows. The - bean with qualifier value "main" would be wired with the constructor - argument that has been qualified with the same value. + The corresponding bean definitions appear as follows. The bean + with qualifier value "main" is wired with the constructor argument that + is qualified with the same value. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -5159,59 +4477,58 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required. - For a fallback match, the bean name is considered as a default - qualifier value. This means that the bean may be defined with an id - "main" instead of the nested qualifier element, leading to the same - matching result. However, note that while this can be used to refer to - specific beans by name, @Autowired is - fundamentally about type-driven injection with optional semantic - qualifiers. This means that qualifier values, even when using the bean - name fallback, always have narrowing semantics within the set of type - matches; they do not semantically express a reference to a unique bean - id. Good qualifier values would be "main" or "EMEA" or "persistent", - expressing characteristics of a specific component - independent from - the bean id (which may be auto-generated in case of an anonymous bean - definition like the one above). + For a fallback match, the bean name is considered a default + qualifier value. Thus you can define the bean with an id "main" instead + of the nested qualifier element, leading to the same matching result. + However, although you can use this convention to refer to specific beans + by name, @Autowired is fundamentally + about type-driven injection with optional semantic qualifiers. This + means that qualifier values, even with the bean name fallback, always + have narrowing semantics within the set of type matches; they do not + semantically express a reference to a unique bean id. Good qualifier + values are "main" or "EMEA" or "persistent", expressing characteristics + of a specific component that are independent from the bean id, which may + be auto-generated in case of an anonymous bean definition like the one + in the preceding example. - Qualifiers also apply to typed collections (as discussed above): - e.g. to Set<MovieCatalog>. In such a case, all - matching beans according to the declared qualifiers are going to be + Qualifiers also apply to typed collections, as discussed above, + for example, to Set<MovieCatalog>. In this + case, all matching beans according to the declared qualifiers are injected as a collection. This implies that qualifiers do not have to be unique; they rather simply constitute filtering criteria. For example, - there could be multiple MovieCatalog beans - defined with the same qualifier value "action"; all of which would be - injected into a Set<MovieCatalog> annotated - with @Qualifier("action"). + you can define multiple MovieCatalog beans with + the same qualifier value "action"; all of which would be injected into a + Set<MovieCatalog> annotated with + @Qualifier("action"). If you intend to express annotation-driven injection by name, do - not primarily use @Autowired - even if + not primarily use @Autowired, even if is technically capable of referring to a bean name through - @Qualifier values. Instead, prefer the - JSR-250 @Resource annotation which is + @Qualifier values. Instead, use the + JSR-250 @Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process. As a specific consequence of this semantic difference, beans - which are themselves defined as a collection or map type cannot be - injected via @Autowired since type - matching is not properly applicable to them. Use + that are themselves defined as a collection or map type cannot be + injected through @Autowired, because + type matching is not properly applicable to them. Use @Resource for such beans, referring to - the specific collection/map bean by unique name. + the specific collection or map bean by unique name. - Note: In contrast to - @Autowired which is applicable to - fields, constructors and multi-argument methods (allowing for - narrowing through qualifier annotations at the parameter level), - @Resource is only supported for fields + @Autowired applies to fields, + constructors, and multi-argument methods, allowing for narrowing + through qualifier annotations at the parameter level. By contrast, + @Resource is supported only for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method. - You may create your own custom qualifier annotations as well. - Simply define an annotation and provide the + You can create your own custom qualifier annotations. Simply + define an annotation and provide the @Qualifier annotation within your definition: @@ -5242,15 +4559,14 @@ public @interface Genre { // ... } - The next step is to provide the information on the candidate bean - definitions. You can add <qualifier/> tags as - sub-elements of the <bean/> tag and then - specify the 'type' and 'value' to - match your custom qualifier annotations. The type will be matched - against the fully-qualified class name of the annotation, or as a - convenience when there is no risk of conflicting names, you may use the - 'short' class name. Both are demonstrated in the following - example. + Next, provide the information for the candidate bean definitions. + You can add <qualifier/> tags as sub-elements + of the <bean/> tag and then specify the + type and value to match your + custom qualifier annotations. The type is matched against the + fully-qualified class name of the annotation. Or, as a convenience if no + risk of conflicting names exists, you can use the short class name. Both + approaches are demonstrated in the following example. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -5278,14 +4594,13 @@ public @interface Genre { </beans> - In the next section, entitled , you will see an annotation-based - alternative to providing the qualifier metadata in XML. Specifically, - see: . + In , you will see an + annotation-based alternative to providing the qualifier metadata in XML. + Specifically, see . In some cases, it may be sufficient to use an annotation without a value. This may be useful when the annotation serves a more generic - purpose and could be applied across several different types of + purpose and can be applied across several different types of dependencies. For example, you may provide an offline catalog that would be searched when no Internet connection is available. First define the simple @@ -5311,16 +4626,16 @@ public @interface Offline { } Now the bean definition only needs a qualifier - 'type': + type: <bean class="example.SimpleMovieCatalog"> <qualifier type="Offline"/> <!-- inject any dependencies required by this bean --> </bean> - It is also possible to define custom qualifier annotations that - accept named attributes in addition to or instead of the simple - 'value' attribute. If multiple attribute values are + You can also define custom qualifier annotations that accept named + attributes in addition to or instead of the simple + value attribute. If multiple attribute values are then specified on a field or parameter to be autowired, a bean definition must match all such attribute values to be considered an autowire candidate. As an example, consider the @@ -5344,8 +4659,8 @@ public @interface MovieQualifier { } The fields to be autowired are annotated with the custom qualifier - and include values for both attributes: 'genre' and - 'format'. + and include values for both attributes: genre and + format. public class MovieRecommender { @@ -5372,10 +4687,11 @@ public @interface MovieQualifier { values. This example also demonstrates that bean meta attributes may be used instead of the <qualifier/> sub-elements. If available, the - <qualifier/> and its attributes would take - precedence, but the autowiring mechanism will fallback on the values + <qualifier/> and its attributes take + precedence, but the autowiring mechanism falls back on the values provided within the <meta/> tags if no such - qualifier is present (see the last 2 bean definitions below). + qualifier is present, as in the last two bean definitions in the + following example. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -5423,11 +4739,10 @@ public @interface MovieQualifier { <classname>CustomAutowireConfigurer</classname> The CustomAutowireConfigurer + url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.html">CustomAutowireConfigurer is a BeanFactoryPostProcessor that - enables further customization of the autowiring process. Specifically, - it allows you to register your own custom qualifier annotation types - even if they are not themselves annotated with Spring's + enables you to register your own custom qualifier annotation types even + if they are not annotated with Spring's @Qualifier annotation. <bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"> @@ -5438,24 +4753,24 @@ public @interface MovieQualifier { </property> </bean> - Note that the particular implementation of - AutowireCandidateResolver that will be - activated for the application context depends upon the Java version. If - running on less than Java 5, the qualifier annotations are not + The particular implementation of + AutowireCandidateResolver that is + activated for the application context depends on the Java version. In + versions earlier than Java 5, the qualifier annotations are not supported, and therefore autowire candidates are solely determined by - the 'autowire-candidate' value of each bean - definition as well as any - 'default-autowire-candidates' pattern(s) available on - the <beans/> element. If running on Java 5 or - greater, the presence of @Qualifier - annotations or any custom annotations registered with the + the autowire-candidate value of each bean definition + as well as by any default-autowire-candidates + pattern(s) available on the <beans/> element. + In Java 5 or later, the presence of + @Qualifier annotations and any custom + annotations registered with the CustomAutowireConfigurer will also play a role. - Regardless of the Java version, the determination of a "primary" - candidate (when multiple beans qualify as autowire candidates) is the - same: if exactly one bean definition among the candidates has a - 'primary' attribute set to 'true', + Regardless of the Java version, when multiple beans qualify as + autowire candidates, the determination of a "primary" + candidate is the same: if exactly one bean definition among the + candidates has a primary attribute set to true, it will be selected.
@@ -5464,14 +4779,14 @@ public @interface MovieQualifier { Spring also supports injection using the JSR-250 @Resource annotation on fields or bean - property setter methods. This is a common pattern found in Java EE 5 and - Java 6 (e.g. in JSF 1.2 managed beans or JAX-WS 2.0 endpoints), which - Spring supports for Spring-managed objects as well. + property setter methods. This is a common pattern in Java EE 5 and Java + 6, for example, in JSF 1.2 managed beans or JAX-WS 2.0 endpoints. Spring + supports this pattern for Spring-managed objects as well. - @Resource takes a 'name' attribute, - and by default Spring will interpret that value as the bean name to be + @Resource takes a name attribute, + and by default Spring interprets that value as the bean name to be injected. In other words, it follows by-name - semantics as demonstrated in this example: + semantics, as demonstrated in this example: public class SimpleMovieLister { @@ -5483,12 +4798,11 @@ public @interface MovieQualifier { } } - If no name is specified explicitly, then the default name will be - derived from the name of the field or setter method: In case of a field, - it will simply be equivalent to the field name; in case of a setter - method, it will be equivalent to the bean property name. So the - following example is going to have the bean with name "movieFinder" - injected into its setter method: + If no name is specified explicitly, the default name is derived + from the field name or setter method. In case of a field, it takes the + field name; in case of a setter method, it takes the bean property name. + So the following example is going to have the bean with name + "movieFinder" injected into its setter method: public class SimpleMovieLister { @@ -5501,34 +4815,33 @@ public @interface MovieQualifier { } - The name provided with the annotation will be resolved as a bean - name by the ApplicationContext of which - the CommonAnnotationBeanPostProcessor is aware. - Note that the names may be resolved via JNDI if Spring's SimpleJndiBeanFactory - is configured explicitly. However, it is recommended to rely on the - default behavior and simply use Spring's JNDI lookup capabilities to - preserve the level of indirection. + The name provided with the annotation is resolved as a bean name + by the ApplicationContext of which the + CommonAnnotationBeanPostProcessor is aware. The + names can be resolved through JNDI if you configure Spring's SimpleJndiBeanFactory + explicitly. However, it is recommended that you rely on the default + behavior and simply use Spring's JNDI lookup capabilities to preserve + the level of indirection. - Similar to @Autowired, - @Resource may fall back to standard bean - type matches (i.e. find a primary type match instead of a specific named - bean) as well as resolve well-known "resolvable dependencies": the - BeanFactory interface, the - ApplicationContext interface, the - ResourceLoader interface, the - ApplicationEventPublisher interface and - the MessageSource interface. Note that - this only applies to @Resource usage with - no explicit name specified! + In the exclusive case of @Resource + usage with no explicit name specified, and similar to + @Autowired, + @Resource finds a primary type match + instead of a specific named bean and resolves well-known resolvable + dependencies: the + BeanFactory, + ApplicationContext, ResourceLoader, + ApplicationEventPublisher, and + MessageSource interfaces. + - So the following example will have its - customerPreferenceDao field looking for a bean with - name "customerPreferenceDao" first, then falling back to a primary type - match for the type CustomerPreferenceDao. The - "context" field will simply be injected based on the known resolvable - dependency type + Thus in the following example, the + customerPreferenceDao field first looks for a bean + named customerPreferenceDao, then falls back to a primary type match for + the type CustomerPreferenceDao. The "context" + field is injected based on the known resolvable dependency type ApplicationContext. public class MovieRecommender { @@ -5561,10 +4874,10 @@ public @interface MovieQualifier { callbacks. Provided that the CommonAnnotationBeanPostProcessor is registered within the Spring ApplicationContext, a - method carrying one of these annotations will be invoked at the same - point in the lifecycle as the corresponding Spring lifecycle interface's - method or explicitly declared callback method. In the example below, the - cache will be pre-populated upon initialization and cleared upon + method carrying one of these annotations is invoked at the same point in + the lifecycle as the corresponding Spring lifecycle interface method or + explicitly declared callback method. In the example below, the cache + will be pre-populated upon initialization and cleared upon destruction. public class CachingMovieLister { @@ -5581,7 +4894,7 @@ public @interface MovieQualifier { } - For details regarding the effects of combining various lifecycle + For details about the effects of combining various lifecycle mechanisms, see . @@ -5591,66 +4904,70 @@ public @interface MovieQualifier {
Classpath scanning and managed components - Thus far most of the examples within this chapter have used XML for - specifying the configuration metadata that produces each - BeanDefinition within the Spring container. - The previous section () - demonstrated the possibility of providing a considerable amount of the - configuration metadata using source-level annotations. Even in those - examples however, the "base" bean definitions were explicitly defined in - the XML file while the annotations were driving the dependency injection - only. The current section introduces an option for implicitly detecting - the candidate components by scanning the classpath - and matching against filters. + + Most examples in this chapter use XML to specify the configuration + metadata that produces each BeanDefinition + within the Spring container. The previous section () demonstrates how to provide a lot of + the configuration metadata through source-level annotations. Even in those + examples, however, the "base" bean definitions are explicitly defined in + the XML file, while the annotations only drive the dependency injection. + This section describes an option for implicitly detecting the + candidate components by scanning the classpath. + Candidate components are classes that match against a filter criteria + and have a corresponding bean definition registered with the container. + This removes the need to use XML to perform bean registration, instead + you can use annotations (for example @Component), AspectJ type expressions, + or your own custom filter criteria to select which classes + will have bean definitions registered with the container. + - Starting with Spring 3.0 many of the features provided by the - Spring JavaConfig - project have been added to the core Spring Framework. This - allows you to define beans using Java rather than using the traditional - XML files. Take a look at the - @Configuration, @Bean, - @Import and @DependsOn - annotations for how to use these new features. + Starting with Spring 3.0, many features provided by the Spring JavaConfig + project are part of the core Spring Framework. This allows you + to define beans using Java rather than using the traditional XML files. + Take a look at the @Configuration, + @Bean, @Import, and + @DependsOn annotations for how to use + these new features.
<interfacename>@Component</interfacename> and further stereotype annotations - Beginning with Spring 2.0, the - @Repository annotation was introduced as - a marker for any class that fulfills the role or - stereotype of a repository (a.k.a. Data Access - Object or DAO). Among the possibilities for leveraging such a marker is - the automatic translation of exceptions as described in . + In Spring 2.0 and later, the + @Repository annotation is a marker for + any class that fulfills the role or stereotype + (also known as Data Access Object or DAO) of a repository. Among the + uses of this marker is the automatic translation of exceptions as + described in . Spring 2.5 introduces further stereotype annotations: @Component, - @Service and + @Service, and @Controller. - @Component serves as a generic stereotype - for any Spring-managed component; whereas, + @Component is a generic stereotype for + any Spring-managed component. @Repository, @Service, and - @Controller serve as specializations of - @Component for more specific use cases - (e.g., in the persistence, service, and presentation layers, - respectively). What this means is that you can annotate your component - classes with @Component, but by - annotating them with @Repository, + @Controller are specializations of + @Component for more specific use cases, + for example, in the persistence, service, and presentation layers, + respectively. Therefore, you can annotate your component classes with + @Component, but by annotating them with + @Repository, @Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets - for pointcuts. Of course, it is also possible that + for pointcuts. It is also possible that @Repository, @Service, and @Controller may carry additional semantics in future releases of the Spring Framework. Thus, if you are - making a decision between using - @Component or + choosing between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated above, @Repository @@ -5659,11 +4976,11 @@ public @interface MovieQualifier {
- Auto-detecting components + Automatically detecting classes and registering bean definitions + - Spring provides the capability of automatically detecting - 'stereotyped' classes and registering corresponding - BeanDefinitions with the + Spring can automatically detect stereotyped classes and register + corresponding BeanDefinitions with the ApplicationContext. For example, the following two classes are eligible for such autodetection: @@ -5683,11 +5000,12 @@ public class JpaMovieFinder implements MovieFinder { // implementation elided for clarity } - To autodetect these classes and register the corresponding beans - requires the inclusion of the following element in XML where - 'basePackage' would be a common parent package for the two classes (or - alternatively a comma-separated list could be specified that included - the parent package of each class). + To autodetect these classes and register the corresponding beans, + you need to include the following element in XML, where the + base-package element is + a common parent package for the two classes. (Alternatively, you can + specify a comma-separated list that includes the parent package of each + class.) <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -5703,24 +5021,26 @@ public class JpaMovieFinder implements MovieFinder { </beans> - Note that the scanning of classpath packages requires the - presence of corresponding directory entries in the classpath. When - building jars with Ant, make sure to not activate - the files-only switch of the jar task! + The scanning of classpath packages requires the presence of + corresponding directory entries in the classpath. When you build JARs + with Ant, make sure that you do not activate the + files-only switch of the JAR task. Furthermore, the AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor are - both included implicitly when using the component-scan element. That + both included implicitly when you use the component-scan element. That means that the two components are autodetected and wired together - all without any bean configuration metadata provided in XML. - The registration of those post-processors can be disabled by - including the annotation-config attribute with a - value of 'false'. + You can disable the registration of + AutowiredAnnotationBeanPostProcessor + and CommonAnnotationBeanPostProcessor + by including the annotation-config attribute with + a value of false.
@@ -5730,18 +5050,16 @@ public class JpaMovieFinder implements MovieFinder { By default, classes annotated with @Component, @Repository, - @Service, or - @Controller (or classes annotated with a - custom annotation that itself is annotated with - @Component) are the only detected - candidate components. However it is simple to modify and extend this - behavior by applying custom filters. These can be added as either + @Service, + @Controller, or a custom annotation that + itself is annotated with @Component are + the only detected candidate components. However, you can modify and + extend this behavior simply by applying custom filters. Add them as include-filter or exclude-filter sub-elements of the - 'component-scan' element. Each filter element - requires the 'type' and - 'expression' attributes. Five filtering options exist - as described below. + component-scan element. Each filter element requires + the type and expression + attributes. The following table describes the filtering options. Filter Types @@ -5796,8 +5114,8 @@ public class JpaMovieFinder implements MovieFinder { org\.example\.Default.* - A regex expression to be matched by the target - components' class names. + A regex expression to be matched by the target components + class names. @@ -5813,7 +5131,7 @@ public class JpaMovieFinder implements MovieFinder {
- Find below an example of the XML configuration for ignoring all + The following example shows the XML configuration ignoring all @Repository annotations and using "stub" repositories instead. @@ -5827,7 +5145,7 @@ public class JpaMovieFinder implements MovieFinder { </beans> - It is also possible to disable the default filters by providing + You can also disable the default filters by providing use-default-filters="false" as an attribute of the <component-scan/> element. This will in effect disable automatic detection of classes annotated with @@ -5842,10 +5160,10 @@ public class JpaMovieFinder implements MovieFinder { Defining bean metadata within components Spring components can also contribute bean definition metadata to - the container. This is done with the same @Bean + the container. You do this with the same @Bean annotation used to define bean metadata within @Configuration annotated classes. Here is a simple - example + example: @Component public class FactoryMethodComponent { @@ -5861,17 +5179,17 @@ public class FactoryMethodComponent { } } - This class is a Spring component and has application specific code - contained in its DoWork method. However, it - also contributes a bean definition that has a factory method referring - to the method publicInstance. The + This class is a Spring component that has application-specific + code contained in its DoWork method. However, + it also contributes a bean definition that has a factory method + referring to the method publicInstance. The @Bean annotation identifies the factory method and - also other bean definition properties, such as a qualifier value via the + other bean definition properties, such as a qualifier value through the @Qualifier annotation. Other method level annotations that can be specified are @Scope, @Lazy, and custom qualifier annotations. Autowired - fields and methods are supported as before with the additional support - for autowiring of @Bean methods, as shown in the example below + fields and methods are supported as previously discussed, with + additional support for autowiring of @Bean methods: @Component public class FactoryMethodComponent { @@ -5905,26 +5223,26 @@ public class FactoryMethodComponent { } - Note the use of autowiring of the String - method parameter country to the value of the + The example autowires the String method + parameter country to the value of the Age property on another bean named privateInstance. A Spring Expression Language element - is used to define the value of the property via the notation #{ + defines the value of the property through the notation #{ <expression> }. For @Value annotations, an expression resolver is preconfigured to look for bean names when resolving expression text. The @Bean methods in a Spring component are processed differently than their counterparts inside a Spring - @Configuration class. The difference is that - @Component classes are not enhanced with CGLIB to - intercept the invocation of methods and fields. CGLIB proxying is the - means by which invoking methods or fields within - @Configuration classes' @Bean - methods create bean metadata references to collaborating objects and do - not invoke the method with normal Java semantics. + @Configuration class. The + difference is that @Component classes are not + enhanced with CGLIB to intercept the invocation of methods and fields. + CGLIB proxying is the means by which invoking methods or fields within + @Configuration classes @Bean + methods create bean metadata references to collaborating objects. + Methods are not invoked with normal Java semantics. In contrast, calling a method or field within a - @Component classes' @Bean method + @Component classes @Bean method has standard Java semantics.
@@ -5932,9 +5250,9 @@ public class FactoryMethodComponent { Naming autodetected components When a component is autodetected as part of the scanning process, - its bean name will be generated by the + its bean name is generated by the BeanNameGenerator strategy known to that - scanner. By default, any Spring 'stereotype' annotation + scanner. By default, any Spring stereotype annotation (@Component, @Repository, @Service, and @@ -5942,10 +5260,10 @@ public class FactoryMethodComponent { name value will thereby provide that name to the corresponding bean definition. If such an annotation contains no name value or for any other detected component (such - as those discovered due to custom filters), the default bean name - generator will return the uncapitalized non-qualified class name. For - example, if the following two components were detected, the names would - be 'myMovieLister' and 'movieFinderImpl': + as those discovered by custom filters), the default bean name generator + returns the uncapitalized non-qualified class name. For example, if the + following two components were detected, the names would be myMovieLister + and movieFinderImpl: @Service("myMovieLister") public class SimpleMovieLister { @@ -5958,10 +5276,10 @@ public class MovieFinderImpl implements MovieFinder { } - If you don't want to rely on the default bean-naming strategy, - you may provide a custom bean-naming strategy. First, implement the + If you do not want to rely on the default bean-naming strategy, + you can provide a custom bean-naming strategy. First, implement the BeanNameGenerator + url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/support/BeanNameGenerator.html">BeanNameGenerator interface, and be sure to include a default no-arg constructor. Then, provide the fully-qualified class name when configuring the scanner: @@ -5983,11 +5301,11 @@ public class MovieFinderImpl implements MovieFinder {
Providing a scope for autodetected components - As with Spring-managed components in general, the default and by - far most common scope is 'singleton'. However, there are times when - other scopes are needed. Therefore Spring 2.5 introduces a new - @Scope annotation as well. Simply provide - the name of the scope within the annotation, such as: + As with Spring-managed components in general, the default and most + common scope for autodetected components is singleton. However, + sometimes you need other scopes, which Spring 2.5 provides with a new + @Scope annotation. Simply provide the + name of the scope within the annotation: @Scope(StandardScopes.PROTOTYPE) @Repository @@ -5996,10 +5314,9 @@ public class MovieFinderImpl implements MovieFinder { } - If you would like to provide a custom strategy for scope - resolution rather than relying on the annotation-based approach, - implement the ScopeMetadataResolver + To provide a custom strategy for scope resolution rather than + relying on the annotation-based approach, implement the ScopeMetadataResolver interface, and be sure to include a default no-arg constructor. Then, provide the fully-qualified class name when configuring the scanner: @@ -6014,12 +5331,11 @@ public class MovieFinderImpl implements MovieFinder { When using certain non-singleton scopes, it may be necessary to generate proxies for the scoped objects. The reasoning is described in - detail within the section entitled . For this purpose, a - scoped-proxy attribute is available on the - 'component-scan' element. The three possible values are: 'no', - 'interfaces', and 'targetClass'. For example, the following - configuration will result in standard JDK dynamic proxies: + . For this + purpose, a scoped-proxy attribute is available on + the component-scan element. The three possible values are: no, + interfaces, and targetClass. For example, the following configuration + will result in standard JDK dynamic proxies: <beans ...> @@ -6032,20 +5348,19 @@ public class MovieFinderImpl implements MovieFinder {
Providing qualifier metadata with annotations - The @Qualifier annotation was - introduced in the section above entitled . The examples in that - section demonstrated use of the - @Qualifier annotation as well as custom - qualifier annotations to provide fine-grained control when resolving - autowire candidates. Since those examples were based on XML bean + The @Qualifier annotation is + discussed in . + The examples in that section demonstrate the use of the + @Qualifier annotation and custom + qualifier annotations to provide fine-grained control when you resolve + autowire candidates. Because those examples were based on XML bean definitions, the qualifier metadata was provided on the candidate bean - definitions using the 'qualifier' or - 'meta' sub-elements of the 'bean' + definitions using the qualifier or + meta sub-elements of the bean element in the XML. When relying upon classpath scanning for - autodetection of components, then the qualifier metadata may be provided - with type-level annotations on the candidate class. The following three - examples demonstrate this technique. + autodetection of components, you provide the qualifier metadata with + type-level annotations on the candidate class. The following three + examples demonstrate this technique: @Component @Qualifier("Action") @@ -6066,11 +5381,11 @@ public class CachingMovieCatalog implements MovieCatalog { } - As with most of the annotation-based alternatives, keep in mind - that the annotation metadata is bound to the class definition itself, - while the use of XML allows for multiple beans of the same - type to provide variations in their qualifier metadata - since that metadata is provided per-instance rather than + As with most annotation-based alternatives, keep in mind that + the annotation metadata is bound to the class definition itself, while + the use of XML allows for multiple beans of the same + type to provide variations in their qualifier metadata, + because that metadata is provided per-instance rather than per-class.
@@ -6088,26 +5403,28 @@ public class CachingMovieCatalog implements MovieCatalog { classes consist principally of @Bean-annotated methods that define instantiation, configuration, and initialization logic for objects that - will be managed by the Spring IoC container. + are managed by the Spring IoC container. Annotating a class with the @Configuration indicates that the class - may be used by the Spring IoC container as a source of bean definitions. + can be used by the Spring IoC container as a source of bean definitions. The simplest possible @Configuration class would read as follows: @Configuration public class AppConfig { } - An application may make use of one + An application may use one @Configuration-annotated class, or many. @Configuration is meta-annotated as a - @Component, therefore - Configuration-classes are candidates for component-scanning and may also - take advantage of @Autowired annotations - at the field and method level but not at the constructor level. - Configuration-classes must also have a default constructor. Externalized - values may be wired into Configuration-classes using the + @Component. Therefore, + @Configuration-annotated classes are + candidates for component-scanning and can also take advantage of + @Autowired annotations at the field and + method levels, but not at the constructor level. + @Configuration-annotated classes must + also have a default constructor. You can wire externalized values into + @Configuration-annotated classes with the @Value annotation.
@@ -6125,18 +5442,20 @@ public class AppConfig { and name.
You can use the @Bean annotation in - a Configuration-class or in a Component-class. + a @Configuration-annotated or in a + @Component-annotated class. +
Declaring a bean To declare a bean, simply annotate a method with the - @Bean annotation. Such a method will be - used to register a bean definition within a - ApplicationContext of the type specified as the methods + @Bean annotation. You use this method + to register a bean definition within an + ApplicationContext of the type specified as the method's return value. By default, the bean name will be the same as the method - name (see bean naming for details - on how to customize this behavior). The following is a simple example + name. (See bean naming for details + on how to customize this behavior.) The following is a simple example of a @Bean method declaration: @Configuration public class AppConfig { @@ -6148,16 +5467,14 @@ public class AppConfig { } - For comparison sake, the configuration above is exactly - equivalent to the following Spring XML: <beans> + The preceding configuration is exactly equivalent to the + following Spring XML: <beans> <bean name="transferService" class="com.acme.TransferServiceImpl"/> </beans> - Both will result in a bean named transferService - being available in the ApplicationContext, bound to an - object instance of type TransferServiceImpl: - + Both declarations make a bean named transferService + available in the ApplicationContext, bound to an object + instance of type TransferServiceImpl: transferService -> com.acme.TransferServiceImpl
@@ -6182,14 +5499,15 @@ public class AppConfig { }
- In the example above, the foo bean recevies a + In the example above, the foo bean receives a reference to bar via constructor injection.
Receiving lifecycle callbacks - Beans created in a Configuration-class supports the regular + Beans created in a @Configuration-annotated + class supports the regular lifecycle callbacks. Any classes defined with the @Bean annotation can use the @PostConstruct and @PreDestroy annotations from JSR-250, see the section on lifecycle callbacks are fully supported as well. If a bean implements InitializingBean, DisposableBean, or Lifecycle, their - respective methods will be called by the container. + respective methods are called by the container. The standard set of *Aware interfaces such as MessageSourceAware, ApplicationContextAware, - etc. are also fully supported. + and so on are also fully supported. The @Bean annotation supports specifying arbitrary initialization and destruction callback methods, @@ -6257,9 +5575,9 @@ public class AppConfig { } - Remember that because you are working directly in Java, you - can do anything you like with your objects, and do not always need - to rely on the container! + When you work directly in Java, you can do anything you like + with your objects, and do not always need to rely on the + container!
@@ -6269,15 +5587,15 @@ public class AppConfig {
Using the <interfacename>@Scope</interfacename> annotation - + You can specify that your beans defined with the @Bean annotation should have a specific scope. You can use any of the standard scopes specified in the Bean Scopes section. - The default scope is "singleton", but this - can be overridden by using the @Scope + The default scope is singleton, but you can + override this with the @Scope annotation: @Configuration public class MyConfiguration { @Bean @@ -6298,12 +5616,12 @@ public class MyConfiguration { the XML configuration is the <aop:scoped-proxy/> element. Configuring your beans in Java with a @Scope annotation offers equivalent support with the proxyMode attribute. The default - is no proxy (ScopedProxyMode.NO) but you can + is no proxy (ScopedProxyMode.NO), but you can specify ScopedProxyMode.TARGET_CLASS or ScopedProxyMode.INTERFACES. - If we were to port the XML reference documentation scoped - proxy example (see link above) to our + If you port the scoped proxy example from the XML reference + documentation (see preceding link) to our @Bean using Java, it would look like the following: // an HTTP Session-scoped bean exposed as a proxy @Bean @@ -6315,7 +5633,7 @@ public UserPreferences userPreferences() { @Bean public Service userService() { UserService service = new SimpleUserService(); - // a reference to the proxied 'userPreferences' bean + // a reference to the proxied userPreferences bean service.seUserPreferences(userPreferences()); return service; } @@ -6326,9 +5644,9 @@ public Service userService() { As noted earlier, lookup method - injection is an advanced feature that should be comparatively - rarely used. It is useful in cases where a singleton-scoped bean has - a dependency on a prototype-scoped bean. Using Java for this type of + injection is an advanced feature that you should use rarely. + It is useful in cases where a singleton-scoped bean has a dependency + on a prototype-scoped bean. Using Java for this type of configuration provides a natural means for implementing this pattern. public abstract class CommandManager { public Object process(Object commandState) { @@ -6344,11 +5662,11 @@ public Service userService() { protected abstract Command createCommand(); } - Using Java-configuration support we can easily create a - subclass of CommandManager where the abstract + Using Java-configuration support , you can create a subclass + of CommandManager where the abstract createCommand() method is overridden in such a way that - it 'looks up' a brand new (prototype) command object: - @Bean + it looks up a new (prototype) command object: @Bean @Scope("prototype") public AsyncCommand asyncCommand() { AsyncCommand command = new AsyncCommand(); @@ -6372,9 +5690,9 @@ public CommandManager commandManager() {
Customizing bean naming - By default, Configuration-classes uses a - @Bean method's name as the name of the - resulting bean. This functionality can be overridden, however, using + By default, Configuration-classes use a + @Bean methods name as the name of the + resulting bean. This functionality can be overridden, however, with the name attribute. @Configuration public class AppConfig { @@ -6388,6 +5706,651 @@ public class AppConfig {
+ +
+ Registering a <interfacename>LoadTimeWeaver</interfacename> + + The context namespace introduced in Spring 2.5 + provides a load-time-weaver element. + + <beans ...> + + <context:load-time-weaver/> + +</beans> + + Adding this element to an XML-based Spring configuration file + activates a Spring LoadTimeWeaver for the + ApplicationContext. Any bean within that + ApplicationContext may implement + LoadTimeWeaverAware, thereby receiving a + reference to the load-time weaver instance. This is particularly useful in + combination with Spring's JPA support where + load-time weaving may be necessary for JPA class transformation. Consult + the LocalContainerEntityManagerFactoryBean Javadoc + for more detail. For more on AspectJ load-time weaving, see . +
+ +
+ Additional Capabilities of the + <interfacename>ApplicationContext</interfacename> + + + As was discussed in the chapter introduction, the + org.springframework.beans.factory package provides + basic functionality for managing and manipulating beans, including in a + programmatic way. The org.springframework.context + package adds the ApplicationContext + interface, which implements the BeanFactory interface, + in addition to extending other interfaces to provide additional functionality + in a more application framework-oriented style. + Many people use the ApplicationContext in a + completely declarative fashion, not even creating it + programmatically, but instead relying on support classes such as + ContextLoader to automatically instantiate an + ApplicationContext as part of the normal + startup process of a J2EE web application. + + To enhance BeanFactory functionality + in a more framework-oriented style the context package also provides the + following functionality: + + + + Access to messages in i18n-style, through + the MessageSource interface. + + + + Access to resources, such as URLs and + files, through the ResourceLoader interface. + + + + Event publication to beans implementing the + ApplicationListener interface, through the use + of the ApplicationEventPublisher interface. + + + + Loading of multiple (hierarchical) + contexts, allowing each to be focused on one particular + layer, such as the web layer of an application, through the + HierarchicalBeanFactory interface. + + + +
+ Internationalization using + <interfacename>MessageSource</interfacename> + + The ApplicationContext interface + extends an interface called + MessageSource, and therefore provides + internationalization (i18n) functionality. Spring also provides + the interface HierarchicalMessageSource, which + can resolve messages hierarchically. Together these interfaces + provide the foundation upon which Spring effects message resolution. + The methods defined on these interfaces include: + + + String getMessage(String code, Object[] args, + String default, Locale loc): The basic method used to + retrieve a message from the + MessageSource. When no message is + found for the specified locale, the default message is used. Any + arguments passed in become replacement values, using the + MessageFormat functionality provided + by the standard library. + + + + String getMessage(String code, Object[] args, + Locale loc): Essentially the same as the previous + method, but with one difference: no default message can be + specified; if the message cannot be found, a + NoSuchMessageException is thrown. + + + + String getMessage(MessageSourceResolvable + resolvable, Locale locale): All properties used in the + preceding methods are also wrapped in a class named + MessageSourceResolvable, which you + can use with this method. + + + + When an ApplicationContext is + loaded, it automatically searches for a + MessageSource bean defined in the + context. The bean must have the name messageSource. + If such a bean is found, all calls to the preceding methods are + delegated to the message source. If no message source is found, the + ApplicationContext attempts to find a + parent containing a bean with the same name. If it does, it uses that + bean as the MessageSource. If the + ApplicationContext cannot find any source + for messages, an empty DelegatingMessageSource is + instantiated in order to be able to accept calls to the methods defined + above. + + Spring provides two MessageSource + implementations, ResourceBundleMessageSource and + StaticMessageSource. Both implement + HierarchicalMessageSource in order to do + nested messaging. The StaticMessageSource is + rarely used but provides programmatic ways to add messages to the + source. The ResourceBundleMessageSource is shown + in the following example: + + <beans> + <bean id="messageSource" + class="org.springframework.context.support.ResourceBundleMessageSource"> + <property name="basenames"> + <list> + <value>format</value> + <value>exceptions</value> + <value>windows</value> + </list> + </property> + </bean> +</beans> + + In the example it is assumed you have three resource bundles + defined in your classpath called format, + exceptions and windows. Any + request to resolve a message will be handled in the + JDK standard way of resolving messages through ResourceBundles. + For the purposes of the + example, assume the contents of two of the above resource bundle + files are... + + # in format.properties +message=Alligators rock! + + # in exceptions.properties +argument.required=The '{0}' argument is required. + + A program to execute the + MessageSource functionality is shown in the next + example. Remember that all ApplicationContext + implementations are also MessageSource + implementations and so can be cast to the + MessageSource interface. + + public static void main(String[] args) { + MessageSource resources = new ClassPathXmlApplicationContext("beans.xml"); + String message = resources.getMessage("message", null, "Default", null); + System.out.println(message); +} + + The resulting output from the above program will be... + + Alligators rock! + + So to summarize, the MessageSource is + defined in a file called beans.xml, which exists at + the root of your classpath. The messageSource bean + definition refers to a number of resource bundles through its + basenames property. The three files that are passed + in the list to the basenames property exist as files + at the root of your classpath and are called + format.properties, + exceptions.properties, and + windows.properties respectively. + + The next example shows arguments passed to the message lookup; + these arguments will be converted into Strings and inserted into + placeholders in the lookup message. + + <beans> + + <!-- this MessageSource is being used in a web application --> + <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> + <property name="basename" value="test-messages"/> + </bean> + + <!-- lets inject the above MessageSource into this POJO --> + <bean id="example" class="com.foo.Example"> + <property name="messages" ref="messageSource"/> + </bean> + +</beans> + + public class Example { + + private MessageSource messages; + + public void setMessages(MessageSource messages) { + this.messages = messages; + } + + public void execute() { + String message = this.messages.getMessage("argument.required", + new Object [] {"userDao"}, "Required", null); + System.out.println(message); + } + +} + + The resulting output from the invocation of the + execute() method will be... + + The userDao argument is required. + + With regard to internationalization (i18n), Spring's various + MessageResource implementations follow the same + locale resolution and fallback rules as the standard JDK + ResourceBundle. In short, and continuing with the + example messageSource defined previously, if you want + to resolve messages against the British (en-GB) locale, you would create + files called format_en_GB.properties, + exceptions_en_GB.properties, and + windows_en_GB.properties respectively. + + Typically, locale resolution is managed by the surrounding + environment of the application. In this example, the locale against + which (British) messages will be resolved is specified manually. + + # in exceptions_en_GB.properties +argument.required=Ebagum lad, the '{0}' argument is required, I say, required. + + public static void main(final String[] args) { + MessageSource resources = new ClassPathXmlApplicationContext("beans.xml"); + String message = resources.getMessage("argument.required", + new Object [] {"userDao"}, "Required", Locale.UK); + System.out.println(message); +} + + The resulting output from the running of the above program will + be... + + Ebagum lad, the 'userDao' argument is required, I say, required. + + You can also use the MessageSourceAware + interface to acquire a reference to any + MessageSource that has been defined. Any bean + that is defined in an ApplicationContext that + implements the MessageSourceAware interface is + injected with the application context's + MessageSource when the bean is created and + configured. + + As an alternative to + ResourceBundleMessageSource, Spring provides + a ReloadableResourceBundleMessageSource + class. This variant supports the same bundle file format but is more + flexible than the standard JDK based + ResourceBundleMessageSource + implementation. In particular, it allows for reading + files from any Spring resource location (not just from the + classpath) and supports hot reloading of bundle property files + (while efficiently caching them in between). Check out the + ReloadableResourceBundleMessageSource javadoc + for details. + + +
+ +
+ Standard and Custom Events + + Event handling in the + ApplicationContext is provided through + the ApplicationEvent class and + ApplicationListener interface. If a bean + that implements the ApplicationListener + interface is deployed into the context, every time an + ApplicationEvent gets published to the + ApplicationContext, that bean is + notified. Essentially, this is the standard + Observer design pattern. Spring provides the + following standard events: + + + Built-in Events + + + + + + + + + Event + + Explanation + + + + + + ContextRefreshedEvent + + Published when the + ApplicationContext is initialized + or refreshed, for example, using the + refresh() method on the + ConfigurableApplicationContext + interface. "Initialized" here means that all beans are loaded, + post-processor beans are detected and activated, singletons are + pre-instantiated, and the + ApplicationContext object is + ready for use. As long as the context has not been closed, a + refresh can be triggered multiple times, provided that the + chosen ApplicationContext + actually supports such "hot" refreshes. For example, + XmlWebApplicationContext supports hot + refreshes, but GenericApplicationContext + does not. + + + + ContextStartedEvent + + Published when the + ApplicationContext is started, + using the start() method on the + ConfigurableApplicationContext + interface. "Started" here means that all + Lifecycle beans receive an + explicit start signal. Typically this signal is used to restart + beans after an explicit stop, but it may also be used to start + components that have not been configured for autostart , for + example, components that have not already started on + initialization. + + + + ContextStoppedEvent + + Published when the + ApplicationContext is stopped, + using the stop() method on the + ConfigurableApplicationContext + interface. "Stopped" here means that all + Lifecycle beans receive an + explicit stop signal. A stopped context may be restarted through + a start() call. + + + + ContextClosedEvent + + Published when the + ApplicationContext is closed, + using the close() method on the + ConfigurableApplicationContext + interface. "Closed" here means that all singleton beans are + destroyed. A closed context reaches its end of life; it cannot + be refreshed or restarted. + + + + RequestHandledEvent + + A web-specific event telling all beans that an HTTP + request has been serviced. This event is published + after the request is complete. This event + is only applicable to web applications using Spring's + DispatcherServlet. + + + +
+ + You can also implement custom events. Simply call the + publishEvent() method on the + ApplicationContext, specifying a + parameter that is an instance of your custom event class that implements + ApplicationEvent. Event listeners receive events + synchronously. This means the publishEvent() + method blocks until all listeners have finished processing the event. + (It is possible to supply an alternate event publishing strategy through + an ApplicationEventMulticaster + implementation). Furthermore, when a listener receives an event, it + operates inside the transaction context of the publisher, if a + transaction context is available. + + + This example shows the bean definitions used to configure an + ApplicationContext: + + <bean id="emailer" class="example.EmailBean"> + <property name="blackList"> + <list> + <value>black@list.org</value> + <value>white@list.org</value> + <value>john@doe.org</value> + </list> + </property> +</bean> + +<bean id="blackListListener" class="example.BlackListNotifier"> + <property name="notificationAddress" value="spam@list.org"/> +</bean> + + This example shows the implementation of the classes refered to in the previous bean definitions: + + public class EmailBean implements ApplicationContextAware { + + private List blackList; + private ApplicationContext ctx; + + public void setBlackList(List blackList) { + this.blackList = blackList; + } + + public void setApplicationContext(ApplicationContext ctx) { + this.ctx = ctx; + } + + public void sendEmail(String address, String text) { + if (blackList.contains(address)) { + BlackListEvent event = new BlackListEvent(address, text); + ctx.publishEvent(event); + return; + } + // send email... + } +} + + public class BlackListNotifier implements ApplicationListener { + + private String notificationAddress; + + public void setNotificationAddress(String notificationAddress) { + this.notificationAddress = notificationAddress; + } + + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof BlackListEvent) { + // notify appropriate person... + } + } +} + + When the sendEmail method is called, if there are any emails that + should be blacklisted, a custom event of the type BlackListEvent + is published to the application context. The BlackListNotifier class + which implements the interface ApplicationListener is registered as a + subscriber to the application context and will receive the BlackListEvent. + In order to access properties specific to BlackListEvent, the listener must + perform a downcast. + +
+ +
+ Convenient access to low-level resources + + For optimal usage and understanding of application contexts, users + should generally familiarize themselves with Spring's + Resource abstraction, as described in the + chapter . + + An application context is a + ResourceLoader, which can be used to load + Resources. A + Resource is essentially a + more feature rich version of the JDK class java.net.URL, + in fact, the implementations of the Resource + wrap an instance of java.net.URL where appropriate. + A Resource can obtain low-level resources + from almost any location in a transparent fashion, including from the + classpath, a filesystem location, anywhere describable with a standard + URL, and some other variations. If the resource location string is a + simple path without any special prefixes, where those resources come + from is specific and appropriate to the actual application context + type. + + You can configure a bean deployed into the application context to + implement the special callback interface, + ResourceLoaderAware, to be automatically + called back at initialization time with the application context itself + passed in as the ResourceLoader. You can + also expose properties of type Resource, + to be used to access static resources; they will be injected into it + like any other properties. You can specify those + Resource properties as simple String + paths, and rely on a special JavaBean + PropertyEditor that is automatically + registered by the context, to convert those text strings to actual + Resource objects when the bean is + deployed. + + The location path or paths supplied to an + ApplicationContext constructor are + actually resource strings, and in simple form are treated appropriately + to the specific context implementation. + ClassPathXmlApplicationContext treats a simple + location path as a classpath location. You can also use location paths + (resource strings) with special prefixes to force loading of definitions + from the classpath or a URL, regardless of the actual context + type. +
+ +
+ Convenient <interfacename>ApplicationContext</interfacename> + instantiation for web applications + + You can create ApplicationContext + instances declaratively by using, for example, a + ContextLoader. Of course you can also create + ApplicationContext instances + programmatically by using one of the + ApplicationContext implementations. + + + The ContextLoader mechanism comes in two + flavors: the ContextLoaderListener and the + ContextLoaderServlet. They have the same + functionality but differ in that the listener version is not reliable in + Servlet 2.3 containers. In the Servlet 2.4 specification, Servlet + context listeners must execute immediately after the Servlet context for + the web application is created and is available to service the first + request (and also when the Servlet context is about to be shut down). As + such a Servlet context listener is an ideal place to initialize the + Spring ApplicationContext. All things + being equal, you should probably prefer + ContextLoaderListener; for more information on + compatibility, have a look at the Javadoc for the + ContextLoaderServlet. + + You can register an + ApplicationContext using the + ContextLoaderListener as follows: + + <context-param> + <param-name>contextConfigLocation</param-name> + <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value> +</context-param> + +<listener> + <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> +</listener> + +<!-- or use the ContextLoaderServlet instead of the above listener +<servlet> + <servlet-name>context</servlet-name> + <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> + <load-on-startup>1</load-on-startup> +</servlet> +--> + + The listener inspects the contextConfigLocation + parameter. If the parameter does not exist, the listener uses + /WEB-INF/applicationContext.xml as a default. When + the parameter does exist, the listener separates + the String by using predefined delimiters (comma, semicolon and + whitespace) and uses the values as locations where application contexts + will be searched. Ant-style path patterns are supported as well. + Examples are /WEB-INF/*Context.xml for all files with + names ending with "Context.xml", residing in the "WEB-INF" directory, + and /WEB-INF/**/*Context.xml, for all such files in + any subdirectory of "WEB-INF". + + You can use ContextLoaderServlet instead of + ContextLoaderListener. The Servlet uses the + contextConfigLocation parameter just as the listener + does. +
+ +
+ Deploying a Spring ApplicationContext as a J2EE RAR file + + In Spring 2.5 and later, it is possible to deploy a Spring + ApplicationContext as a RAR file, encapsulating the context and all of + its required bean classes and library JARs in a J2EE RAR deployment + unit. This is the equivalent of bootstrapping a standalone + ApplicationContext, just hosted in J2EE environment, being able to + access the J2EE servers facilities. RAR deployment is a more natural + alternative to scenario of deploying a headless WAR file, in effect, a + WAR file without any HTTP entry points that is used only for + bootstrapping a Spring ApplicationContext in a J2EE environment. + + RAR deployment is ideal for application contexts that do not need + HTTP entry points but rather consist only of message endpoints and + scheduled jobs. Beans in such a context can use application server + resources such as the JTA transaction manager and JNDI-bound JDBC + DataSources and JMS ConnectionFactory instances, and may also register + with the platform's JMX server - all through Spring's standard + transaction management and JNDI and JMX support facilities. Application + components can also interact with the application server's JCA + WorkManager through Spring's TaskExecutor + abstraction. + + Check out the JavaDoc of the SpringContextResourceAdapter + class for the configuration details involved in RAR deployment. + + For a simple deployment of a Spring ApplicationContext + as a J2EE RAR file: package all application classes into a + RAR file, which is a standard JAR file with a different file extension. + Add all required library JARs into the root of the RAR archive. Add a + "META-INF/ra.xml" deployment descriptor (as shown in + SpringContextResourceAdapters JavaDoc) and the + corresponding Spring XML bean definition file(s) (typically + "META-INF/applicationContext.xml"), and drop the resulting RAR file into + your application server's deployment directory. + + + Such RAR deployment units are usually self-contained; they do + not expose components to the outside world, not even to other + modules of the same application. Interaction with a RAR-based + ApplicationContext usually occurs through JMS destinations that it + shares with other modules. A RAR-based ApplicationContext may also, + for example, schedule some jobs, reacting to new files in the file + system (or the like). If it needs to allow synchronous access from + the outside, it could for example export RMI endpoints, which of + course may be used by other application modules on the same + machine. + +
+
+
The BeanFactory @@ -6400,45 +6363,41 @@ public class AppConfig { DisposableBean, are still present in Spring for the purposes of backward compatibility with the large number of third-party frameworks that integrate with Spring. Often third-party components that - can not use more modern equivalents such as @PostConstruct or @PreDestroy - in order to remain compatible with JDK 1.4 or avoid a dependency on - JSR-250. + can not use more modern equivalents such as @PostConstruct or + @PreDestroy in order to remain compatible with JDK 1.4 or to + avoid a dependency on JSR-250. - This section provides some additional background into the - differences between the BeanFactory and ApplicationContext and how one - might access the IoC container directly via a 'classic' singleton - lookup. + This section provides additional background into the differences + between the BeanFactory and + ApplicationContext and how one might access + the IoC container directly through a classic singleton lookup.
<interfacename>BeanFactory</interfacename> or <interfacename>ApplicationContext</interfacename>? - Short version: use an - ApplicationContext unless you have a - really good reason for not doing so. For those of you that are looking - for slightly more depth as to the 'but why' of the above recommendation, - keep reading. + Use an ApplicationContext unless + you have a good reason for not doing so. - As the ApplicationContext includes - all functionality of the BeanFactory, it - is generally recommended that it be used in preference to the - BeanFactory, except for a few limited - situations such as in an Applet, where memory + Because the ApplicationContext + includes all functionality of the + BeanFactory, it is generally recommended + over the BeanFactory, except for a few + situations such as in an Applet where memory consumption might be critical and a few extra kilobytes might make a - difference. However, for most 'typical' enterprise applications and + difference. However, for most typical enterprise applications and systems, the ApplicationContext is what - you will want to use. Versions of Spring 2.0 and above make + you will want to use. Spring 2.0 and later makes heavy use of the BeanPostProcessor - extension point (to effect proxying and suchlike), and if you are - using just a plain BeanFactory then a - fair amount of support such as transactions and AOP will not take effect - (at least not without some extra steps on your part), which could be - confusing because nothing will actually be wrong with the - configuration. + extension point (to effect proxying and so on). If you use only a + plain BeanFactory, a fair amount of + support such as transactions and AOP will not take effect, at least not + without some extra steps on your part. This situation could be confusing + because nothing is actually wrong with the configuration. - Find below a feature matrix that lists what features are provided - by the BeanFactory and + The following table lists features provided by the + BeanFactory and ApplicationContext interfaces and implementations. @@ -6512,9 +6471,9 @@ public class AppConfig { - To explicitly register a bean post-processor when using a - BeanFactory implementation you will need - to write code like this: + To explicitly register a bean post-processor with a + BeanFactory implementation, you must + write code like this: ConfigurableBeanFactory factory = new XmlBeanFactory(...); @@ -6524,17 +6483,10 @@ factory.addBeanPostProcessor(postProcessor); // now start using the factory - This explicit registration step is not convenient, and this is one - of the reasons why the various - ApplicationContext implementations are - preferred above plain BeanFactory - implementations in the vast majority of Spring-backed applications, - especially when using BeanPostProcessors. - To explicitly register a BeanFactoryPostProcessor when using a - BeanFactory implementation you will need - to write code like this: + BeanFactory implementation, you must + write code like this: XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml")); @@ -6545,49 +6497,49 @@ cfg.setLocation(new FileSystemResource("jdbc.properties")); // now actually do the replacement cfg.postProcessBeanFactory(factory); - In both cases, the explicit registration step is not convenient, - and this is one of the reasons why the various + In both cases, the explicit registration step is inconvenient, + which is one reason why the various ApplicationContext implementations are preferred above plain BeanFactory implementations in the vast majority of Spring-backed applications, especially when using BeanFactoryPostProcessors and - BeanPostProcessors, which are the mechanisms by - which important functionality such as property placeholder replacement - and AOP are implemented. + BeanPostProcessors. These mechanisms implement + important functionality such as property placeholder replacement and + AOP.
Glue code and the evil singleton - The majority of the code inside an application is best written in - a DI style, where that code is served out of a Spring IoC container, has - its own dependencies supplied by the container when it is created, and - is completely unaware of the container. However, for the small glue - layers of code that are sometimes needed to tie other code together, - there is sometimes a need for singleton (or quasi-singleton) style - access to a Spring IoC container. For example, third party code may try + It is best to write most application code in a + dependency-injection (DI) style, where that code is served out of a + Spring IoC container, has its own dependencies supplied by the container + when it is created, and is completely unaware of the container. However, + for the small glue layers of code that are sometimes needed to tie other + code together, you sometimes need a singleton (or quasi-singleton) style + access to a Spring IoC container. For example, third-party code may try to construct new objects directly (Class.forName() - style), without the ability to force it to get these objects out of a - Spring IoC container. If the object constructed by the third party code - is just a small stub or proxy, which then uses a singleton style access - to a Spring IoC container to get a real object to delegate to, then - inversion of control has still been achieved for the majority of the - code (the object coming out of the container); thus most code is still - unaware of the container or how it is accessed, and remains decoupled - from other code, with all ensuing benefits. EJBs may also use this - stub/proxy approach to delegate to a plain Java implementation object, - coming out of a Spring IoC container. While the Spring IoC container - itself ideally does not have to be a singleton, it may be unrealistic in - terms of memory usage or initialization times (when using beans in the - Spring IoC container such as a Hibernate + style), without the ability to get these objects out of a Spring IoC + container. If + the object constructed by the third-party code is a small stub or proxy, + which then uses a singleton style access to a Spring IoC container to + get a real object to delegate to, then inversion of control has still + been achieved for the majority of the code (the object coming out of the + container). Thus most code is still unaware of the container or how it + is accessed, and remains decoupled from other code, with all ensuing + benefits. EJBs may also use this stub/proxy approach to delegate to a + plain Java implementation object, retrieved from a Spring IoC container. + While the Spring IoC container itself ideally does not have to be a singleton, + it may be unrealistic in terms of memory usage or initialization times + (when using beans in the Spring IoC container such as a Hibernate SessionFactory) for each bean to use its own, non-singleton Spring IoC container. Looking up the application context in a service locator style is - sometimes the only option you have to access shared Spring managed - components, such as in an EJB 2.1 environment, or you want to share a - single ApplicationContext as a parent to WebApplicationContexts across - war files. In this case you should look into using the utility class + sometimes the only option for accessing shared Spring-managed + components, such as in an EJB 2.1 environment, or when you want to share + a single ApplicationContext as a parent to WebApplicationContexts across + WAR files. In this case you should look into using the utility class ContextSingletonBeanFactoryLocator locator that is described in this
-
- Registering a <interfacename>LoadTimeWeaver</interfacename> - - The context namespace introduced in Spring 2.5 - provides a load-time-weaver element. - - <beans ...> - - <context:load-time-weaver/> - -</beans> - - Adding this element to an XML-based Spring configuration file - activates a Spring LoadTimeWeaver for the - ApplicationContext. Any bean within that - ApplicationContext may implement - LoadTimeWeaverAware thereby receiving a - reference to the load-time weaver instance. This is particularly useful in - combination with Spring's JPA support where - load-time weaving may be necessary for JPA class transformation. Consult - the LocalContainerEntityManagerFactoryBean Javadoc - for more detail. For more on AspectJ load-time weaving, see . -
+