diff --git a/spring-framework-reference/src/beans.xml b/spring-framework-reference/src/beans.xml
index 48f4237fd01..4a2c95bbae0 100644
--- a/spring-framework-reference/src/beans.xml
+++ b/spring-framework-reference/src/beans.xml
@@ -24,6 +24,7 @@
(it is a sub-interface) and adds other functionality such as easier
integration with Spring's AOP features, message resource handling (for use
in internationalization), event propagation, and application-layer
+ in internationalization), event publication, and application-layer
specific contexts such as the
WebApplicationContext for use in web
applications.
@@ -33,40 +34,17 @@
ApplicationContext adds more
enterprise-centric functionality to it. The
ApplicationContext is a complete superset
- of the BeanFactory, and any description of
- BeanFactory capabilities and behavior is to
- be considered to apply to the
- ApplicationContext as well.
-
-
- BeanFactory or
- ApplicationContext?
-
- Users are sometimes unsure whether a
- BeanFactory or an
- ApplicationContext is best suited for use
- in a particular situation. A BeanFactory
- pretty much just instantiates and configures beans. An
- ApplicationContext also does that,
- and it provides the supporting infrastructure to
- enable lots of enterprise-specific features such as
- transactions and AOP.
-
- In short, favor the use of an
- ApplicationContext.
-
- (For the specific details behind this recommendation, see this
- section.)
-
+ of the BeanFactory, and is used exclusively
+ in this chapter when describing Spring's IoC container. For more
+ information on using the BeanFactory instead of an
+ ApplicationContext refer to the section .
This chapter is divided into two parts, with the first part covering the basic principles
- that apply to both the BeanFactory and
- ApplicationContext, and with the second part covering those features
- that apply only to the ApplicationContext
- interface.
+ linkend="beans-basics">first part covering Inversion of Control
+ features and the second part
+ covering additional application framework features such as event
+ publication and internationalization.
@@ -95,27 +73,42 @@
The container
- The
- org.springframework.beans.factory.BeanFactory
- is the actual representation of the Spring IoC
- container that is responsible for containing and
- otherwise managing the aforementioned beans.
-
- The BeanFactory interface is the
- central IoC container interface in Spring. Its responsibilities include
- instantiating or sourcing application objects, configuring such objects,
- and assembling the dependencies between these objects.
+ The interface
+ org.springframework.context.ApplicationContext
+ represents the Spring IoC container and is responsible for
+ instantiating, configuring, and assembling the aforementioned beans. The
+ container gets its instructions on what objects to instantiate,
+ configure and assemble by reading configuration metadata. The
+ configuration metadata can be represented in either XML, Java
+ annotations, or Java code and allows you to express the objects that
+ compose your application and the rich interdependencies between such
+ objects.There are a number of implementations of the
- BeanFactory interface that come supplied
- straight out-of-the-box with Spring. The most commonly used
- BeanFactory implementation is the
- XmlBeanFactory class. This implementation allows
- you to express the objects that compose your application, and the
- doubtless rich interdependencies between such objects, in terms of XML.
- The XmlBeanFactory takes this XML
- configuration metadata and uses it to create a
- fully configured system or application.
+ ApplicationContext interface that come supplied
+ straight out-of-the-box with Spring. In standalone applications it has
+ traditionally been common to pragmatically create an instance of ClassPathXmlApplicationContext
+ or FileSystemXmlApplicationContext.
+ This is because XML has been the traditional format for defining the
+ configuration metadata. To support the mixing of different configuration
+ metadata formats use the GenericApplicationContext
+ implementation.
+
+ In the vast majority of application scenarios, explicit user code
+ is not required to instantiate one or more instances of a Spring IoC
+ container. For example, in a web application scenario, a simple eight
+ (or so) lines of boilerplate J2EE web descriptor XML in the
+ web.xml file of the application will typically
+ suffice (see ).
+
+ The high level view of how the Spring works is shown below. Your
+ application classes are combined with configuration metadata so that
+ once the ApplicationContext is created and
+ initialized you have a fully configured and executable system or
+ application.
@@ -139,49 +132,46 @@
this configuration metadata is nothing more than how you (as an
application developer) inform the Spring container as to how to
instantiate, configure, and assemble [the objects in
- your application]. This configuration metadata is
- typically supplied in a simple and intuitive XML format. When using
- XML-based configuration metadata, you write bean
- definitions for those beans that you want the Spring IoC
- container to manage, and then let the container do its stuff.
+ your application].
+
+ This configuration metadata has historically been supplied in a
+ simple and intuitive XML format and so the majority of this chapter
+ will use the XML format to convey key concepts and features of the
+ Spring IoC container.
- XML-based metadata is by far the most commonly used form of
- configuration metadata. It is not however the
- only form of configuration metadata that is allowed. The Spring IoC
- container itself is totally decoupled from the
- format in which this configuration metadata is actually written. The
- XML-based configuration metadata format really is simple though, and
- so the majority of this chapter will use the XML format to convey
- key concepts and features of the Spring IoC container.
-
- You can find details of another form of metadata that the
- Spring container can consume in the section entitled
+ While XML-based metadata has been by far the most commonly
+ used form of configuration metadata. It is not
+ however the only form of configuration metadata that is allowed. The
+ Spring IoC container itself is totally
+ decoupled from the format in which this configuration metadata is
+ actually written.
-
- Resources
+ You can find details of other forms of metadata that the Spring
+ container can consume in the following sections
- The location path or paths supplied to an
- ApplicationContext constructor are
- actually resource strings that allow the container to load
- configuration metadata from a variety of external resources such as
- the local file system, from the Java CLASSPATH,
- etc.
+
+
+ Annotation-based
+ configuration: Spring 2.5 introduced support for annotation
+ based configuration metadata.
+
- Once you have learned about Spring's IoC container, you may
- wish to learn a little more about Spring's
- Resource abstraction, as described in
- the chapter entitled .
-
-
- In the vast majority of application scenarios, explicit user
- code is not required to instantiate one or more instances of a Spring
- IoC container. For example, in a web application scenario, a simple
- eight (or so) lines of boilerplate J2EE web descriptor XML in the
- web.xml file of the application will typically
- suffice (see ).
+
+ Java-based
+ configuration: 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 external to your application classes
+ using Java rather than XML files. Take a look at the
+ @Configuration,
+ @Bean, @Import and
+ @DependsOn annotations for how to
+ use these new features.
+
+
Spring configuration consists of at least one bean definition
that the container must manage, but typically there will be more than
@@ -200,7 +190,11 @@
Queues, and so forth. Typically one
does not configure fine-grained domain objects in the container,
because it is usually the responsibility of DAOs and business logic to
- create/load domain objects.
+ create/load domain objects. However, one can use Spring's integration
+ with AspectJ to configure objects that have been created outside the
+ control of an IoC container. See the section Using AspectJ to dependency inject domain
+ objects with Spring for more information.
Find below an example of the basic structure of XML-based
configuration metadata.
@@ -222,6 +216,15 @@
<!-- more bean definitions go here -->
</beans>
+
+ The id attribute is a string that you use to
+ identify the individual bean definition. The class
+ attribute defines the type of the bean and uses the fully qualified
+ classname. The value of the id attribute is used as a means to refer
+ to collaborating objects. Note the XML for referring to collaborating
+ objects is not shown in this example, see the section on Dependencies for more
+ information.
@@ -230,29 +233,90 @@
Instantiating a Spring IoC container is straightforward.
- ApplicationContext context = new ClassPathXmlApplicationContext(
- new String[] {"services.xml", "daos.xml"});
+ ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
-// an ApplicationContext is also a BeanFactory (via inheritance)
-BeanFactory factory = context;
+
+ The location path or paths supplied to an
+ ApplicationContext constructor are
+ actually resource strings that allow the container to load
+ configuration metadata from a variety of external resources such as
+ the local file system, from the Java CLASSPATH,
+ etc.
+
+ Once you have learned about Spring's IoC container, you may wish
+ to learn a little more about Spring's
+ Resource abstraction, as described in
+ the chapter entitled .
+
+
+ The services.xml configuration file is
+
+ <?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+
+ <!-- services -->
+
+ <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
+ <property name="accountDao" ref="accountDao"/>
+ <property name="itemDao" ref="itemDao"/>
+ <!-- additional collaborators and configuration for this bean go here -->
+ </bean>
+
+ <!-- more bean definitions for services go here -->
+
+</beans>
+
+
+ and daos.xml is
+
+ <?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+
+ <bean id="accountDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao">
+ <!-- additional collaborators and configuration for this bean go here -->
+ </bean>
+
+ <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapItemDao">
+ <!-- additional collaborators and configuration for this bean go here -->
+ </bean>
+
+ <!-- more bean definitions for data access objects go here -->
+
+</beans>
+
+ In this example, the service layer consists of the class
+ PetStoreServiceImpl and there are two data access
+ objects of the type SqlMapAccountDao and
+ SqlMapItemDao which are based on the iBatis Object/Relational mapping
+ framework. While the details of configuring an object's dependencies is
+ discussed in the chapter, Dependencies, it is intuitive to see
+ that the property element refers to the name of
+ JavaBean property and the ref element refers to the
+ name of another bean definition. This linkage between id and ref
+ elements expresses the dependency between collaborating objects. Composing XML-based configuration metadata
- It can often be useful to split up container definitions into
- multiple XML files. One way to then load an application context which
- is configured from all these XML fragments is to use the application
- context constructor which takes multiple
- Resource locations. With a bean
- factory, a bean definition reader can be used multiple times to read
- definitions from each file in turn.
+ It can often be useful to split up bean definitions into
+ multiple XML files. Often each individual XML configuration file
+ represents a logical layer or module in your architecture. One way to
+ then load an application context which is configured from all these
+ XML fragments is to use the application context constructor which
+ takes multiple Resource locations as
+ was shown in the previous section.
- Generally, the Spring team prefers the above approach, since it
- keeps container configuration files unaware of the fact that they are
- being combined with others. An alternate approach is to use one or
- more occurrences of the <import/> element to
- load bean definitions from another file (or files). Let's look at a
- sample:
+ An alternate approach is to use one or more occurrences of the
+ <import/> element to load bean definitions
+ from another file (or files). Let's look at a sample:<beans>
@@ -304,6 +368,42 @@ BeanFactory factory = context;
+
+ Using the container
+
+ An ApplicationContext is
+ essentially nothing more than the interface for an advanced factory
+ capable of maintaining a registry of different beans and their
+ dependencies. Using the method T getBean(Stringname,
+ Class<T> requiredType) you can retrieve instances of
+ your beans;
+
+ The ApplicationContext enables you
+ to read bean definitions and access them as shown below.
+
+ // create and configure beans
+ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
+
+// retrieve configured instance
+PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class);
+
+// use configured instance
+List userList service.getUsernameList();
+
+
+ Basically that is all there is to it. Using
+ getBean you can retrieve instances of your
+ beans; the client-side view of the
+ ApplicationContext is simple. The
+ ApplicationContext interface has just a
+ few other methods for retrieving beans, but ideally your application
+ code should never use them... indeed, your application code should have
+ no calls to the getBean method at all, and thus
+ no dependency on Spring APIs at all. For example, Spring's integration
+ with web frameworks provides for dependency injection for various web
+ framework classes such as controllers and JSF-managed beans.
+
+
The beans
@@ -712,31 +812,6 @@ BeanFactory factory = context;
-
-
- Using the container
-
- A BeanFactory is essentially
- nothing more than the interface for an advanced factory capable of
- maintaining a registry of different beans and their dependencies. The
- BeanFactory enables you to read bean
- definitions and access them using the bean factory. When using just the
- BeanFactory you would create one and read
- in some bean definitions in the XML format as follows:
-
- Resource res = new FileSystemResource("beans.xml");
-BeanFactory factory = new XmlBeanFactory(res);
-
- Basically that is all there is to it. Using
- getBean(String) you can retrieve instances of
- your beans; the client-side view of the
- BeanFactory is simple. The
- BeanFactory interface has just a few
- other methods, but ideally your application code should never use
- them... indeed, your application code should have no calls to the
- getBean(String) method at all, and thus no
- dependency on Spring APIs at all.
-
@@ -937,10 +1012,9 @@ public class ExampleBean {
Constructor-injection is favored by some purists though (and
with good reason). Supplying all of an object's dependencies means
- that that object is never returned to client (calling) code in a
- less than totally initialized state. The flip side is that the
- object becomes less amenable to re-configuration (or
- re-injection).
+ that object is never returned to client (calling) code in a less
+ than totally initialized state. The flip side is that the object
+ becomes less amenable to re-configuration (or re-injection).
There is no hard and fast rule here. Use whatever type of DI
makes the most sense for a particular class; sometimes, when dealing
@@ -950,29 +1024,29 @@ public class ExampleBean {
only type of DI available to you.
- The BeanFactory supports both of
- these variants for injecting dependencies into beans it manages. (It
- in fact also supports injecting setter-based dependencies after some
- dependencies have already been supplied via the constructor approach.)
- The configuration for the dependencies comes in the form of a
- BeanDefinition, which is used together
- with PropertyEditor instances to know
- how to convert properties from one format to another. However, most
- users of Spring will not be dealing with these classes directly (that
- is programmatically), but rather with an XML definition file which
- will be converted internally into instances of these classes, and used
- to load an entire Spring IoC container instance.
+ The ApplicationContext supports
+ both of these variants for injecting dependencies into beans it
+ manages. (It in fact also supports injecting setter-based dependencies
+ after some dependencies have already been supplied via the constructor
+ approach.) The configuration for the dependencies comes in the form of
+ a BeanDefinition, which is used
+ together with PropertyEditor instances
+ to know how to convert properties from one format to another. However,
+ most users of Spring will not be dealing with these classes directly
+ (that is programmatically), but rather with an XML definition file
+ which will be converted internally into instances of these classes,
+ and used to load an entire Spring IoC container instance.Bean dependency resolution generally happens as follows:
- The BeanFactory is created
- and initialized with a configuration which describes all the
- beans. (Most Spring users use a
- BeanFactory or
+ The ApplicationContext is
+ created and initialized with a configuration which describes all
+ the beans. (Many Spring users use a an
ApplicationContext implementation
- that supports XML format configuration files.)
+ that supports XML format configuration files but Java code and
+ annotation based configurations are also supported.)
@@ -1231,7 +1305,7 @@ public class ExampleBean {
<!-- results in a setDriverClassName(String) call -->
<property name="driverClassName">
- <value>com.mysql.jdbc.Driver</value>
+ <value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/mydb</value>
@@ -2023,12 +2097,13 @@ support=support@example.co.uk
relationships between collaborating beans. This means that it is
possible to automatically let Spring resolve collaborators (other beans)
for your bean by inspecting the contents of the
- BeanFactory. The autowiring functionality
- has five modes. Autowiring is specified per bean
- and can thus be enabled for some beans, while other beans will not be
- autowired. Using autowiring, it is possible to reduce or eliminate the
- need to specify properties or constructor arguments, thus saving a
- significant amount of typing.
+ ApplicationContext. The autowiring
+ functionality has five modes. Autowiring is specified
+ per bean and can thus be enabled for some beans,
+ while other beans will not be autowired. Using autowiring, it is
+ possible to reduce or eliminate the need to specify properties or
+ constructor arguments, thus saving a significant amount of typing.
+ See the section entitled When using XML-based configuration metadata, the autowire
@@ -2331,23 +2406,23 @@ support=support@example.co.uk
One solution to this issue is to forego some inversion of control.
Bean A can be made
aware of the container by implementing the
- BeanFactoryAware interface, and use programmatic means to ask the
- container via a getBean("B") call for (a
- typically new) bean B instance every time it needs it. Find below an
- admittedly somewhat contrived example of this approach:
+ ApplicationContextFactoryAware interface,
+ and use programmatic means
+ to ask the container via a getBean("B") call
+ for (a typically new) bean B instance every time it needs it. Find below
+ an admittedly somewhat contrived example of this approach:
// a class that uses a stateful Command-style class to perform some processing
package fiona.apple;
-// lots of Spring-API imports
+// Spring-API imports
import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.context.Applicationcontext;
+import org.springframework.context.ApplicationContextAware;
-public class CommandManager implements BeanFactoryAware {
+public class CommandManager implements ApplicationContextAware {
- private BeanFactory beanFactory;
+ private ApplicationContext applicationContext;
public Object process(Map commandState) {
// grab a new instance of the appropriate Command
@@ -2359,11 +2434,11 @@ public class CommandManager implements BeanFactoryAware {
// the Command returned here could be an implementation that executes asynchronously, or whatever
protected Command createCommand() {
- return (Command) this.beanFactory.getBean("command"); // notice the Spring API dependency
+ return this.applicationContext.getBean("command", Command.class); // notice the Spring API dependency
}
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- this.beanFactory = beanFactory;
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
}
}
@@ -2469,14 +2544,15 @@ public abstract class CommandManager {
The interested reader may also find the
ServiceLocatorFactoryBean (in the
org.springframework.beans.factory.config package)
- to be of use; the approach is similar to that of the
+ to be of use. The approach used in ServiceLocatorFactoryBean is
+ similar to that of another utility class,
ObjectFactoryCreatingFactoryBean, but it
allows you to specify your own lookup interface as opposed to having
- to use a Spring-specific lookup interface such as the
- ObjectFactory. Consult the (copious)
- Javadoc for the ServiceLocatorFactoryBean for
- a full treatment of this alternative approach (that
- does reduce the coupling to Spring).
+ to use a Spring-specific lookup interface. Consult the JavaDocs for
+ these classes as well as this blog
+ entry for a additional information
+ ServiceLocatorFactoryBean.
@@ -2837,7 +2913,6 @@ public class ReplacementComputeValue implements MethodReplacer {
implementation (such as
XmlWebApplicationContext). If you try using
these next scopes with regular Spring IoC containers such as the
- XmlBeanFactory or
ClassPathXmlApplicationContext, you
will get an
IllegalStateException complaining about an
@@ -3659,159 +3734,53 @@ public final class Boot {
Knowing who you are
- BeanFactoryAware
+ ApplicationContextAwareA class which implements the
- org.springframework.beans.factory.BeanFactoryAware
+ org.springframework.contxt.ApplicationContextAware
interface is provided with a reference to the
- BeanFactory that created it, when it is
- created by that BeanFactory.
+ ApplicationContext that created it,
+ when it is created by that
+ ApplicationContext.
- public interface BeanFactoryAware {
+ public interface ApplicationContextAware {
- void setBeanFactory(BeanFactory beanFactory) throws BeansException;
+ void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}This allows beans to manipulate the
- BeanFactory that created them
+ ApplicationContext that created them
programmatically, through the
- BeanFactory interface, or by casting
- the reference to a known subclass of this which exposes additional
- functionality. Primarily this would consist of 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.
-
- An alternative option that is equivalent in effect to the
- BeanFactoryAware-based approach is to
- use the
- org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean.
- (It should be noted that this approach still does not reduce the
- coupling to Spring, but it does not violate the central principle of
- IoC as much as the
- BeanFactoryAware-based
- approach.)
-
- The ObjectFactoryCreatingFactoryBean is a
- FactoryBean
- implementation that returns a reference to an object (factory) that
- can in turn be used to effect a bean lookup. The
- ObjectFactoryCreatingFactoryBean class does
- itself implement the BeanFactoryAware
- interface; what client beans are actually injected with is an instance
- of the ObjectFactory interface. This is
- a Spring-specific interface (and hence there is still no total
- decoupling from Spring), but clients can then use the
- ObjectFactory's
- getObject() method to effect the bean lookup
- (under the hood the ObjectFactory
- implementation instance that is returned simply delegates down to a
- BeanFactory to actually lookup a bean
- by name). All that you need to do is supply the
- ObjectFactoryCreatingFactoryBean with the name
- of the bean that is to be looked up. Let's look at an example:
-
- package x.y;
-
-public class NewsFeed {
-
- private String news;
-
- public void setNews(String news) {
- this.news = news;
- }
-
- public String getNews() {
- return this.toString() + ": '" + news + "'";
- }
-}
-
- package x.y;
-
-import org.springframework.beans.factory.ObjectFactory;
-
-public class NewsFeedManager {
-
- private ObjectFactory factory;
-
- public void setFactory(ObjectFactory factory) {
- this.factory = factory;
- }
-
- public void printNews() {
- // here is where the lookup is performed; note that there is no
- // need to hard code the name of the bean that is being looked up...
- NewsFeed news = (NewsFeed) factory.getObject();
- System.out.println(news.getNews());
- }
-}
-
- Find below the XML configuration to wire together the above
- classes using the
- ObjectFactoryCreatingFactoryBean
- approach.
-
- <beans>
- <bean id="newsFeedManager" class="x.y.NewsFeedManager">
- <property name="factory">
- <bean
-class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
- <property name="targetBeanName">
- <idref local="newsFeed" />
- </property>
- </bean>
- </property>
- </bean>
- <bean id="newsFeed" class="x.y.NewsFeed" scope="prototype">
- <property name="news" value="... that's fit to print!" />
- </bean>
-</beans>
-
- And here is a small driver program to test the fact that new
- (prototype) instances of the newsFeed bean are
- actually being returned for each call to the injected
- ObjectFactory inside the
- NewsFeedManager's
- printNews() method.
-
- import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-import x.y.NewsFeedManager;
-
-public class Main {
-
- public static void main(String[] args) throws Exception {
-
- ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
- NewsFeedManager manager = (NewsFeedManager) ctx.getBean("newsFeedManager");
- manager.printNews();
- manager.printNews();
- }
-}
-
- The output from running the above program will look like so
- (results will of course vary on your machine).
-
- x.y.NewsFeed@1292d26: '... that's fit to print!'
-x.y.NewsFeed@5329c5: '... that's fit to print!'
+ 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
+ As of Spring 2.5, you can rely upon autowiring of the
- BeanFactory as yet another alternative
- to implementing the BeanFactoryAware
- interface. The "traditional" constructor and
+ 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
- BeanFactory 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 BeanFactory 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
+ 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 .
@@ -3822,12 +3791,12 @@ x.y.NewsFeed@5329c5: '... that's fit to print!'If a bean implements the
org.springframework.beans.factory.BeanNameAware
- interface and is deployed in a
- BeanFactory, the
- BeanFactory 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
+ 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.
@@ -3847,14 +3816,16 @@ x.y.NewsFeed@5329c5: '... that's fit to print!'
needed. Using parent and child bean definitions can potentially save a lot
of typing. Effectively, this is a form of templating.
- When working with a BeanFactory
- programmatically, child bean definitions are represented by the
+ 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
- declaratively in something like the XmlBeanFactory.
- 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.
+ 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.<bean id="inheritedTestBean" abstract="true"
class="org.springframework.beans.TestBean">
@@ -3918,14 +3889,12 @@ x.y.NewsFeed@5329c5: '... that's fit to print!'
ignore bean definitions which are defined as abstract.
- ApplicationContexts (but
- notBeanFactories) will by
- default pre-instantiate all singletons. 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
+ ApplicationContexts will by default
+ pre-instantiate all singletons. 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
actually (attempt to) pre-instantiate the abstract
bean.
@@ -3936,7 +3905,7 @@ x.y.NewsFeed@5329c5: '... that's fit to print!'
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 BeanFactory or
+ subclass any of the various
ApplicationContext implementation classes.
The Spring IoC container can be infinitely extended by plugging in
implementations of special integration interfaces. The next few sections
@@ -4010,35 +3979,15 @@ x.y.NewsFeed@5329c5: '... that's fit to print!'
implemented as bean post-processors and they do this proxy-wrapping
logic.
- It is important to know that a
- BeanFactory treats bean post-processors
- slightly differently than an
- ApplicationContext. An
+ 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. On
- the other hand, when using a BeanFactory
- implementation, bean post-processors explicitly have to be registered,
- with code like this:
-
- ConfigurableBeanFactory factory = new XmlBeanFactory(...);
-
-// now register any needed BeanPostProcessor instances
-MyBeanPostProcessor postProcessor = new MyBeanPostProcessor();
-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.
+ deploying the post-processors in a similar fashion to any other bean.
+ BeanPostProcessors and AOP
@@ -4223,38 +4172,15 @@ org.springframework.scripting.groovy.GroovyMessenger@272961
even if both containers are part of the same hierarchy.
- A bean factory post-processor is executed manually (in the case of
- a BeanFactory) or automatically (in the
- case 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
+ 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
post-processors, such as
PropertyOverrideConfigurer and
- PropertyPlaceholderConfigurer, both described
- below. A custom BeanFactoryPostProcessor
- can also be used to register custom property editors, for
- example.
-
- In a BeanFactory, the process of
- applying a BeanFactoryPostProcessor is
- manual, and will be similar to this:
-
- XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
-
-// bring in some property values from a Properties file
-PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
-cfg.setLocation(new FileSystemResource("jdbc.properties"));
-
-// now actually do the replacement
-cfg.postProcessBeanFactory(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
- BeanFactoryPostProcessors.
+ PropertyPlaceholderConfigurer. A custom
+ BeanFactoryPostProcessor can also be used
+ to register custom property editors, for example.
@@ -4283,13 +4209,13 @@ cfg.postProcessBeanFactory(factory);
PropertyPlaceholderConfigurerThe PropertyPlaceholderConfigurer
- is used to externalize property values from a
- BeanFactory 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.
+ 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.
Consider the following XML-based configuration metadata
fragment, where a DataSource with
@@ -4485,8 +4411,7 @@ dataSource.url=jdbc:mysql:mydb
the bean it produces. This may be achieved by prepending the bean id
with '&' (sans quotes) when calling the
getBean method of the
- BeanFactory (including
- ApplicationContext). So for a given
+ ApplicationContext. So for a given
FactoryBean with an id of
myBean, invoking getBean("myBean")
on the container will return the product of the
@@ -4506,13 +4431,11 @@ dataSource.url=jdbc:mysql:mydb
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 manually, but
- instead relying on support classes such as
+ 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. (Of course, it is still possible to
- create an ApplicationContext
- programmatically.)
+ startup process of a J2EE web-app.
The basis for the context package is the
ApplicationContext interface, located in
@@ -4546,113 +4469,6 @@ dataSource.url=jdbc:mysql:mydb
-
- BeanFactory or
- ApplicationContext?
-
- 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.
-
- 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
- consumption might be critical and a few extra kilobytes might make a
- 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
- 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.
-
- Find below a feature matrix that lists what features are provided
- by the BeanFactory and
- ApplicationContext interfaces (and
- attendant implementations). (The following sections describe
- functionality that ApplicationContext
- adds to the basic BeanFactory
- capabilities in a lot more depth than the said feature matrix.)
-
-
-
-
Internationalization using
MessageSources
@@ -5098,9 +4914,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.
Convenient ApplicationContext
instantiation for web applications
- As opposed to the BeanFactory,
- which will often be created programmatically,
- ApplicationContext instances can be
+ ApplicationContext instances can be
created declaratively using for example a
ContextLoader. Of course you can also create
ApplicationContext instances
@@ -5164,123 +4978,61 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.
will use the 'contextConfigLocation' parameter just
as the listener does.
-
-
- Glue code and the evil singleton
+
+ Deploying a Spring ApplicationContext as a J2EE RAR file
- 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 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 SessionFactory) for each bean
- to use its own, non-singleton Spring IoC container.
+ 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.
- As another example, in complex J2EE applications with multiple
- layers (various JAR files, EJBs, and WAR files packaged as an EAR), with
- each layer having its own Spring IoC container definition (effectively
- forming a hierarchy), the preferred approach when there is only one
- web-app (WAR) in the top hierarchy is to simply create one composite
- Spring IoC container from the multiple XML definition files from each
- layer. All of the various Spring IoC container implementations may be
- constructed from multiple definition files in this fashion. However, if
- there are multiple sibling web-applications at the root of the hierarchy,
- it is problematic to create a Spring IoC container for each
- web-application which consists of mostly identical bean definitions from
- lower layers, as there may be issues due to increased memory usage, issues
- with creating multiple copies of beans which take a long time to
- initialize (for example a Hibernate
- SessionFactory), and possible issues due to
- side-effects. As an alternative, classes such as ContextSingletonBeanFactoryLocator
- or SingletonBeanFactoryLocator
- may be used to demand-load multiple hierarchical (that is one container is
- the parent of another) Spring IoC container instances in a singleton
- fashion, which may then be used as the parents of the web-application
- Spring IoC container instances. The result is that bean definitions for
- lower layers are loaded only as needed, and loaded only once.
+ 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.
- You can see a detailed example of the usage of these classes by
- viewing the Javadoc for the SingletonBeanFactoryLocator
- and ContextSingletonBeanFactoryLocator
- classes. As mentioned in the chapter on EJBs,
- the Spring convenience base classes for EJBs normally use a non-singleton
- BeanFactoryLocator implementation, which is
- easily replaced by the use of
- SingletonBeanFactoryLocator and
- ContextSingletonBeanFactoryLocator.
-
+ Check out the JavaDoc of the SpringContextResourceAdapter
+ class for the configuration details involved in RAR deployment.
-
- Deploying a Spring ApplicationContext as a J2EE RAR file
+ 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!
- 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.
+ 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 configuration
+ Annotation-based container configurationAs mentioned in the section entitled , using a
@@ -5941,8 +5693,8 @@ public @interface MovieQualifier {
The name provided with the annotation will be resolved as a bean
- name by the BeanFactory of which the
- CommonAnnotationBeanPostProcessor is aware.
+ 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
@@ -6028,8 +5780,7 @@ public @interface MovieQualifier {
- Classpath scanning, managed components and writing configurations
- using Java
+ Classpath scanning and managed componentsThus far most of the examples within this chapter have used XML for
specifying the configuration metadata that produces each
@@ -6278,6 +6029,247 @@ 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
+ annotation used to define bean metadata within
+ @Configuration annotated classes. Here is a simple
+ example
+
+ @Component
+public class FactoryMethodComponent {
+
+ @Bean @Qualifier("public")
+ public TestBean publicInstance() {
+ return new TestBean("publicInstance");
+ }
+
+ public void DoWork()
+ {
+ // Component method implementation omitted
+ }
+}
+
+ 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
+ @Bean annotation identifies the factory method and
+ also other bean definition properties, such as a qualifier value via 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
+
+ @Component
+public class FactoryMethodComponent {
+
+ private static int i;
+
+ @Bean @Qualifier("public")
+ public TestBean publicInstance() {
+ return new TestBean("publicInstance");
+ }
+
+ // use of a custom qualifier and autowiring of method parameters
+
+ @Bean @BeanAge(1)
+ protected TestBean protectedInstance(@Qualifier("public") TestBean spouse, @Value("#{privateInstance.age}") String country) {
+ TestBean tb = new TestBean("protectedInstance", 1);
+ tb.setSpouse(tb);
+ tb.setCountry(country);
+ return tb;
+ }
+
+ @Bean @Scope(StandardScopes.PROTOTYPE)
+ private TestBean privateInstance() {
+ return new TestBean("privateInstance", i++);
+ }
+
+ @Bean @Scope(value = StandardScopes.SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
+ public TestBean requestScopedInstance() {
+ return new TestBean("requestScopedInstance", 3);
+ }
+}
+
+
+ Note the use of autowiring of 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 #{
+ <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.
+ In contrast, calling a method or field within a
+ @Component classes' @Bean method
+ has standard Java semantics.
+
+
+
+ Naming autodetected components
+
+ When a component is autodetected as part of the scanning process,
+ its bean name will be generated by the
+ BeanNameGenerator strategy known to that
+ scanner. By default, any Spring 'stereotype' annotation
+ (@Component,
+ @Repository,
+ @Service, and
+ @Controller) that contains a
+ 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':
+
+ @Service("myMovieLister")
+public class SimpleMovieLister {
+ // ...
+}
+
+ @Repository
+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
+ BeanNameGenerator
+ interface, and be sure to include a default no-arg constructor. Then,
+ provide the fully-qualified class name when configuring the
+ scanner:
+
+
+ <beans ...>
+
+ <context:component-scan base-package="org.example"
+ name-generator="org.example.MyNameGenerator" />
+
+</beans>
+
+ As a general rule, consider specifying the name with the
+ annotation whenever other components may be making explicit references
+ to it. On the other hand, the auto-generated names are adequate whenever
+ the container is responsible for wiring.
+
+
+
+ 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:
+
+ @Scope(StandardScopes.PROTOTYPE)
+@Repository
+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
+ interface, and be sure to include a default no-arg constructor. Then,
+ provide the fully-qualified class name when configuring the
+ scanner:
+
+
+ <beans ...>
+
+ <context:component-scan base-package="org.example"
+ scope-resolver="org.example.MyScopeResolver" />
+
+</beans>
+
+ 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:
+
+ <beans ...>
+
+ <context:component-scan base-package="org.example"
+ scoped-proxy="interfaces" />
+
+</beans>
+
+
+
+ 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
+ definitions, the qualifier metadata was provided on the candidate 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.
+
+ @Component
+@Qualifier("Action")
+public class ActionMovieCatalog implements MovieCatalog {
+ // ...
+}
+
+ @Component
+@Genre("Action")
+public class ActionMovieCatalog implements MovieCatalog {
+ // ...
+}
+
+ @Component
+@Offline
+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
+ per-class.
+
+
+
+
+
+ Java-based container configuration
+
Using the @Configuration
annotation
@@ -6331,12 +6323,12 @@ public class AppConfig {
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 BeanFactory
- of the type specified as the methods 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 of a
- @Bean method declaration:
+ used to register a bean definition within a
+ ApplicationContext of the type specified as the methods
+ 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
+ of a @Bean method declaration:
@Configuration
public class AppConfig {
@@ -6354,9 +6346,9 @@ public class AppConfig {
</beans> Both will result in a bean named transferService
- being available in the BeanFactory or
- ApplicationContext, bound to an object instance of type
- TransferServiceImpl:
+ being available in the ApplicationContext, bound to an
+ object instance of type TransferServiceImpl:
+
transferService -> com.acme.TransferServiceImpl
@@ -6502,7 +6494,7 @@ public class MyConfiguration {
specify ScopedProxyMode.TARGET_CLASS or
ScopedProxyMode.INTERFACES.
- If we were to port the the XML reference documentation scoped
+ If we were to port the XML reference documentation scoped
proxy example (see link above) to our
@Bean using Java, it would look like
the following: // an HTTP Session-scoped bean exposed as a proxy
@@ -6586,242 +6578,211 @@ public class AppConfig {
}
+
-
- Defining bean metadata within components
+
+ The BeanFactory
- Spring components can also contribute bean definition metadata to
- the container. This is done with the same @Bean
- annotation used to define bean metadata within
- @Configuration annotated classes. Here is a simple
- example
+ The BeanFactory provides the underlying basis
+ for Spring's IoC functionality but it is only used directly in integration
+ with other third-party frameworks and is now largely historical in nature
+ for most users of Spring. The BeanFactory and
+ related interfaces, such as BeanFactoryAware,
+ InitializingBean,
+ 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.
- @Component
-public class FactoryMethodComponent {
+ 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.
- @Bean @Qualifier("public")
- public TestBean publicInstance() {
- return new TestBean("publicInstance");
- }
+
+ BeanFactory or
+ ApplicationContext?
- public void DoWork()
- {
- // Component method implementation omitted
- }
-}
+ 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.
- 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
- @Bean annotation identifies the factory method and
- also other bean definition properties, such as a qualifier value via 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
+ 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
+ consumption might be critical and a few extra kilobytes might make a
+ 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
+ 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.
- @Component
-public class FactoryMethodComponent {
+ Find below a feature matrix that lists what features are provided
+ by the BeanFactory and
+ ApplicationContext interfaces and
+ implementations.
- private static int i;
+
+ Feature Matrix
- @Bean @Qualifier("public")
- public TestBean publicInstance() {
- return new TestBean("publicInstance");
- }
+
+
- // use of a custom qualifier and autowiring of method parameters
+
+
+ Feature
- @Bean @BeanAge(1)
- protected TestBean protectedInstance(@Qualifier("public") TestBean spouse, @Value("#{privateInstance.age}") String country) {
- TestBean tb = new TestBean("protectedInstance", 1);
- tb.setSpouse(tb);
- tb.setCountry(country);
- return tb;
- }
+ BeanFactory
- @Bean @Scope("prototype")
- private TestBean privateInstance() {
- return new TestBean("privateInstance", i++);
- }
+ ApplicationContext
+
+
+
+
+ Bean instantiation/wiring
- @Bean @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
- public TestBean requestScopedInstance() {
- return new TestBean("requestScopedInstance", 3);
- }
-}
-
+ Yes
- Note the use of autowiring of 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 #{
- <expression> }. For @Value
- annotations, an expression resolver is preconfigured to look for bean
- names when resolving expression text.
+ Yes
+
- 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.
- In contrast, calling a method or field within a
- @Component classes' @Bean method
- has standard Java semantics.
+
+ Automatic
+ BeanPostProcessor
+ registration
+
+ No
+
+ Yes
+
+
+
+ Automatic
+ BeanFactoryPostProcessor
+ registration
+
+ No
+
+ Yes
+
+
+
+ Convenient
+ MessageSource access (for
+ i18n)
+
+ No
+
+ Yes
+
+
+ ApplicationEvent
+ publication
+
+ No
+
+ Yes
+
+
+
+
+
+ To explicitly register a bean post-processor when using a
+ BeanFactory implementation you will need
+ to write code like this:
+
+ ConfigurableBeanFactory factory = new XmlBeanFactory(...);
+
+// now register any needed BeanPostProcessor instances
+MyBeanPostProcessor postProcessor = new MyBeanPostProcessor();
+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:
+
+ XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
+
+// bring in some property values from a Properties file
+PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
+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
+ 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.
-
- Naming autodetected components
+
+ Glue code and the evil singleton
- When a component is autodetected as part of the scanning process,
- its bean name will be generated by the
- BeanNameGenerator strategy known to that
- scanner. By default, any Spring 'stereotype' annotation
- (@Component,
- @Repository,
- @Service, and
- @Controller) that contains a
- 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':
+ 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
+ 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
+ SessionFactory) for each bean to use its
+ own, non-singleton Spring IoC container.
- @Service("myMovieLister")
-public class SimpleMovieLister {
- // ...
-}
-
- @Repository
-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
- BeanNameGenerator
- interface, and be sure to include a default no-arg constructor. Then,
- provide the fully-qualified class name when configuring the
- scanner:
-
-
- <beans ...>
-
- <context:component-scan base-package="org.example"
- name-generator="org.example.MyNameGenerator" />
-
-</beans>
-
- As a general rule, consider specifying the name with the
- annotation whenever other components may be making explicit references
- to it. On the other hand, the auto-generated names are adequate whenever
- the container is responsible for wiring.
-
-
-
- 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 introduced a new
- @Scope annotation as well. Simply provide
- the name of the scope within the annotation, such as:
-
- @Scope("prototype")
-@Repository
-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
- interface, and be sure to include a default no-arg constructor. Then,
- provide the fully-qualified class name when configuring the
- scanner:
-
-
- <beans ...>
-
- <context:component-scan base-package="org.example"
- scope-resolver="org.example.MyScopeResolver" />
-
-</beans>
-
- 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:
-
- <beans ...>
-
- <context:component-scan base-package="org.example"
- scoped-proxy="interfaces" />
-
-</beans>
-
-
-
- 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
- definitions, the qualifier metadata was provided on the candidate 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.
-
- @Component
-@Qualifier("Action")
-public class ActionMovieCatalog implements MovieCatalog {
- // ...
-}
-
- @Component
-@Genre("Action")
-public class ActionMovieCatalog implements MovieCatalog {
- // ...
-}
-
- @Component
-@Offline
-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
- per-class.
-
+ 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
+ ContextSingletonBeanFactoryLocator
+ locator that is described in this SpringSource
+ team blog entry.