3.0
Copyright © 2004-2010 Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Alef Arendsen, Thomas Risberg, Darren Davison, Dmitriy Kopylenko, Mark Pollack, Thierry Templier, Erwin Vervaet, Portia Tung, Ben Hale, Adrian Colyer, John Lewis, Costin Leau, Mark Fisher, Sam Brannen, Ramnivas Laddad, Arjen Poutsma, Chris Beams, Tareq Abedrabbo, Andy Clement, Dave Syer, Oliver Gierke
Table of Contents
The Spring Framework is a lightweight solution and a potential one-stop-shop for building your enterprise-ready applications. However, Spring is modular, allowing you to use only those parts that you need, without having to bring in the rest. You can use the IoC container, with Struts on top, but you can also use only the Hibernate integration code or the JDBC abstraction layer. The Spring Framework supports declarative transaction management, remote access to your logic through RMI or web services, and various options for persisting your data. It offers a full-featured MVC framework, and enables you to integrate AOP transparently into your software.
Spring is designed to be non-intrusive, meaning that your domain logic code generally has no dependencies on the framework itself. In your integration layer (such as the data access layer), some dependencies on the data access technology and the Spring libraries will exist. However, it should be easy to isolate these dependencies from the rest of your code base.
This document is a reference guide to Spring Framework features. If you have any requests, comments, or questions on this document, please post them on the user mailing list or on the support forums at http://forum.springsource.org/.
Spring Framework is a Java platform that provides comprehensive infrastructure support for developing Java applications. Spring handles the infrastructure so you can focus on your application.
Spring enables you to build applications from “plain old Java objects” (POJOs) and to apply enterprise services non-invasively to POJOs. This capability applies to the Java SE programming model and to full and partial Java EE.
Examples of how you, as an application developer, can use the Spring platform advantage:
Make a Java method execute in a database transaction without having to deal with transaction APIs.
Make a local Java method a remote procedure without having to deal with remote APIs.
Make a local Java method a management operation without having to deal with JMX APIs.
Make a local Java method a message handler without having to deal with JMS APIs.
Java applications -- a loose term that runs the gamut from constrained applets to n-tier server-side enterprise applications -- typically consist of objects that collaborate to form the application proper. Thus the objects in an application have dependencies on each other.
Although the Java platform provides a wealth of application development functionality, it lacks the means to organize the basic building blocks into a coherent whole, leaving that task to architects and developers. True, you can use design patterns such as Factory, Abstract Factory, Builder, Decorator, and Service Locator to compose the various classes and object instances that make up an application. However, these patterns are simply that: best practices given a name, with a description of what the pattern does, where to apply it, the problems it addresses, and so forth. Patterns are formalized best practices that you must implement yourself in your application.
The Spring Framework Inversion of Control (IoC) component addresses this concern by providing a formalized means of composing disparate components into a fully working application ready for use. The Spring Framework codifies formalized design patterns as first-class objects that you can integrate into your own application(s). Numerous organizations and institutions use the Spring Framework in this manner to engineer robust, maintainable applications.
The Spring Framework consists of features organized into about 20 modules. These modules are grouped into Core Container, Data Access/Integration, Web, AOP (Aspect Oriented Programming), Instrumentation, and Test, as shown in the following diagram.

Overview of the Spring Framework
The Core Container consists of the Core, Beans, Context, and Expression Language modules.
The Core and
Beans modules provide the fundamental parts of the
framework, including the IoC and Dependency Injection features. The
BeanFactory is a sophisticated implementation of
the factory pattern. It removes the need for programmatic singletons and
allows you to decouple the configuration and specification of
dependencies from your actual program logic.
The Context
module builds on the solid base provided by the Core and Beans
modules: it is a means to access objects in a framework-style manner
that is similar to a JNDI registry. The Context module inherits its
features from the Beans module and adds support for internationalization
(using, for example, resource bundles), event-propagation,
resource-loading, and the transparent creation of contexts by, for
example, a servlet container. The Context module also supports Java EE
features such as EJB, JMX ,and basic remoting. The
ApplicationContext interface is the focal point
of the Context module.
The Expression Language module provides a powerful expression language for querying and manipulating an object graph at runtime. It is an extension of the unified expression language (unified EL) as specified in the JSP 2.1 specification. The language supports setting and getting property values, property assignment, method invocation, accessing the context of arrays, collections and indexers, logical and arithmetic operators, named variables, and retrieval of objects by name from Spring's IoC container. It also supports list projection and selection as well as common list aggregations.
The Data Access/Integration layer consists of the JDBC, ORM, OXM, JMS and Transaction modules.
The JDBC module provides a JDBC-abstraction layer that removes the need to do tedious JDBC coding and parsing of database-vendor specific error codes.
The ORM module provides integration layers for popular object-relational mapping APIs, including JPA, JDO, Hibernate, and iBatis. Using the ORM package you can use all of these O/R-mapping frameworks in combination with all of the other features Spring offers, such as the simple declarative transaction management feature mentioned previously.
The OXM module provides an abstraction layer that supports Object/XML mapping implementations for JAXB, Castor, XMLBeans, JiBX and XStream.
The Java Messaging Service (JMS) module contains features for producing and consuming messages.
The Transaction module supports programmatic and declarative transaction management for classes that implement special interfaces and for all your POJOs (plain old Java objects).
The Web layer consists of the Web, Web-Servlet, Web-Struts, and Web-Portlet modules.
Spring's Web module provides basic web-oriented integration features such as multipart file-upload functionality and the initialization of the IoC container using servlet listeners and a web-oriented application context. It also contains the web-related parts of Spring's remoting support.
The Web-Servlet module contains Spring's model-view-controller (MVC) implementation for web applications. Spring's MVC framework provides a clean separation between domain model code and web forms, and integrates with all the other features of the Spring Framework.
The Web-Struts module contains the support classes for integrating a classic Struts web tier within a Spring application. Note that this support is now deprecated as of Spring 3.0. Consider migrating your application to Struts 2.0 and its Spring integration or to a Spring MVC solution.
The Web-Portlet module provides the MVC implementation to be used in a portlet environment and mirrors the functionality of Web-Servlet module.
Spring's AOP module provides an AOP Alliance-compliant aspect-oriented programming implementation allowing you to define, for example, method-interceptors and pointcuts to cleanly decouple code that implements functionality that should be separated. Using source-level metadata functionality, you can also incorporate behavioral information into your code, in a manner similar to that of .NET attributes.
The separate Aspects module provides integration with AspectJ.
The Instrumentation module provides class instrumentation support and classloader implementations to be used in certain application servers.
The building blocks described previously make Spring a logical choice in many scenarios, from applets to full-fledged enterprise applications that use Spring's transaction management functionality and web framework integration.

Typical full-fledged Spring web application
Spring's declarative
transaction management features make the web application fully
transactional, just as it would be if you used EJB container-managed
transactions. All your custom business logic can be implemented with
simple POJOs and managed by Spring's IoC container. Additional services
include support for sending email and validation that is independent of
the web layer, which lets you choose where to execute validation rules.
Spring's ORM support is integrated with JPA, Hibernate, JDO and iBatis;
for example, when using Hibernate, you can continue to use your existing
mapping files and standard Hibernate
SessionFactory configuration. Form
controllers seamlessly integrate the web-layer with the domain model,
removing the need for ActionForms or other classes
that transform HTTP parameters to values for your domain model.

Spring middle-tier using a third-party web framework
Sometimes circumstances do not allow you to completely switch to a
different framework. The Spring Framework does not
force you to use everything within it; it is not an
all-or-nothing solution. Existing front-ends built
with WebWork, Struts, Tapestry, or other UI frameworks can be integrated
with a Spring-based middle-tier, which allows you to use Spring
transaction features. You simply need to wire up your business logic using
an ApplicationContext and use a
WebApplicationContext to integrate your web
layer.

Remoting usage scenario
When you need to access existing code through web services, you can
use Spring's Hessian-, Burlap-,
Rmi- or JaxRpcProxyFactory
classes. Enabling remote access to existing applications is not
difficult.

EJBs - Wrapping existing POJOs
The Spring Framework also provides an access and abstraction layer for Enterprise JavaBeans, enabling you to reuse your existing POJOs and wrap them in stateless session beans for use in scalable, fail-safe web applications that might need declarative security.
Dependency management and dependency injection are different
things. To get those nice features of Spring into your application (like
dependency injection) you need to assemble all the libraries needed (jar
files) and get them onto your classpath at runtime, and possibly at
compile time. These dependencies are not virtual components that are
injected, but physical resources in a file system (typically). The
process of dependency management involves locating those resources,
storing them and adding them to classpaths. Dependencies can be direct
(e.g. my application depends on Spring at runtime), or indirect (e.g. my
application depends on commons-dbcp which depends on
commons-pool). The indirect dependencies are also known as
"transitive" and it is those dependencies that are hardest to identify
and manage.
If you are going to use Spring you need to get a copy of the jar
libraries that comprise the pieces of Spring that you need. To make this
easier Spring is packaged as a set of modules that separate the
dependencies as much as possible, so for example if you don't want to
write a web application you don't need the spring-web modules. To refer
to Spring library modules in this guide we use a shorthand naming
convention spring-* or spring-*.jar, where "*"
represents the short name for the module (e.g. spring-core,
spring-webmvc, spring-jms, etc.). The actual
jar file name that you use may be in this form (see below) or it may
not, and normally it also has a version number in the file name (e.g.
spring-core-3.0.0.RELEASE.jar).
In general, Spring publishes its artifacts to four different places:
On the community download site http://www.springsource.org/downloads/community.
Here you find all the Spring jars bundled together into a zip file
for easy download. The names of the jars here since version 3.0
are in the form
org.springframework.*-<version>.jar.
Maven Central, which is the default repository that Maven
queries, and does not require any special configuration to use.
Many of the common libraries that Spring depends on also are
available from Maven Central and a large section of the Spring
community uses Maven for dependency management, so this is
convenient for them. The names of the jars here are in the form
spring-*-<version>.jar and the Maven groupId is
org.springframework.
The Enterprise Bundle Repository (EBR), which is run by
SpringSource and also hosts all the libraries that integrate with
Spring. Both Maven and Ivy repositories are available here for all
Spring jars and their dependencies, plus a large number of other
common libraries that people use in applications with Spring. Both
full releases and also milestones and development snapshots are
deployed here. The names of the jar files are in the same form as
the community download
(org.springframework.*-<version>.jar), and the
dependencies are also in this "long" form, with external libraries
(not from SpringSource) having the prefix
com.springsource. See the FAQ
for more information.
In a public Maven repository hosted on Amazon S3 for development snapshots and milestone releases (a copy of the final releases is also held here). The jar file names are in the same form as Maven Central, so this is a useful place to get development versions of Spring to use with other libraries depoyed in Maven Central.
So the first thing you need to decide is how to manage your dependencies: most people use an automated system like Maven or Ivy, but you can also do it manually by downloading all the jars yourself. When obtaining Spring with Maven or Ivy you have then to decide which place you'll get it from. In general, if you care about OSGi, use the EBR, since it houses OSGi compatible artifacts for all of Spring's dependencies, such as Hibernate and Freemarker. If OSGi does not matter to you, either place works, though there are some pros and cons between them. In general, pick one place or the other for your project; do not mix them. This is particularly important since EBR artifacts necessarily use a different naming convention than Maven Central artifacts.
Table 1.1. Comparison of Maven Central and SpringSource EBR Repositories
| Feature | Maven Central | EBR |
|---|---|---|
| OSGi Compatible | Not explicit | Yes |
| Number of Artifacts | Tens of thousands; all kinds | Hundreds; those that Spring integrates with |
| Consistent Naming Conventions | No | Yes |
| Naming Convention: GroupId | Varies. Newer artifacts often use domain name, e.g. org.slf4j. Older ones often just use the artifact name, e.g. log4j. | Domain name of origin or main package root, e.g. org.springframework |
| Naming Convention: ArtifactId | Varies. Generally the project or module name, using a hyphen "-" separator, e.g. spring-core, logj4. | Bundle Symbolic Name, derived from the main package root, e.g. org.springframework.beans. If the jar had to be patched to ensure OSGi compliance then com.springsource is appended, e.g. com.springsource.org.apache.log4j |
| Naming Convention: Version | Varies. Many new artifacts use m.m.m or m.m.m.X (with m=digit, X=text). Older ones use m.m. Some neither. Ordering is defined but not often relied on, so not strictly reliable. | OSGi version number m.m.m.X, e.g. 3.0.0.RC3. The text qualifier imposes alphabetic ordering on versions with the same numeric values. |
| Publishing | Usually automatic via rsync or source control updates. Project authors can upload individual jars to JIRA. | Manual (JIRA processed by SpringSource) |
| Quality Assurance | By policy. Accuracy is responsibility of authors. | Extensive for OSGi manifest, Maven POM and Ivy metadata. QA performed by Spring team. |
| Hosting | Contegix. Funded by Sonatype with several mirrors. | S3 funded by SpringSource. |
| Search Utilities | Various | http://www.springsource.com/repository |
| Integration with SpringSource Tools | Integration through STS with Maven dependency management | Extensive integration through STS with Maven, Roo, CloudFoundry |
Although Spring provides integration and support for a huge range of enterprise and other external tools, it intentionally keeps its mandatory dependencies to an absolute minimum: you shouldn't have to locate and download (even automatically) a large number of jar libraries in order to use Spring for simple use cases. For basic dependency injection there is only one mandatory external dependency, and that is for logging (see below for a more detailed description of logging options).
Next we outline the basic steps needed to configure an application that depends on Spring, first with Maven and then with Ivy. In all cases, if anything is unclear, refer to the documentation of your dependency management system, or look at some sample code - Spring itself uses Ivy to manage dependencies when it is building, and our samples mostly use Maven.
If you are using Maven for dependency management you don't even need to supply the logging dependency explicitly. For example, to create an application context and use dependency injection to configure an application, your Maven dependencies will look like this:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.0.RELEASE</version>
<scope>runtime</scope>
</dependency>
</dependencies> That's it. Note the scope can be declared as runtime if you don't need to compile against Spring APIs, which is typically the case for basic dependency injection use cases.
We used the Maven Central naming conventions in the example above, so that works with Maven Central or the SpringSource S3 Maven repository. To use the S3 Maven repository (e.g. for milestones or developer snaphots), you need to specify the repository location in your Maven configuration. For full releases:
<repositories>
<repository>
<id>com.springsource.repository.maven.release</id>
<url>http://maven.springframework.org/release/</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>For milestones:
<repositories>
<repository>
<id>com.springsource.repository.maven.milestone</id>
<url>http://maven.springframework.org/milestone/</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>And for snapshots:
<repositories>
<repository>
<id>com.springsource.repository.maven.snapshot</id>
<url>http://maven.springframework.org/snapshot/</url>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>To use the SpringSource EBR you would need to use a different naming convention for the dependencies. The names are usually easy to guess, e.g. in this case it is:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context</artifactId>
<version>3.0.0.RELEASE</version>
<scope>runtime</scope>
</dependency>
</dependencies>You also need to declare the location of the repository explicitly (only the URL is important):
<repositories>
<repository>
<id>com.springsource.repository.bundles.release</id>
<url>http://repository.springsource.com/maven/bundles/release/</url>
</repository>
</repositories>If you are managing your dependencies by hand, the URL in the repository declaration above is not browseable, but there is a user interface at http://www.springsource.com/repository that can be used to search for and download dependencies. It also has handy snippets of Maven and Ivy configuration that you can copy and paste if you are using those tools.
If you prefer to use Ivy to manage dependencies then there are similar names and configuration options.
To configure Ivy to point to the SpringSource EBR add the
following resolvers to your
ivysettings.xml:
<resolvers>
<url name="com.springsource.repository.bundles.release">
<ivy pattern="http://repository.springsource.com/ivy/bundles/release/
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact pattern="http://repository.springsource.com/ivy/bundles/release/
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<url name="com.springsource.repository.bundles.external">
<ivy pattern="http://repository.springsource.com/ivy/bundles/external/
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact pattern="http://repository.springsource.com/ivy/bundles/external/
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
</resolvers>The XML above is not valid because the lines are too long - if you copy-paste then remove the extra line endings in the middle of the url patterns.
Once Ivy is configured to look in the EBR adding a dependency is
easy. Simply pull up the details page for the bundle in question in
the repository browser and you'll find an Ivy snippet ready for you to
include in your dependencies section. For example (in
ivy.xml):
<dependency org="org.springframework"
name="org.springframework.core" rev="3.0.0.RELEASE" conf="compile->runtime"/>Logging is a very important dependency for Spring because a) it is the only mandatory external dependency, b) everyone likes to see some output from the tools they are using, and c) Spring integrates with lots of other tools all of which have also made a choice of logging dependency. One of the goals of an application developer is often to have unified logging configured in a central place for the whole application, including all external components. This is more difficult than it might have been since there are so many choices of logging framework.
The mandatory logging dependency in Spring is the Jakarta Commons
Logging API (JCL). We compile against JCL and we also make JCL
Log objects visible for classes that extend the
Spring Framework. It's important to users that all versions of Spring
use the same logging library: migration is easy because backwards
compatibility is preserved even with applications that extend Spring.
The way we do this is to make one of the modules in Spring depend
explicitly on commons-logging (the canonical implementation
of JCL), and then make all the other modules depend on that at compile
time. If you are using Maven for example, and wondering where you picked
up the dependency on commons-logging, then it is from
Spring and specifically from the central module called
spring-core.
The nice thing about commons-logging is that you
don't need anything else to make your application work. It has a runtime
discovery algorithm that looks for other logging frameworks in well
known places on the classpath and uses one that it thinks is appropriate
(or you can tell it which one if you need to). If nothing else is
available you get pretty nice looking logs just from the JDK
(java.util.logging or JUL for short). You should find that your Spring
application works and logs happily to the console out of the box in most
situations, and that's important.
Unfortunately, the runtime discovery algorithm in
commons-logging, while convenient for the end-user, is
problematic. If we could turn back the clock and start Spring now
as a new project it would use a different logging dependency. The
first choice would probably be the Simple Logging Facade for Java (SLF4J), which is also used by a lot
of other tools that people use with Spring inside their
applications.
Switching off commons-logging is easy: just make
sure it isn't on the classpath at runtime. In Maven terms you exclude
the dependency, and because of the way that the Spring dependencies
are declared, you only have to do that once.
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.0.RELEASE</version>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies> Now this application is probably broken because there is no implementation of the JCL API on the classpath, so to fix it a new one has to be provided. In the next section we show you how to provide an alternative implementation of JCL using SLF4J as an example.
SLF4J is a cleaner dependency and more efficient at runtime than
commons-logging because it uses compile-time bindings
instead of runtime discovery of the other logging frameworks it
integrates. This also means that you have to be more explicit about what
you want to happen at runtime, and declare it or configure it
accordingly. SLF4J provides bindings to many common logging frameworks,
so you can usually choose one that you already use, and bind to that for
configuration and management.
SLF4J provides bindings to many common logging frameworks,
including JCL, and it also does the reverse: bridges between other
logging frameworks and itself. So to use SLF4J with Spring you need to
replace the commons-logging dependency with the SLF4J-JCL
bridge. Once you have done that then logging calls from within Spring
will be translated into logging calls to the SLF4J API, so if other
libraries in your application use that API, then you have a single place
to configure and manage logging.
A common choice might be to bridge Spring to SLF4J, and then
provide explicit binding from SLF4J to Log4J. You need to supply 4
dependencies (and exclude the existing commons-logging):
the bridge, the SLF4J API, the binding to Log4J, and the Log4J
implementation itself. In Maven you would do that like this
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.0.RELEASE</version>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.8</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>runtime</scope>
</dependency>
</dependencies> That might seem like a lot of dependencies just to get some
logging. Well it is, but it is optional, and it
should behave better than the vanilla commons-logging with
respect to classloader issues, notably if you are in a strict container
like an OSGi platform. Allegedly there is also a performance benefit
because the bindings are at compile-time not runtime.
A more common choice amongst SLF4J users, which uses fewer steps
and generates fewer dependencies, is to bind directly to Logback. This removes the extra
binding step because Logback implements SLF4J directly, so you only need
to depend on two libaries not four (jcl-over-slf4j and
logback). If you do that you might also need to exlude the
slf4j-api dependency from other external dependencies (not Spring),
because you only want one version of that API on the classpath.
Many people use Log4j as a logging framework for configuration and management purposes. It's efficient and well-established, and in fact it's what we use at runtime when we build and test Spring. Spring also provides some utilities for configuring and initializing Log4j, so it has an optional compile-time dependency on Log4j in some modules.
To make Log4j work with the default JCL dependency
(commons-logging) all you need to do is put Log4j on the
classpath, and provide it with a configuration file
(log4j.properties or log4j.xml in the root
of the classpath). So for Maven users this is your dependency
declaration:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.0.RELEASE</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>runtime</scope>
</dependency>
</dependencies> And here's a sample log4j.properties for logging to the console:
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
log4j.category.org.springframework.beans.factory=DEBUGMany people run their Spring applications in a container that
itself provides an implementation of JCL. IBM Websphere Application
Server (WAS) is the archetype. This often causes problems, and
unfortunately there is no silver bullet solution; simply excluding
commons-logging from your application is not enough in
most situations.
To be clear about this: the problems reported are usually not
with JCL per se, or even with commons-logging: rather
they are to do with binding commons-logging to another
framework (often Log4J). This can fail because
commons-logging changed the way they do the runtime
discovery in between the older versions (1.0) found in some
containers and the modern versions that most people use now (1.1).
Spring does not use any unusual parts of the JCL API, so nothing
breaks there, but as soon as Spring or your application tries to do
any logging you can find that the bindings to Log4J are not
working.
In such cases with WAS the easiest thing to do is to invert the class loader hierarchy (IBM calls it "parent last") so that the application controls the JCL dependency, not the container. That option isn't always open, but there are plenty of other suggestions in the public domain for alternative approaches, and your mileage may vary depending on the exact version and feature set of the container.
If you have been using the Spring Framework for some time, you will be aware that Spring has undergone two major revisions: Spring 2.0, released in October 2006, and Spring 2.5, released in November 2007. It is now time for a third overhaul resulting in Spring 3.0.
The entire framework code has been revised to take advantage of Java 5 features like generics, varargs and other language improvements. We have done our best to still keep the code backwards compatible. We now have consistent use of generic Collections and Maps, consistent use of generic FactoryBeans, and also consistent resolution of bridge methods in the Spring AOP API. Generic ApplicationListeners automatically receive specific event types only. All callback interfaces such as TransactionCallback and HibernateCallback declare a generic result value now. Overall, the Spring core codebase is now freshly revised and optimized for Java 5.
Spring's TaskExecutor abstraction has been updated for close integration with Java 5's java.util.concurrent facilities. We provide first-class support for Callables and Futures now, as well as ExecutorService adapters, ThreadFactory integration, etc. This has been aligned with JSR-236 (Concurrency Utilities for Java EE 6) as far as possible. Furthermore, we provide support for asynchronous method invocations through the use of the new @Async annotation (or EJB 3.1's @Asynchronous annotation).
The Spring reference documentation has also substantially been updated to reflect all of the changes and new features for Spring 3.0. While every effort has been made to ensure that there are no errors in this documentation, some errors may nevertheless have crept in. If you do spot any typos or even more serious errors, and you can spare a few cycles during lunch, please do bring the error to the attention of the Spring team by raising an issue.
There are many excellent articles and tutorials that show how to get started with Spring 3 features. Read them at the Spring Documentation page.
The samples have been improved and updated to take advantage of the new features in Spring 3. Additionally, the samples have been moved out of the source tree into a dedicated SVN repository available at:
https://anonsvn.springframework.org/svn/spring-samples/
As such, the samples are no longer distributed alongside Spring 3 and need to be downloaded separately from the repository mentioned above. However, this documentation will continue to refer to some samples (in particular Petclinic) to illustrate various features.
![]() | Note |
|---|---|
For more information on Subversion (or in short SVN), see the project homepage at:
http://subversion.apache.org/ |
The framework modules have been revised and are now managed separately with one source-tree per module jar:
org.springframework.aop
org.springframework.beans
org.springframework.context
org.springframework.context.support
org.springframework.expression
org.springframework.instrument
org.springframework.jdbc
org.springframework.jms
org.springframework.orm
org.springframework.oxm
org.springframework.test
org.springframework.transaction
org.springframework.web
org.springframework.web.portlet
org.springframework.web.servlet
org.springframework.web.struts
We are now using a new Spring build system as known from Spring Web Flow 2.0. This gives us:
Ivy-based "Spring Build" system
consistent deployment procedure
consistent dependency management
consistent generation of OSGi manifests
This is a list of new features for Spring 3.0. We will cover these features in more detail later in this section.
Spring Expression Language
IoC enhancements/Java based bean metadata
General-purpose type conversion system and field formatting system
Object to XML mapping functionality (OXM) moved from Spring Web Services project
Comprehensive REST support
@MVC additions
Declarative model validation
Early support for Java EE 6
Embedded database support
BeanFactory interface returns typed bean instances as far as possible:
T getBean(Class<T> requiredType)
T getBean(String name, Class<T> requiredType)
Map<String, T> getBeansOfType(Class<T> type)
Spring's TaskExecutor interface now extends
java.util.concurrent.Executor:
extended AsyncTaskExecutor supports standard Callables with Futures
New Java 5 based converter API and SPI:
stateless ConversionService and Converters
superseding standard JDK PropertyEditors
Typed ApplicationListener<E>
Spring introduces an expression language which is similar to Unified EL in its syntax but offers significantly more features. The expression language can be used when defining XML and Annotation based bean definitions and also serves as the foundation for expression language support across the Spring portfolio. Details of this new functionality can be found in the chapter Spring Expression Language (SpEL).
The Spring Expression Language was created to provide the Spring community a single, well supported expression language that can be used across all the products in the Spring portfolio. Its language features are driven by the requirements of the projects in the Spring portfolio, including tooling requirements for code completion support within the Eclipse based SpringSource Tool Suite.
The following is an example of how the Expression Language can be used to configure some properties of a database setup
<bean class="mycompany.RewardsTestDatabase"> <property name="databaseName" value="#{systemProperties.databaseName}"/> <property name="keyGenerator" value="#{strategyBean.databaseKeyGenerator}"/> </bean>
This functionality is also available if you prefer to configure your components using annotations:
@Repository public class RewardsTestDatabase { @Value("#{systemProperties.databaseName}") public void setDatabaseName(String dbName) { … } @Value("#{strategyBean.databaseKeyGenerator}") public void setKeyGenerator(KeyGenerator kg) { … } }
Some core features from the JavaConfig project have been added to the Spring Framework now. This means that the following annotations are now directly supported:
@Configuration
@Bean
@DependsOn
@Primary
@Lazy
@Import
@ImportResource
@Value
Here is an example of a Java class providing basic configuration using the new JavaConfig features:
package org.example.config; @Configuration public class AppConfig { private @Value("#{jdbcProperties.url}") String jdbcUrl; private @Value("#{jdbcProperties.username}") String username; private @Value("#{jdbcProperties.password}") String password; @Bean public FooService fooService() { return new FooServiceImpl(fooRepository()); } @Bean public FooRepository fooRepository() { return new HibernateFooRepository(sessionFactory()); } @Bean public SessionFactory sessionFactory() { // wire up a session factory AnnotationSessionFactoryBean asFactoryBean = new AnnotationSessionFactoryBean(); asFactoryBean.setDataSource(dataSource()); // additional config return asFactoryBean.getObject(); } @Bean public DataSource dataSource() { return new DriverManagerDataSource(jdbcUrl, username, password); } }
To get this to work you need to add the following component scanning entry in your minimal application context XML file.
<context:component-scan base-package="org.example.config"/> <util:properties id="jdbcProperties" location="classpath:org/example/config/jdbc.properties"/>
Or you can bootstrap a @Configuration class directly using
AnnotationConfigApplicationContext:
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); FooService fooService = ctx.getBean(FooService.class); fooService.doStuff(); }
See Section 3.11.2, “Instantiating the Spring container using
AnnotationConfigApplicationContext” for full information on
AnnotationConfigApplicationContext.
@Bean annotated methods are also supported
inside Spring components. They contribute a factory bean definition to
the container. See Defining bean metadata within
components for more information
A general purpose type conversion system has been introduced. The system is currently used by SpEL for type conversion, and may also be used by a Spring Container and DataBinder when binding bean property values.
In addition, a formatter SPI has been introduced for formatting field values. This SPI provides a simpler and more robust alternative to JavaBean PropertyEditors for use in client environments such as Spring MVC.
Object to XML mapping functionality (OXM) from the Spring Web
Services project has been moved to the core Spring Framework now. The
functionality is found in the org.springframework.oxm
package. More information on the use of the OXM
module can be found in the Marshalling XML using O/X
Mappers chapter.
The most exciting new feature for the Web Tier is the support for building RESTful web services and web applications. There are also some new annotations that can be used in any web application.
Server-side support for building RESTful applications has been
provided as an extension of the existing annotation driven MVC web
framework. Client-side support is provided by the
RestTemplate class in the spirit of other
template classes such as JdbcTemplate and
JmsTemplate. Both server and client side REST
functionality make use of
HttpConverters to facilitate the
conversion between objects and their representation in HTTP requests
and responses.
The MarshallingHttpMessageConverter uses
the Object to XML mapping functionality mentioned
earlier.
Refer to the sections on MVC and the RestTemplate for more information.
A mvc namespace has been introduced that greatly simplifies Spring MVC configuration.
Additional annotations such as
@CookieValue and
@RequestHeaders have been added. See Mapping cookie values with the
@CookieValue annotation and Mapping request header attributes with
the @RequestHeader annotation for more information.
Several validation enhancements, including JSR 303 support that uses Hibernate Validator as the default provider.
We provide support for asynchronous method invocations through the use of the new @Async annotation (or EJB 3.1's @Asynchronous annotation).
JSR 303, JSF 2.0, JPA 2.0, etc
Convenient support for embedded Java database engines, including HSQL, H2, and Derby, is now provided.
This part of the reference documentation covers all of those technologies that are absolutely integral to the Spring Framework.
Foremost amongst these is the Spring Framework's Inversion of Control (IoC) container. A thorough treatment of the Spring Framework's IoC container is closely followed by comprehensive coverage of Spring's Aspect-Oriented Programming (AOP) technologies. The Spring Framework has its own AOP framework, which is conceptually easy to understand, and which successfully addresses the 80% sweet spot of AOP requirements in Java enterprise programming.
Coverage of Spring's integration with AspectJ (currently the richest - in terms of features - and certainly most mature AOP implementation in the Java enterprise space) is also provided.
Finally, the adoption of the test-driven-development (TDD) approach to software development is certainly advocated by the Spring team, and so coverage of Spring's support for integration testing is covered (alongside best practices for unit testing). The Spring team has found that the correct use of IoC certainly does make both unit and integration testing easier (in that the presence of setter methods and appropriate constructors on classes makes them easier to wire together in a test without having to set up service locator registries and suchlike)... the chapter dedicated solely to testing will hopefully convince you of this as well.
This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) [1]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 interface provides an advanced
configuration mechanism capable of managing any type of object.
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 application-layer specific
contexts such as the WebApplicationContext
for use in web applications.
In short, the BeanFactory provides the
configuration framework and basic functionality, and the
ApplicationContext adds more
enterprise-specific functionality. The
ApplicationContext is a complete superset
of the BeanFactory, and is used exclusively
in this chapter in descriptions of Spring's IoC container.
For
more information on using the BeanFactory instead
of the ApplicationContext, refer to Section 3.14, “The BeanFactory”.
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container 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 among them, are reflected in the configuration metadata used by a container.
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 is
represented in XML, Java annotations, or Java code. It allows you to
express the objects that compose your application and the rich
interdependencies between such objects.
Several implementations of the
ApplicationContext interface are supplied
out-of-the-box with Spring. In standalone applications it is common to
create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext.
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 these additional
metadata formats.
In most 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 Section 3.13.4, “Convenient ApplicationContext
instantiation for web applications”).
If you are using the SpringSource Tool Suite Eclipse-powered development environment
or Spring Roo this
boilerplate configuration can be easily created with few mouse clicks or
keystrokes.
The following diagram is a high-level view of how Spring works. Your
application classes are combined with configuration metadata so that after
the ApplicationContext is created and initialized,
you have a fully configured and executable system or application.

The Spring IoC container
As the preceding diagram shows, the Spring IoC container consumes a form of configuration metadata; this configuration metadata represents how you as an application developer tell the Spring container to instantiate, configure, and assemble the objects in your application.
Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is what most of this chapter uses to convey key concepts and features of the Spring IoC container.
![]() | Note |
|---|---|
XML-based metadata is not the only allowed form of configuration metadata. The Spring IoC container itself is totally decoupled from the format in which this configuration metadata is actually written. |
For information about using other forms of metadata with the Spring container, see:
Annotation-based configuration: Spring 2.5 introduced support for annotation-based configuration metadata.
Java-based configuration:
Starting with Spring 3.0, many features provided by the Spring JavaConfig
project became part of the core Spring Framework. Thus you
can define beans external to your application classes by using Java
rather than XML files. To use these new features, see the
@Configuration, @Bean,
@Import and
@DependsOn annotations.
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.
These bean definitions correspond to the actual objects that make up
your application. Typically you define service layer objects, data
access objects (DAOs), presentation objects such as Struts
Action instances, infrastructure objects
such as Hibernate SessionFactories, JMS
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 and
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.
The following example shows the basic structure of XML-based configuration metadata:
<?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="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- 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 refers to collaborating
objects. The XML for referring to collaborating objects is not shown in
this example; see Dependencies
for more information.
Instantiating a Spring IoC container is straightforward. 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, and so on.
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});![]() | Note |
|---|---|
After you learn about Spring's IoC container, you may want to know
more about Spring's |
The following example shows the service layer objects
(services.xml) configuration file:
<?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>
The following example shows the data access objects
daos.xml file:
<?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 the preceding example, the service layer consists of the class
PetStoreServiceImpl, and two data access objects
of the type SqlMapAccountDao and SqlMapItemDao
are based on the iBatis
Object/Relational mapping framework. The property
name element refers to the name of the 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. For details of configuring an
object's dependencies, see Dependencies.
It can be useful to have bean definitions span multiple XML files. Often each individual XML configuration file represents a logical layer or module in your architecture.
You can use the application context constructor to load bean
definitions from all these XML fragments. This constructor takes
multiple Resource locations, as was
shown in the previous section. Alternatively, use one or more
occurrences of the <import/> element to load
bean definitions from another file or files. For example:
<beans> <import resource="services.xml"/> <import resource="resources/messageSource.xml"/> <import resource="/resources/themeSource.xml"/> <bean id="bean1" class="..."/> <bean id="bean2" class="..."/> </beans>
In the preceding example, external bean definitions are loaded
from three files, services.xml,
messageSource.xml, and
themeSource.xml. All location paths are relative to
the definition file doing the importing, so
services.xml must be in the same directory or
classpath location as the file doing the importing, while
messageSource.xml and
themeSource.xml must be in a
resources location below the location of the
importing file. As you can see, a leading slash is ignored, but given
that these paths are relative, it is better form not to use the slash
at all. The contents of the files being imported, including the top
level <beans/> element, must be valid XML
bean definitions according to the Spring Schema or DTD.
![]() | Note |
|---|---|
It is possible, but not recommended, to reference files in parent directories using a relative "../" path. Doing so creates a dependency on a file that is outside the current application. In particular, this reference is not recommended for "classpath:" URLs (for example, "classpath:../services.xml"), where the runtime resolution process chooses the "nearest" classpath root and then looks into its parent directory. Classpath configuration changes may lead to the choice of a different, incorrect directory. You can always use fully qualified resource locations instead of relative paths: for example, "file:C:/config/services.xml" or "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 "${...}" placeholders that are resolved against JVM system properties at runtime. |
The ApplicationContext is 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 follows:
// 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();
You use getBean() to retrieve instances of
your beans. The ApplicationContext
interface has 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.
A Spring IoC container manages one or more beans.
These beans are created with the configuration metadata that you supply to
the container, for example, in the form of XML
<bean/> definitions.
Within the container itself, these bean definitions are represented as
BeanDefinition objects, which contain
(among other information) the following metadata:
A package-qualified class name: typically the actual implementation class of the bean being defined.
Bean behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth).
References to other beans that are needed for the bean to do its work; these references are also called collaborators or dependencies.
Other configuration settings to set in the newly created object, for example, the number of connections to use in a bean that manages a connection pool, or the size limit of the pool.
This metadata translates to a set of properties that make up each bean definition.
Table 3.1. The bean definition
| Property | Explained in... |
|---|---|
| class | |
| name | |
| scope | |
| constructor arguments | |
| properties | |
| autowiring mode | |
| lazy-initialization mode | |
| initialization method | |
| destruction method |
In addition to bean definitions that contain information on how to
create a specific bean, the
ApplicationContext implementations also
permit the registration of existing objects that are created outside the
container, by users. This is done by accessing the ApplicationContext's
BeanFactory via the method getBeanFactory() which
returns the BeanFactory implementation
DefaultListableBeanFactory.
DefaultListableBeanFactory supports this
registration through the methods
registerSingleton(..) and
registerBeanDefinition(..). However, typical
applications work solely with beans defined through metadata bean
definitions.
Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. A bean usually has only one identifier, but if it requires more than one, the extra ones can be considered aliases.
In XML-based configuration metadata, you use the
id and/or name attributes to
specify the bean identifier(s). The id attribute
allows you to specify exactly one id, and because it is a real XML
element ID attribute, the XML parser can do some extra validation when
other elements reference the id. As such, it is the preferred way to
specify a bean identifier. However, the XML specification does limit the
characters that are legal in XML ids. This is usually not a constraint,
but if you need to use one of these special XML characters, or want to
introduce other aliases to the bean, you can also specify them in the
name attribute, separated by a comma
(,), semicolon (;), or white
space.
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 Service Location style lookup,
you must provide a name. Motivations for not supplying a name are
related to using inner beans
and autowiring
collaborators.
In a bean definition itself, you can supply more than one name for
the bean, by using a combination of up to one name specified by the
id attribute, and any number of other names in the
name attribute. These names can be equivalent
aliases to the same bean, and are useful for some situations, such as
allowing each component in an application to refer to a common
dependency by using a bean name that is specific to that component
itself.
Specifying all aliases where the bean is actually defined is not
always adequate, however. It is sometimes desirable to introduce an
alias for a bean that is defined elsewhere. This is commonly the case
in large systems where configuration is split amongst each subsystem,
each subsystem having its own set of object definitions. In XML-based
configuration metadata, you can use the
<alias/> element to accomplish this.
<alias name="fromName" alias="toName"/>
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 the name 'subsystemB-dataSource'. When composing the main application that uses both these subsystems the main application refers to the DataSource via the name 'myApp-dataSource'. To have all three names refer to the same object you add to the MyApp configuration metadata the following aliases definitions:
<alias name="subsystemA-dataSource" alias="subsystemB-dataSource"/> <alias name="subsystemA-dataSource" alias="myApp-dataSource" />
Now each component and the main application can refer to the dataSource through a name that is unique and guaranteed not to clash with any other definition (effectively creating a namespace), yet they refer to the same bean.
A bean definition essentially is a recipe for creating one or more objects. The container looks at the recipe for a named bean when asked, and uses the configuration metadata encapsulated by that bean definition to create (or acquire) an actual object.
If you use XML-based configuration metadata, you specify the type
(or class) of object that is to be instantiated in the
class attribute of the
<bean/> element. This class
attribute, which internally is a Class property
on a BeanDefinition instance, is usually
mandatory. (For exceptions, see Section 3.3.2.3, “Instantiation using an instance factory method” and Section 3.7, “Bean definition inheritance”.) You use the
Class property in one of two ways:
Typically, to specify the bean class to be constructed in the
case where the container itself directly creates the bean by calling
its constructor reflectively, somewhat equivalent to Java code using
the new operator.
To specify the actual class containing the
static factory method that will be invoked to
create the object, in the less common case where the container
invokes a static, factory
method on a class to create the bean. The object type returned from
the invocation of the static factory method may
be the same class or another class entirely.
When you create a bean by the constructor approach, all normal 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 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 limited to managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-argument) constructor and appropriate setters and getters modeled after the properties in the container. You can also have more exotic non-bean-style classes in your container. If, for example, you need to use a legacy connection pool that absolutely does not adhere to the JavaBean specification, Spring can manage it as well.
With XML-based configuration metadata you can specify your bean class as follows:
<bean id="exampleBean" class="examples.ExampleBean"/> <bean name="anotherExample" class="examples.ExampleBeanTwo"/>
For details about the mechanism for supplying arguments to the constructor (if required) and setting object instance properties after the object is constructed, see Injecting Dependencies.
When defining a bean that you create with a static factory method,
you use the class attribute to specify the class
containing the static factory method and an
attribute named factory-method to specify the name
of the factory method itself. You should be able to call this method
(with optional arguments as described later) and return a live object,
which subsequently is treated as if it had been created through a
constructor. One use for such a bean definition is to call
static factories in legacy code.
The following bean definition specifies that the bean will be
created by calling a factory-method. The definition does not specify
the type (class) of the returned object, only the class containing the
factory method. In this example, the
createInstance() method must be a
static method.
<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/>
public class ClientService { private static ClientService clientService = new ClientService(); private ClientService() {} public static ClientService createInstance() { return clientService; } }
For details about the mechanism for supplying (optional) arguments to the factory method and setting object instance properties after the object is returned from the factory, see Dependencies and configuration in detail.
Similar to instantiation through a static factory
method, instantiation with an instance factory method invokes a
non-static method of an existing bean from the container to create a
new bean. To use this mechanism, leave the class
attribute empty, and in the factory-bean
attribute, specify the name of a bean in the current (or
parent/ancestor) container that contains the instance method that is
to be invoked to create the object. Set the name of the factory method
itself with the factory-method attribute.
<!-- the factory bean, which contains a method called createInstance() --> <bean id="serviceLocator" class="examples.DefaultServiceLocator"> <!-- inject any dependencies required by this locator bean --> </bean> <!-- the bean to be created via the factory bean --> <bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>
public class DefaultServiceLocator { private static ClientService clientService = new ClientServiceImpl(); private DefaultServiceLocator() {} public ClientService createClientServiceInstance() { return clientService; } }
One factory class can also hold more than one factory method as shown here:
<bean id="serviceLocator" class="examples.DefaultServiceLocator"> <!-- inject any dependencies required by this locator bean --> </bean> <bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/> <bean id="accountService" factory-bean="serviceLocator" factory-method="createAccountServiceInstance"/>
public class DefaultServiceLocator { private static ClientService clientService = new ClientServiceImpl(); private static AccountService accountService = new AccountServiceImpl(); private DefaultServiceLocator() {} public ClientService createClientServiceInstance() { return clientService; } public AccountService createAccountServiceInstance() { return accountService; } }
This approach shows that the factory bean itself can be managed and configured through dependency injection (DI). See Dependencies and configuration in detail.
![]() | Note |
|---|---|
In Spring documentation, factory bean
refers to a bean that is configured in the Spring container that
will create objects through an instance or static
factory method. By contrast,
|
A typical enterprise application does not consist of a single object (or bean in the Spring parlance). Even the simplest application has a few objects that work together to present what the end-user sees as a coherent application. This next section explains how you go from defining a number of bean definitions that stand alone to a fully realized application where objects collaborate to achieve a goal.
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 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 on its own by using direct construction of classes, or the Service Locator pattern.
Code is cleaner with the DI principle and decoupling is more effective when objects are provided with their dependencies. The object does not look up its dependencies, and does not know the location or class of the dependencies. As such, your classes become easier to test, in particular when the dependencies are on interfaces or abstract base classes, which allow for stub or mock implementations to be used in unit tests.
DI exists in two major variants, Constructor-based dependency injection and Setter-based dependency injection.
Constructor-based DI is accomplished by the
container invoking a constructor with a number of arguments, each
representing a dependency. Calling a static factory
method with specific arguments to construct the bean is nearly
equivalent, and this discussion treats arguments to a constructor and to
a static factory method similarly. The following
example shows a class that can only be dependency-injected with
constructor injection. Notice that there is nothing
special about this class, it is a POJO that has no
dependencies on container specific interfaces, base classes or
annotations.
public class SimpleMovieLister { // the SimpleMovieLister has a dependency on a MovieFinder private MovieFinder movieFinder; // a constructor so that the Spring container can 'inject' a MovieFinder public SimpleMovieLister(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // business logic that actually 'uses' the injected MovieFinder is omitted... }
Constructor argument resolution matching occurs using the argument's type. If no potential ambiguity exists in the constructor arguments of a bean definition, then the order in which the constructor arguments are defined in a bean definition is the order in which those arguments are supplied to the appropriate constructor when the bean is being instantiated. Consider the following class:
package x.y; public class Foo { public Foo(Bar bar, Baz baz) { // ... } }
No potential ambiguity exists, assuming that
Bar and Baz classes are
not related by inheritance. Thus the following configuration works
fine, and you do not need to specify the constructor argument indexes
and/or types explicitly in the
<constructor-arg/> element.
<beans> <bean id="foo" class="x.y.Foo"> <constructor-arg ref="bar"/> <constructor-arg ref="baz"/> </bean> <bean id="bar" class="x.y.Bar"/> <bean id="baz" class="x.y.Baz"/> </beans>
When another bean is referenced, the type is known, and matching
can occur (as was the case with the preceding example). When a simple
type is used, such as
<value>true<value>, Spring cannot
determine the type of the value, and so cannot match by type without
help. Consider the following class:
package examples; public class ExampleBean { // No. of years to the calculate the Ultimate Answer private int years; // The Answer to Life, the Universe, and Everything private String ultimateAnswer; public ExampleBean(int years, String ultimateAnswer) { this.years = years; this.ultimateAnswer = ultimateAnswer; } }
In the preceding scenario, the container
can use type matching with simple types if you
explicitly specify the type of the constructor argument using the
type attribute. For example:
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg type="int" value="7500000"/> <constructor-arg type="java.lang.String" value="42"/> </bean>
Use the index attribute to specify explicitly
the index of constructor arguments. For example:
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg index="0" value="7500000"/> <constructor-arg index="1" value="42"/> </bean>
In addition to resolving the ambiguity of multiple simple values, specifying an index resolves ambiguity where a constructor has two arguments of the same type. Note that the index is 0 based.
Setter-based DI is accomplished by the
container calling setter methods on your beans after invoking a
no-argument constructor or no-argument static factory
method to instantiate your bean.
The following example shows a class that can only be dependency-injected using pure setter injection. This class is conventional Java. It is a POJO that has no dependencies on container specific interfaces, base classes or annotations.
public class SimpleMovieLister { // the SimpleMovieLister has a dependency on the MovieFinder private MovieFinder movieFinder; // a setter method so that the Spring container can 'inject' a MovieFinder public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // 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.
The container performs bean dependency resolution as follows:
The ApplicationContext is created
and initialized with configuration metadata that describes all the
beans. Configuration metadata can be specified via XML, Java code or
annotations.
For each bean, its dependencies are expressed in the form of properties, constructor arguments, or arguments to the static-factory method if you are using that instead of a normal constructor. These dependencies are provided to the bean, when the bean is actually created.
Each property or constructor argument is an actual definition of the value to set, or a reference to another bean in the container.
Each property or constructor argument which is a value is
converted from its specified format to the actual type of that
property or constructor argument. By default Spring can convert a
value supplied in string format to all built-in types, such as
int, long,
String, boolean, etc.
The Spring container validates the configuration of each bean as the container is created, including the validation of whether bean reference properties refer to valid beans. However, the bean properties themselves are not set until the bean is actually created. Beans that are singleton-scoped and set to be pre-instantiated (the default) are created when the container is created. Scopes are defined in Section 3.5, “Bean scopes” Otherwise, the bean is created only when it is requested. Creation of a bean potentially causes a graph of beans to be created, as the bean's dependencies and its dependencies' dependencies (and so on) are created and assigned.
You can generally trust Spring to do the right thing. It detects
configuration problems, such as references to non-existent beans and
circular dependencies, at container load-time. Spring sets properties
and resolves dependencies as late as possible, when the bean is actually
created. This means that a Spring container which has loaded correctly
can later generate an exception when you request an object if there is a
problem creating that object or one of its dependencies. For example,
the bean throws an exception as a result of a missing or invalid
property. This potentially delayed visibility of some configuration
issues is why ApplicationContext
implementations by default pre-instantiate singleton beans. At the cost
of some upfront time and memory to create these beans before they are
actually needed, you discover configuration issues when the
ApplicationContext is created, not later.
You can still override this default behavior so that singleton beans
will lazy-initialize, rather than be pre-instantiated.
If no circular dependencies exist, when one or more collaborating beans are being injected into a dependent bean, each collaborating bean is totally configured prior to being injected into the dependent bean. This means that if bean A has a dependency on bean B, the Spring IoC container completely configures bean B prior to invoking the setter method on bean A. In other words, the bean is instantiated (if not a pre-instantiated singleton), its dependencies are set, and the relevant lifecycle methods (such as a configured init method or the IntializingBean callback method) are invoked.
The following example uses XML-based configuration metadata for setter-based DI. A small part of a Spring XML configuration file specifies some bean definitions:
<bean id="exampleBean" class="examples.ExampleBean"> <!-- setter injection using the nested <ref/> element --> <property name="beanOne"><ref bean="anotherExampleBean"/></property> <!-- setter injection using the neater 'ref' attribute --> <property name="beanTwo" ref="yetAnotherBean"/> <property name="integerProperty" value="1"/> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
public class ExampleBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public void setBeanOne(AnotherBean beanOne) { this.beanOne = beanOne; } public void setBeanTwo(YetAnotherBean beanTwo) { this.beanTwo = beanTwo; } public void setIntegerProperty(int i) { this.i = i; } }
In the preceding example, setters are declared to match against the properties specified in the XML file. The following example uses constructor-based DI:
<bean id="exampleBean" class="examples.ExampleBean"> <!-- constructor injection using the nested <ref/> element --> <constructor-arg> <ref bean="anotherExampleBean"/> </constructor-arg> <!-- constructor injection using the neater 'ref' attribute --> <constructor-arg ref="yetAnotherBean"/> <constructor-arg type="int" value="1"/> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
public class ExampleBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public ExampleBean( AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { this.beanOne = anotherBean; this.beanTwo = yetAnotherBean; this.i = i; } }
The constructor arguments specified in the bean definition will be
used as arguments to the constructor of the
ExampleBean.
Now consider a variant of this example, where instead of using a
constructor, Spring is told to call a static factory
method to return an instance of the object:
<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance"> <constructor-arg ref="anotherExampleBean"/> <constructor-arg ref="yetAnotherBean"/> <constructor-arg value="1"/> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
public class ExampleBean { // a private constructor private ExampleBean(...) { ... } // a static factory method; the arguments to this method can be // considered the dependencies of the bean that is returned, // regardless of how those arguments are actually used. public static ExampleBean createInstance ( AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { ExampleBean eb = new ExampleBean (...); // some other operations... return eb; } }
Arguments to the static factory method are
supplied via <constructor-arg/> elements,
exactly the same as if a constructor had actually been used. The type of
the class being returned by the factory method does not have to be of
the same type as the class that contains the static
factory method, although in this example it is. An instance (non-static)
factory method would be used in an essentially identical fashion (aside
from the use of the factory-bean attribute instead of
the class attribute), so details will not be
discussed here.
As mentioned in the previous section, you can define bean properties
and constructor arguments as references to other managed beans
(collaborators), or as values defined inline. Spring's XML-based
configuration metadata supports sub-element types within its
<property/> and
<constructor-arg/> elements for this
purpose.
The value attribute of the
<property/> element specifies a property or
constructor argument as a human-readable string representation. As mentioned previously,
JavaBeans PropertyEditors are used to convert these
string values from a String to the actual type of
the property or argument.
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!-- results in a setDriverClassName(String) call --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydb"/> <property name="username" value="root"/> <property name="password" value="masterkaoli"/> </bean>
The following example uses the p-namespace for even more succinct XML configuration.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/mydb" p:username="root" p:password="masterkaoli"/> </beans>
The preceding XML is more succinct; however, typos are discovered at runtime rather than design time, unless you use an IDE such as IntelliJ IDEA or the SpringSource Tool Suite (STS) that support automatic property completion when you create bean definitions. Such IDE assistance is highly recommended.
You can also configure a java.util.Properties
instance as:
<bean id="mappings" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <!-- typed as a java.util.Properties --> <property name="properties"> <value> jdbc.driver.className=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mydb </value> </property> </bean>
The Spring container converts the text inside the
<value/> element into a
java.util.Properties instance by using the
JavaBeans PropertyEditor mechanism. This
is a nice shortcut, and is one of a few places where the Spring team do
favor the use of the nested <value/> element
over the value attribute style.
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
<constructor-arg/> or
<property/> element.
<bean id="theTargetBean" class="..."/> <bean id="theClientBean" class="..."> <property name="targetName"> <idref bean="theTargetBean" /> </property> </bean>
The above bean definition snippet is exactly equivalent (at runtime) to the following snippet:
<bean id="theTargetBean" class="..." /> <bean id="client" class="..."> <property name="targetName" value="theTargetBean" /> </bean>
The first form is preferable to the second, because using the
idref tag allows the container to validate
at deployment time that the referenced, named
bean actually exists. In the second variation, no validation is
performed on the value that is passed to the
targetName property of the
client bean. Typos are only discovered (with most
likely fatal results) when the client bean is
actually instantiated. If the client bean is a
prototype bean, this typo
and the resulting exception may only be discovered long after the
container is deployed.
Additionally, if the referenced bean is in the same XML unit, and
the bean name is the bean id, you can use the
local attribute, which allows the XML parser itself
to validate the bean id earlier, at XML document parse time.
<property name="targetName"> <!-- a bean with id 'theTargetBean' must exist; otherwise an exception will be thrown --> <idref local="theTargetBean"/> </property>
A common place (at least in versions earlier than Spring 2.0)
where the <idref/> element brings value is in the configuration
of AOP interceptors in a
ProxyFactoryBean bean definition. Using
<idref/> elements when you specify the interceptor names
prevents you from misspelling an interceptor id.
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 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 references are ultimately a reference to another object.
Scoping and validation depend on whether you specify the id/name of the
other object through the
bean, or
local,parent attributes.
Specifying the target bean through the bean
attribute of the <ref/> tag is the most general
form, and allows creation of a reference to any bean in the same
container or parent container, regardless of whether it is in the same
XML file. The value of the bean attribute may be the
same as the id attribute of the target bean, or as
one of the values in the name attribute of the target
bean.
<ref bean="someBean"/>
Specifying the target bean through the local
attribute leverages the ability of the XML parser to validate XML id
references within the same file. The value of the
local attribute must be the same as the
id attribute of the target bean. The XML parser
issues an error if no matching element is found in the same file. As
such, using the local variant is the best choice (in order to know about
errors as early as possible) if the target bean is in the same XML
file.
<ref local="someBean"/>
Specifying the target bean through the parent
attribute creates a reference to a bean that is in a parent container of
the current container. The value of the parent
attribute may be the same as either the id attribute
of the target bean, or one of the values in the name
attribute of the target bean, and the target bean must be in a parent
container of the current one. You use this bean reference variant mainly
when you have a hierarchy of containers and you want to wrap an existing
bean in a parent container with a proxy that will have the same name as
the parent bean.
<!-- in the parent context --> <bean id="accountService" class="com.foo.SimpleAccountService"> <!-- insert dependencies as required as here --> </bean>
<!-- in the child (descendant) context --> <bean id="accountService" <-- bean name is the same as the parent bean --> class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref parent="accountService"/> <!-- notice how we refer to the parent bean --> </property> <!-- insert other configuration and dependencies as required here --> </bean>
A <bean/> element inside the
<property/> or
<constructor-arg/> elements defines a so-called
inner bean.
<bean id="outer" class="..."> <!-- instead of using a reference to a target bean, simply define the target bean inline --> <property name="target"> <bean class="com.example.Person"> <!-- this is the inner bean --> <property name="name" value="Fiona Apple"/> <property name="age" value="25"/> </bean> </property> </bean>
An inner bean definition does not require a defined id or name; the
container ignores these values. It also ignores the
scope flag. Inner beans are
always anonymous and they are
always scoped as prototypes. It is
not possible to inject inner beans into
collaborating beans other than into the enclosing bean.
In the <list/>,
<set/>, <map/>, and
<props/> elements, you set the properties and
arguments of the Java Collection types
List, Set,
Map, and
Properties, respectively.
<bean id="moreComplexObject" class="example.ComplexObject"> <!-- results in a setAdminEmails(java.util.Properties) call --> <property name="adminEmails"> <props> <prop key="administrator">administrator@example.org</prop> <prop key="support">support@example.org</prop> <prop key="development">development@example.org</prop> </props> </property> <!-- results in a setSomeList(java.util.List) call --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> <!-- results in a setSomeMap(java.util.Map) call --> <property name="someMap"> <map> <entry key="an entry" value="just some string"/> <entry key ="a ref" value-ref="myDataSource"/> </map> </property> <!-- results in a setSomeSet(java.util.Set) call --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property> </bean>
The value of a map key or value, or a set value, can also again be any of the following elements:
bean | ref | idref | list | set | map | props | value | null
As of Spring 2.0, the container supports the
merging of collections. An application developer
can define a parent-style <list/>,
<map/>, <set/> or
<props/> element, and have child-style
<list/>, <map/>,
<set/> or <props/>
elements inherit and override values from the parent collection. That
is, the child collection's values are the result of merging the
elements of the parent and child collections, with the child's
collection elements overriding values specified in the parent
collection.
This section on merging discusses the parent-child bean mechanism. Readers unfamiliar with parent and child bean definitions may wish to read the relevant section before continuing.
The following example demonstrates collection merging:
<beans> <bean id="parent" abstract="true" class="example.ComplexObject"> <property name="adminEmails"> <props> <prop key="administrator">administrator@example.com</prop> <prop key="support">support@example.com</prop> </props> </property> </bean> <bean id="child" parent="parent"> <property name="adminEmails"> <!-- the merge is specified on the *child* collection definition --> <props merge="true"> <prop key="sales">sales@example.com</prop> <prop key="support">support@example.co.uk</prop> </props> </property> </bean> <beans>
Notice the use of the merge=true attribute on
the <props/> element of the
adminEmails property of the
child bean definition. When the
child bean is resolved and instantiated by the
container, the resulting instance has an
adminEmails Properties
collection that contains the result of the merging of the child's
adminEmails collection with the parent's
adminEmails collection.
administrator=administrator@example.com sales=sales@example.com support=support@example.co.uk
The child Properties collection's value set
inherits all property elements from the parent
<props/>, and the child's value for the
support value overrides the value in the parent
collection.
This merging behavior applies similarly to the
<list/>, <map/>, and
<set/> collection types. In the specific case
of the <list/> element, the semantics
associated with the List collection type, that
is, the notion of an ordered collection of values,
is maintained; the parent's values precede all of the child list's
values. In the case of the Map,
Set, and
Properties collection types, no
ordering exists. Hence no ordering semantics are in effect for the
collection types that underlie the associated
Map,
Set, and
Properties implementation types that
the container uses internally.
You cannot merge different collection types (such as a
Map and a
List), and if you do attempt to do so
an appropriate Exception is thrown. The
merge attribute must be specified on the lower,
inherited, child definition; specifying the merge
attribute on a parent collection definition is redundant and will not
result in the desired merging. The merging feature is available only
in Spring 2.0 and later.
In Java 5 and later, you can use strongly typed collections (using
generic types). That is, it is possible to declare a
Collection type such that it can only
contain String elements (for example). If you
are using Spring to dependency-inject a strongly-typed
Collection into a bean, you can take
advantage of Spring's type-conversion support such that the elements
of your strongly-typed Collection
instances are converted to the appropriate type prior to being added
to the Collection.
public class Foo { private Map<String, Float> accounts; public void setAccounts(Map<String, Float> accounts) { this.accounts = accounts; } }
<beans> <bean id="foo" class="x.y.Foo"> <property name="accounts"> <map> <entry key="one" value="9.99"/> <entry key="two" value="2.75"/> <entry key="six" value="3.99"/> </map> </property> </bean> </beans>
When the accounts property of the
foo bean is prepared for injection, the generics
information about the element type of the strongly-typed
Map<String, Float> is available by
reflection. Thus Spring's type conversion infrastructure recognizes
the various value elements as being of type
Float, and the string values 9.99,
2.75, and 3.99 are converted into an
actual Float type.
Spring
treats empty arguments for properties and the like as empty
Strings. The following XML-based configuration
metadata snippet sets the email property to the empty
String value ("")
<bean class="ExampleBean"> <property name="email" value=""/> </bean>
The preceding example is equivalent to the following Java code:
exampleBean.setEmail(""). The
<null/> element handles null
values. For example:
<bean class="ExampleBean"> <property name="email"><null/></property> </bean>
The above configuration is equivalent to the following Java code:
exampleBean.setEmail(null).
The p-namespace enables you to use the bean
element's attributes, instead of nested
<property/> elements, to describe your property
values and/or collaborating beans.
Spring 2.0 and later supports extensible configuration formats with namespaces, which are based on an XML
Schema definition. The beans configuration format
discussed in this chapter is defined in an XML Schema document. However,
the p-namespace is not defined in an XSD file and exists only in the
core of Spring.
The following example shows two XML snippets that resolve to the same result: The first uses standard XML format and the second uses the p-namespace.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean name="classic" class="com.example.ExampleBean"> <property name="email" value="foo@bar.com"/> </bean> <bean name="p-namespace" class="com.example.ExampleBean" p:email="foo@bar.com"/> </beans>
The example shows an attribute in the p-namespace called email in the bean definition. This tells Spring to include a property declaration. As previously mentioned, the p-namespace does not have a schema definition, so you can set the name of the attribute to the property name.
This next example includes two more bean definitions that both have a reference to another bean:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean name="john-classic" class="com.example.Person"> <property name="name" value="John Doe"/> <property name="spouse" ref="jane"/> </bean> <bean name="john-modern" class="com.example.Person" p:name="John Doe" p:spouse-ref="jane"/> <bean name="jane" class="com.example.Person"> <property name="name" value="Jane Doe"/> </bean> </beans>
As you can see, this example includes not only a property value
using the p-namespace, but also uses a special format to declare
property references. Whereas the first bean definition uses
<property name="spouse" ref="jane"/> to create
a reference from bean john to bean
jane, the second bean definition uses
p:spouse-ref="jane" as an attribute to do the exact
same thing. In this case spouse is the property name,
whereas the -ref part indicates that this is not a
straight value but rather a reference to another bean.
![]() | Note |
|---|---|
The p-namespace is not as flexible as the standard XML format. For
example, the format for declaring property references clashes with
properties that end in |
You can use compound or nested property names when you set bean
properties, as long as all components of the path except the final
property name are not null. Consider the following
bean definition.
<bean id="foo" class="foo.Bar"> <property name="fred.bob.sammy" value="123" /> </bean>
The foo bean has a fred
property, which has a bob property, which has a
sammy property, and that final
sammy property is being set to the value
123. In order for this to work, the
fred property of foo, and the
bob property of fred must not be
null after the bean is constructed, or a
NullPointerException is thrown.
If a bean is a dependency of another that usually means that one bean
is set as a property of another. Typically you accomplish this with the
<ref/>
element in XML-based configuration metadata. However, sometimes
dependencies between beans are less direct; for example, a static
initializer in a class needs to be triggered, such as database driver
registration. The depends-on attribute can explicitly
force one or more beans to be initialized before the bean using this
element is initialized. The following example uses the
depends-on attribute to express a dependency on a
single bean:
<bean id="beanOne" class="ExampleBean" depends-on="manager"/> <bean id="manager" class="ManagerBean" />
To express a dependency on multiple beans, supply a list of bean names
as the value of the depends-on attribute, with commas,
whitespace and semicolons, used as valid delimiters:
<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao"> <property name="manager" ref="manager" /> </bean> <bean id="manager" class="ManagerBean" /> <bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />
![]() | Note |
|---|---|
The |
By default, ApplicationContext
implementations eagerly create and configure all singleton beans as part of
the initialization process. Generally, this pre-instantiation is
desirable, because errors in the configuration or surrounding environment
are discovered immediately, as opposed to hours or even days later. When
this behavior is not desirable, you can prevent
pre-instantiation of a singleton bean by marking the bean definition as
lazy-initialized. A lazy-initialized bean tells the IoC container to
create a bean instance when it is first requested, rather than at
startup.
In XML, this behavior is controlled by the
lazy-init attribute on the
<bean/> element; for example:
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/> <bean name="not.lazy" class="com.foo.AnotherBean"/>
When the preceding configuration is consumed by an
ApplicationContext, the bean named
lazy is not eagerly pre-instantiated when the
ApplicationContext is starting up, whereas
the not.lazy bean is eagerly pre-instantiated.
However, when a lazy-initialized bean is a dependency of a singleton
bean that is not lazy-initialized, the
ApplicationContext creates the
lazy-initialized bean at startup, because it must satisfy the singleton's
dependencies. The lazy-initialized bean is injected into a singleton bean
elsewhere that is not lazy-initialized.
You can also control lazy-initialization at the container level by
using the default-lazy-init attribute on the
<beans/> element; for example:
<beans default-lazy-init="true"> <!-- no beans will be pre-instantiated... --> </beans>
The Spring container can autowire relationships
between collaborating beans. You can allow Spring to resolve collaborators
(other beans) automatically for your bean by inspecting the contents of
the ApplicationContext. Autowiring has the
following advantages:
Autowiring can significantly reduce the need to specify properties or constructor arguments. (Other mechanisms such as a bean template discussed elsewhere in this chapter are also valuable in this regard.)
Autowiring can update a configuration as your objects evolve. For example, if you need to add a dependency to a class, that dependency can be satisfied automatically without you needing to modify the configuration. Thus autowiring can be especially useful during development, without negating the option of switching to explicit wiring when the code base becomes more stable.
When using XML-based configuration metadata[2], you specify autowire mode for a bean definition with the
autowire attribute of the
<bean/> element. The autowiring functionality has
five modes. You specify autowiring per bean and thus
can choose which ones to autowire.
Table 3.2. Autowiring modes
| Mode | Explanation |
|---|---|
| no | (Default) No autowiring. Bean references must be
defined via a |
| byName | Autowiring by property name. Spring looks for a bean
with the same name as the property that needs to be autowired. For
example, if a bean definition is set to autowire by name, and it
contains a master property (that is, it has a
setMaster(..) method), Spring looks for a
bean definition named |
| byType | Allows a property to be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown, which indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens; the property is not set. |
| constructor | Analogous to byType, but applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised. |
With byType or constructor
autowiring mode, you can wire arrays and typed-collections. In such cases
all autowire candidates within the container that
match the expected type are provided to satisfy the dependency. You can
autowire strongly-typed Maps if the expected key type is
String. An autowired Maps values will consist of
all bean instances that match the expected type, and the Maps keys will
contain the corresponding bean names.
You can combine autowire behavior with dependency checking, which is performed after autowiring completes.
Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing to developers to use it to wire only one or two bean definitions.
Consider the limitations and disadvantages of autowiring:
Explicit dependencies in property and
constructor-arg settings always override
autowiring. You cannot autowire so-called
simple properties such as primitives,
Strings, and Classes
(and arrays of such simple properties). This limitation is
by-design.
Autowiring is less exact than explicit wiring. Although, as noted in the above table, Spring is careful to avoid guessing in case of ambiguity that might have unexpected results, the relationships between your Spring-managed objects are no longer documented explicitly.
Wiring information may not be available to tools that may generate documentation from a Spring container.
Multiple bean definitions within the container may match the type specified by the setter method or constructor argument to be autowired. For arrays, collections, or Maps, this is not necessarily a problem. However for dependencies that expect a single value, this ambiguity is not arbitrarily resolved. If no unique bean definition is available, an exception is thrown.
In the latter scenario, you have several options:
Abandon autowiring in favor of explicit wiring.
Avoid autowiring for a bean definition by setting its
autowire-candidate attributes to
false as described in the next section.
Designate a single bean definition as the
primary candidate by setting the
primary attribute of its
<bean/> element to
true.
If you are using Java 5 or later, implement the more fine-grained control available with annotation-based configuration, as described in Section 3.9, “Annotation-based container configuration”.
On a per-bean basis, you can exclude a bean from autowiring. In
Spring's XML format, set the autowire-candidate
attribute of the <bean/> element to
false; the container makes that specific bean
definition unavailable to the autowiring infrastructure (including
annotation style configurations such as @Autowired).
You can also limit autowire candidates based on pattern-matching
against bean names. The top-level <beans/>
element accepts one or more patterns within its
default-autowire-candidates attribute. For example,
to limit autowire candidate status to any bean whose name ends with
Repository, provide a value of *Repository. To
provide multiple patterns, define them in a comma-separated list. An
explicit value of true or false
for a bean definitions autowire-candidate attribute
always takes precedence, and for such beans, the pattern matching rules
do not apply.
These techniques are useful for beans that you never want to be injected into other beans by autowiring. It does not mean that an excluded bean cannot itself be configured using autowiring. Rather, the bean itself is not a candidate for autowiring other beans.
In most application scenarios, most beans in the container are singletons. When a singleton bean needs to collaborate with another singleton bean, or a non-singleton bean needs to collaborate with another non-singleton bean, you typically handle the dependency by defining one bean as a property of the other. A problem arises when the bean lifecycles are different. Suppose singleton bean A needs to use non-singleton (prototype) bean B, perhaps on each method invocation on A. The container only creates the singleton bean A once, and thus only gets one opportunity to set the properties. The container cannot provide bean A with a new instance of bean B every time one is needed.
A solution is to forego some inversion of control. You can make bean A aware of the container by
implementing the 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 an example of this
approach:
// a class that uses a stateful Command-style class to perform some processing package fiona.apple; // Spring-API imports import org.springframework.beans.BeansException; import org.springframework.context.Applicationcontext; import org.springframework.context.ApplicationContextAware; public class CommandManager implements ApplicationContextAware { private ApplicationContext applicationContext; public Object process(Map commandState) { // grab a new instance of the appropriate Command Command command = createCommand(); // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } protected Command createCommand() { // notice the Spring API dependency! return this.applicationContext.getBean("command", Command.class); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
The preceding is not desirable, because the business code is aware of and coupled to the Spring Framework. Method Injection, a somewhat advanced feature of the Spring IoC container, allows this use case to be handled in a clean fashion.
Lookup method injection is the ability of the container to override methods on container managed beans, to return the lookup result for another named bean in the container. The lookup typically involves a prototype bean as in the scenario described in the preceding section. The Spring Framework implements this method injection by using bytecode generation from the CGLIB library to generate dynamically a subclass that overrides the method.
![]() | Note |
|---|---|
For this dynamic subclassing to work, you must have the CGLIB
jar(s) in your classpath. The class that the Spring container will
subclass cannot be |
Looking at the CommandManager class in the
previous code snippet, you see that the Spring container will
dynamically override the implementation of the
createCommand() method. Your
CommandManager class will not have any Spring
dependencies, as can be seen in the reworked example:
package fiona.apple; // no more Spring imports! public abstract class CommandManager { public Object process(Object commandState) { // grab a new instance of the appropriate Command interface Command command = createCommand(); // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } // okay... but where is the implementation of this method? protected abstract Command createCommand(); }
In the client class containing the method to be injected (the
CommandManager in this case), the method to be
injected requires a signature of the following form:
<public|protected> [abstract] <return-type> theMethodName(no-arguments);
If the method is abstract, the
dynamically-generated subclass implements the method. Otherwise, the
dynamically-generated subclass overrides the concrete method defined in
the original class. For example:
<!-- a stateful bean deployed as a prototype (non-singleton) --> <bean id="command" class="fiona.apple.AsyncCommand" scope="prototype"> <!-- inject dependencies here as required --> </bean> <!-- commandProcessor uses statefulCommandHelper --> <bean id="commandManager" class="fiona.apple.CommandManager"> <lookup-method name="createCommand" bean="command"/> </bean>
The bean identified as commandManager calls its
own method createCommand() whenever it needs a
new instance of the command bean. You must be
careful to deploy the command bean as a prototype, if
that is actually what is needed. If it is deployed as a singleton, the same
instance of the command bean is returned each
time.
![]() | Tip |
|---|---|
The interested reader may also find the
|
A less useful form of method injection than lookup method Injection is the ability to replace arbitrary methods in a managed bean with another method implementation. Users may safely skip the rest of this section until the functionality is actually needed.
With XML-based configuration metadata, you can use the
replaced-method element to replace an existing method
implementation with another, for a deployed bean. Consider the following
class, with a method computeValue, which we want to override:
public class MyValueCalculator { public String computeValue(String input) { // some real code... } // some other methods... }
A class implementing the
org.springframework.beans.factory.support.MethodReplacer
interface provides the new method definition.
/** meant to be used to override the existing computeValue(String) implementation in MyValueCalculator */ public class ReplacementComputeValue implements MethodReplacer { public Object reimplement(Object o, Method m, Object[] args) throws Throwable { // get the input value, work with it, and return a computed result String input = (String) args[0]; ... return ...; } }
The bean definition to deploy the original class and specify the method override would look like this:
<bean id="myValueCalculator" class="x.y.z.MyValueCalculator"> <!-- arbitrary method replacement --> <replaced-method name="computeValue" replacer="replacementComputeValue"> <arg-type>String</arg-type> </replaced-method> </bean> <bean id="replacementComputeValue" class="a.b.c.ReplacementComputeValue"/>
You can use one or more contained
<arg-type/> elements within the
<replaced-method/> element to indicate the
method signature of the method being overridden. The signature for the
arguments is necessary only if the method is overloaded and multiple
variants exist within the class. For convenience, the type string for an
argument may be a substring of the fully qualified type name. For
example, the following all match
java.lang.String:
java.lang.String String Str
Because the number of arguments is often enough to distinguish between each possible choice, this shortcut can save a lot of typing, by allowing you to type only the shortest string that will match an argument type.
When you create a bean definition, you create a recipe for creating actual instances of the class defined by that bean definition. The idea that a bean definition is a recipe is important, because it means that, as with a class, you can create many object instances from a single recipe.
You can control not only the various dependencies and configuration
values that are to be plugged into an object that is created from a
particular bean definition, but also the scope of the
objects created from a particular bean definition. This approach is 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 following scopes are supported out of the box. You can also create a custom scope.
Table 3.3. Bean scopes
| Scope | Description |
|---|---|
(Default) Scopes a single bean definition to a single object instance per Spring IoC container. | |
Scopes a single bean definition to any number of object instances. | |
Scopes a single bean definition to the lifecycle of a
single HTTP request; that is, each HTTP request has its own instance
of a bean created off the back of a single bean definition. Only
valid in the context of a web-aware Spring
| |
Scopes a single bean definition to the lifecycle of an
HTTP | |
Scopes a single bean definition to the lifecycle of a
global HTTP |
![]() | Thread-scoped beans |
|---|---|
As of Spring 3.0, a thread scope is available, but is not registered by default. For more information, see the documentation for SimpleThreadScope. For instructions on how to register this or any other custom scope, see Section 3.5.5.2, “Using a custom scope”. |
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, the Spring IoC container creates exactly one instance of the object defined by that bean definition. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object.

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 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"/> <!-- the following is equivalent, though redundant (singleton scope is the default) --> <bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/>
The non-singleton, prototype scope of bean deployment results in the
creation of a new bean instance every time a request
for that specific bean is made. That is, the bean is injected into another
bean or you request it through a getBean() method call
on the container. As a rule, use the prototype scope for all stateful
beans and the singleton scope for stateless beans.
The following diagram illustrates the Spring prototype scope. 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.

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"/>
In contrast to the other scopes, Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, and otherwise assembles a prototype object, and hands it to the client, with no further record of that prototype instance. Thus, although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped objects and release expensive resources that the prototype 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, 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 Section 3.6.1, “Lifecycle callbacks”.)
When you use singleton-scoped beans with dependencies on prototype beans, be aware that dependencies are resolved at instantiation time. Thus if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-injected into the singleton bean. The prototype instance is the sole instance that is ever supplied to the singleton-scoped bean.
However, suppose 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 Section 3.4.6, “Method injection”
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.
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 define your beans. (This initial setup is not
required for the standard scopes, singleton and prototype.)
How you accomplish this initial setup depends on your particular Servlet environment..
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
necessary: DispatcherServlet and
DispatcherPortlet already expose all relevant
state.
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 applications web.xml
file:
<web-app> ... <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> ... </web-app>
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> .. <filter> <filter-name>requestContextFilter</filter-name> <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> </filter> <filter-mapping> <filter-name>requestContextFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ... </web-app>
DispatcherServlet,
RequestContextListener and
RequestContextFilter all do exactly the same
thing, namely bind the HTTP request object to the
Thread that is servicing that request. This makes
beans that are request- and session-scoped available further down the
call chain.
Consider the following bean definition:
<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>
The Spring container creates a new instance of the
LoginAction bean by using the
loginAction bean definition for each and every HTTP
request. That is, the loginAction bean is scoped at
the HTTP request level. You can change the internal state of the
instance that is created as much as you want, because other instances
created from the same loginAction bean definition
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.
Consider the following bean definition:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
The Spring container creates a new instance of the
UserPreferences bean by using the
userPreferences bean definition for the lifetime of a
single HTTP Session. In other words, the
userPreferences bean is effectively scoped at the
HTTP Session level. As with
request-scoped beans, you can change the internal
state of the instance that is created as much as you want, knowing that
other HTTP Session instances that are
also using instances created from the same
userPreferences bean definition do not see these
changes in state, because they are particular to an individual HTTP
Session. When the HTTP
Session is eventually discarded, the bean
that is scoped to that particular HTTP
Session is also discarded.
Consider the following bean definition:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="globalSession"/>
The global session scope is similar to the
standard HTTP Session scope (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.
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.
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 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.
![]() | Note |
|---|---|
You do not need to use the
|
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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- an HTTP Session-scoped bean exposed as a proxy --> <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"> <!-- this next element effects the proxying of the surrounding bean --> <aop:scoped-proxy/> </bean> <!-- 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 --> <property name="userPreferences" ref="userPreferences"/> </bean> </beans>
To create such a proxy, you insert a child
<aop:scoped-proxy/> element into a scoped bean
definition.
(If
you choose class-based proxying, you also need the CGLIB library in your
classpath. See the section called “Choosing the type of proxy to create” and Appendix C, XML Schema-based configuration.) 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"/> <bean id="userManager" class="com.foo.UserManager"> <property name="userPreferences" ref="userPreferences"/> </bean>
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) 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.
Thus you need the following, correct and complete, configuration
when injecting request-, session-,
and globalSession-scoped beans into collaborating
objects:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"> <aop:scoped-proxy/> </bean> <bean id="userManager" class="com.foo.UserManager"> <property name="userPreferences" ref="userPreferences"/> </bean>
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 is created. This means that you
need to have the CGLIB library in the classpath of your
application.
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.
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 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"> <aop:scoped-proxy proxy-target-class="false"/> </bean> <bean id="userManager" class="com.foo.UserManager"> <property name="userPreferences" ref="userPreferences"/> </bean>
For more detailed information about choosing class-based or interface-based proxying, see Section 7.6, “Proxying mechanisms”.
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.
To integrate your custom scope(s) into the Spring container, you
need to implement the
org.springframework.beans.factory.config.Scope
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 and
the Scope Javadoc, which explains the methods you need to implement
in more detail.
The Scope interface has four methods to get
objects from the scope, remove them from the scope, and allow them to be
destroyed.
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 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, but you can return null if the object with the specified name is not found.
Object remove(String name)
The following method registers the callbacks the scope should execute when it is destroyed or when the specified object in the scope is destroyed. Refer to the Javadoc or a Spring scope implementation for more information on destruction callbacks.
void registerDestructionCallback(String name, Runnable destructionCallback)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()
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 following method is
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
registerScope(..) method is an actual instance
of the custom Scope implementation that
you wish to register and use.
Suppose that you write your custom
Scope implementation, and then register
it as below.
![]() | Note |
|---|---|
The example below uses |
Scope threadScope = new SimpleThreadScope(); beanFactory.registerScope("thread", threadScope);
You then create bean definitions that adhere to the scoping rules of
your custom Scope:
<bean id="..." class="..." scope="thread">
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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> <property name="scopes"> <map> <entry key="thread"> <bean class="org.springframework.context.support.SimpleThreadScope"/> </entry> </map> </property> </bean> <bean id="bar" class="x.y.Bar" scope="thread"> <property name="name" value="Rick"/> <aop:scoped-proxy/> </bean> <bean id="foo" class="x.y.Foo"> <property name="bar" ref="bar"/> </bean> </beans>
![]() | Note |
|---|---|
When you place <aop:scoped-proxy/> in a
|
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 through 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
does not offer out-of-the-box, you can implement a
BeanPostProcessor yourself. For more
information, see Section 3.8, “Container extension points”.
In addition to the initialization and destruction callbacks,
Spring-managed objects may also implement the
Lifecycle interface so that those objects
can participate in the startup and shutdown process as driven by the
container's own lifecycle.
The lifecycle callback interfaces are described in this section.
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 a
single method:
void afterPropertiesSet() throws Exception;
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"/>
public class ExampleBean { public void init() { // do some initialization work } }
...is exactly the same as...
<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements InitializingBean { public void afterPropertiesSet() { // do some initialization work } }
... but does not couple the code to Spring.
Implementing the
org.springframework.beans.factory.DisposableBean
interface allows a bean to get a callback when the container containing
it is destroyed. The DisposableBean
interface specifies a single method:
void destroy() throws Exception;
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:
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
public class ExampleBean { public void cleanup() { // do some destruction work (like releasing pooled connections) } }
...is exactly the same as...
<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements DisposableBean { public void destroy() { // do some destruction work (like releasing pooled connections) } }
... but does not couple the code to Spring.
When you write initialization and destroy method callbacks that do
not use the Spring-specific
InitializingBean and
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.
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.
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 { private BlogDao blogDao; public void setBlogDao(BlogDao blogDao) { this.blogDao = blogDao; } // this is (unsurprisingly) the initialization callback method public void init() { if (this.blogDao == null) { throw new IllegalStateException("The [blogDao] property must be set."); } } }
<beans default-init-method="init"> <bean id="blogService" class="com.foo.DefaultBlogService"> <property name="blogDao" ref="blogDao" /> </bean> </beans>
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 bean class has such a
method, it is invoked at the appropriate time.
You configure destroy method callbacks similarly (in XML, that is)
by using the default-destroy-method attribute on the
top-level <beans/> element.
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 of the <bean/> itself.
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.
As of Spring 2.5, you have three options for controlling bean
lifecycle behavior: the InitializingBean and DisposableBean callback
interfaces; custom init() and
destroy() methods; and the @PostConstruct and
@PreDestroy annotations. You can
combine these mechanisms to control a given bean.
![]() | Note |
|---|---|
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,
|
Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:
Methods annotated with
@PostConstruct
afterPropertiesSet() as defined by the
InitializingBean callback
interface
A custom configured init() method
Destroy methods are called in the same order:
Methods annotated with
@PreDestroy
destroy() as defined by the
DisposableBean callback
interface
A custom configured destroy() method
The Lifecycle interface defines the
essential methods for any object that has its own lifecycle requirements
(e.g. starts and stops some background process):
public interface Lifecycle { void start(); void stop(); boolean isRunning(); }
Any Spring-managed object may implement that interface. Then, when
the ApplicationContext itself starts and stops, it will cascade those
calls to all Lifecycle implementations defined within that context. It
does this by delegating to a
LifecycleProcessor:
public interface LifecycleProcessor extends Lifecycle { void onRefresh(); void onClose(); }
Notice that the LifecycleProcessor is
itself an extension of the Lifecycle
interface. It also adds two other methods for reacting to the context
being refreshed and closed.
The order of startup and shutdown invocations can be important. If a
"depends-on" relationship exists between any two objects, the dependent
side will start after its dependency, and it will
stop before its dependency. However, at times the
direct dependencies are unknown. You may only know that objects of a
certain type should start prior to objects of another type. In those
cases, the SmartLifecycle interface
defines another option, namely the getPhase()
method as defined on its super-interface,
Phased.
public interface Phased { int getPhase(); } public interface SmartLifecycle extends Lifecycle, Phased { boolean isAutoStartup(); void stop(Runnable callback); }
When starting, the objects with the lowest phase start first, and
when stopping, the reverse order is followed. Therefore, an object that
implements SmartLifecycle and whose
getPhase() method returns Integer.MIN_VALUE would be
among the first to start and the last to stop. At the other end of the
spectrum, a phase value of Integer.MAX_VALUE would
indicate that the object should be started last and stopped first
(likely because it depends on other processes to be running). When
considering the phase value, it's also important to know that the
default phase for any "normal" Lifecycle
object that does not implement
SmartLifecycle would be 0. Therefore, any
negative phase value would indicate that an object should start before
those standard components (and stop after them), and vice versa for any
positive phase value.
As you can see the stop method defined by
SmartLifecycle accepts a callback. Any
implementation must invoke that callback's run()
method after that implementation's shutdown process is complete. That
enables asynchronous shutdown where necessary since the default
implementation of the LifecycleProcessor
interface, DefaultLifecycleProcessor, will wait
up to its timeout value for the group of objects within each phase to
invoke that callback. The default per-phase timeout is 30 seconds. You
can override the default lifecycle processor instance by defining a bean
named "lifecycleProcessor" within the context. If you only want to
modify the timeout, then defining the following would be
sufficient:
<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor"> <!-- timeout value in milliseconds --> <property name="timeoutPerShutdownPhase" value="10000"/> </bean>
As mentioned, the LifecycleProcessor
interface defines callback methods for the refreshing and closing of the
context as well. The latter will simply drive the shutdown process as if
stop() had been called explicitly, but it will happen when the context
is closing. The 'refresh' callback on the other hand enables another
feature of SmartLifecycle beans. When the
context is refreshed (after all objects have been instantiated and
initialized), that callback will be invoked, and at that point the
default lifecycle processor will check the boolean value returned by
each SmartLifecycle object's
isAutoStartup() method. If "true", then that
object will be started at that point rather than waiting for an explicit
invocation of the context's or its own start() method (unlike the
context refresh, the context start does not happen automatically for a
standard context implementation). The "phase" value as well as any
"depends-on" relationships will determine the startup order in the same
way as described above.
![]() | Note |
|---|---|
This section applies only to non-web applications. Spring's
web-based |
If you are using Spring's IoC container in a non-web application 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.
To register a shutdown hook, you call the
registerShutdownHook() method that is declared
on the AbstractApplicationContext class:
import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public final class Boot { public static void main(final String[] args) throws Exception { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(new String []{"beans.xml"}); // add a shutdown hook for the above context... ctx.registerShutdownHook(); // app runs here... // main method exits, hook is called prior to the app shutting down... } }
When an ApplicationContext creates a
class that implements the
org.springframework.context.ApplicationContextAware
interface, the class is provided with a reference to that
ApplicationContext.
public interface ApplicationContextAware { void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }
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 Section 3.13, “Additional Capabilities of the
ApplicationContext”
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 Section 3.4.5, “Autowiring collaborators”) 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 Section 3.9.2, “@Autowired and @Inject”.
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 { 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.
Besides ApplicationContextAware and
BeanNameAware discussed above, Spring
offers a range of
Aware interfaces that
allow beans to indicate to the container that they require a certain
infrastructure dependency. The most important
Aware interfaces are summarized below - as
a general rule, the name is a good indication of the dependency
type:
Table 3.4. Aware interfaces
| Name | Injected Dependency | Explained in... |
|---|---|---|
| Declaring
| |
| Event publisher of the enclosing
| Section 3.13, “Additional Capabilities of the ApplicationContext” |
| Class loader used to load the bean classes. | |
| Declaring
| |
| Name of the declaring bean | |
| Resource adapter
| |
| Defined weaver for processing class definition at load time | Section 7.8.4, “Load-time weaving with AspectJ in the Spring Framework” |
| Configured strategy for resolving messages (with support for parametrization and internationalization) | Section 3.13, “Additional Capabilities of the ApplicationContext” |
| Spring JMX notification publisher | |
| Current | |
| Current | |
| Configured loader for low-level access to resources | |
| Current | |
| Current |
Note again that usage of these interfaces ties your code to the Spring API and does not follow the Inversion of Control style. As such, they are recommended for infrastructure beans that require programmatic access to the container.
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.
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 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"> <property name="name" value="parent"/> <property name="age" value="1"/> </bean> <bean id="inheritsWithDifferentClass" class="org.springframework.beans.DerivedTestBean" parent="inheritedTestBean" init-method="initialize"> <property name="name" value="override"/> <!-- the age property value of 1 will be inherited from parent --> </bean>
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 must accept the parent's property values.
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 are always taken from the child definition: depends on, autowire mode, dependency check, singleton, scope, lazy init.
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"/> <property name="age" value="1"/> </bean> <bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean" parent="inheritedTestBeanWithoutClass" init-method="initialize"> <property name="name" value="override"/> <!-- age will inherit the value of 1 from the parent bean definition--> </bean>
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
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.
![]() | Note |
|---|---|
|
Typically, an application developer does not need to subclass any
ApplicationContext implementation classes.
You can extend The Spring IoC container infinitely by plugging in
implementations of special integration interfaces. The next few sections
describe these integration interfaces.
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 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. For
more details, consult the Javadoc for the
BeanPostProcessor and
Ordered interfaces.
![]() | Note |
|---|---|
To change the actual bean definition (that is, the recipe that
defines the bean), you instead need to use a
|
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, 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.
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.
![]() | BeanPostProcessors and AOP auto-proxying |
|---|---|
Classes that implement the
For any such bean, you should see an info log message: “Bean foo is not eligible for getting processed by all BeanPostProcessor interfaces (for example: not eligible for auto-proxying)”. |
The following examples show how to write, register, and use
BeanPostProcessors in the context of an
ApplicationContext.
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.
Find below the custom
BeanPostProcessor implementation class
definition:
package scripting; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.BeansException; public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor { // simply return the instantiated bean as-is public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; // we could potentially return any object reference here... } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("Bean '" + beanName + "' created : " + bean.toString()); return bean; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd"> <lang:groovy id="messenger" script-source="classpath:org/springframework/scripting/groovy/Messenger.groovy"> <lang:property name="message" value="Fiona Apple Is Just So Dreamy."/> </lang:groovy> <!-- when the above bean (messenger) is instantiated, this custom BeanPostProcessor implementation will output the fact to the system console --> <bean class="scripting.InstantiationTracingBeanPostProcessor"/> </beans>
Notice how the
InstantiationTracingBeanPostProcessor is simply
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
Chapter 26, Dynamic language support.)
The following small driver script executes the preceding code and configuration:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.scripting.Messenger; public final class Boot { public static void main(final String[] args) throws Exception { ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml"); Messenger messenger = (Messenger) ctx.getBean("messenger"); System.out.println(messenger); } }
The output of the preceding execution resembles the following:
Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961 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. An example is
Spring's RequiredAnnotationBeanPostProcessor -- a
BeanPostProcessor implementation that
ships with the Spring distribution which ensures that JavaBean
properties on beans that are marked with an (arbitrary) annotation are
actually (configured to be) dependency-injected with a value.
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 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. 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
BeanFactoryPostProcessor and
Ordered interfaces for more details.
![]() | Note |
|---|---|
If you want to change the actual bean instances
(the objects that are created from the configuration metadata), then you
instead need to use a Also, |
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,
for example, to register custom property editors.
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.
![]() | Note |
|---|---|
As with |
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. 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"/> </bean> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
The actual values come from another file in the standard Java
Properties format:
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=rootTherefore, 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. 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 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. You can customize this behavior by setting the
systemPropertiesMode property of the configurer. It
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 |
|---|---|
You can use the
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:com/foo/strategy.properties</value> </property> <property name="properties"> <value>custom.strategy.class=com.foo.DefaultStrategy</value> </property> </bean> <bean id="serviceStrategy" class="${custom.strategy.class}"/> 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 |
The PropertyOverrideConfigurer, another 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 definition is not aware of
being overridden, so it is not 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
wins, due to the overriding mechanism.
Properties file configuration lines take this format:
beanName.property=value
For example:
dataSource.driverClassName=com.mysql.jdbc.Driver dataSource.url=jdbc:mysql:mydb
This example file is usable against a container definition that contains a bean called dataSource, which has driver and url properties.
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 set to the scalar value
123.
![]() | Note |
|---|---|
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 dedicated
configuration element:
<context:property-override location="classpath:override.properties"/>
You implement the
org.springframework.beans.factory.FactoryBean
interface for objects that are themselves
factories.
The FactoryBean interface is a 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(): returns an instance
of the object this factory creates. The instance can possibly be
shared, depending on whether this factory returns singletons or
prototypes.
boolean isSingleton(): returns
true if this
FactoryBean returns singletons,
false otherwise.
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; more than 50
implementations of the FactoryBean
interface ship with Spring itself.
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 returns the product of the
FactoryBean, and invoking
getBean("&myBean") returns the
FactoryBean instance
itself.
An alternative to XML setups is provided by annotation-based
configuration which rely on the bytecode metadata for wiring up components
instead of angle-bracket declarations. Instead of using XML to describe a
bean wiring, the developer moves the configuration into the component class
itself by using annotations on the relevant class, method, or field
declaration. As mentioned in Section 3.8.1.2, “Example: The
RequiredAnnotationBeanPostProcessor”, using a
BeanPostProcessor in conjunction with
annotations is a common means of extending the Spring IoC container. For
example, Spring 2.0 introduced the possibility of enforcing required
properties with the @Required annotation. As of Spring 2.5, it is now possible to follow
that same general approach to drive Spring's dependency injection.
Essentially, the @Autowired annotation
provides the same capabilities as described in Section 3.4.5, “Autowiring collaborators” but with more fine-grained control and
wider applicability. Spring 2.5 also adds support for JSR-250 annotations
such as @Resource,
@PostConstruct, and
@PreDestroy. Spring 3.0 adds support for
JSR-330 (Dependency Injection for Java) annotations contained in the
javax.inject package such as @Inject,
@Qualifier, @Named, and @Provider if the JSR330 jar is
present on the classpath. Use of these annotations also requires that
certain BeanPostProcessors be registered
within the Spring container.
![]() | Note |
|---|---|
| Annotation injection is performed before XML injection, thus the latter configuration will override the former for properties wired through both approaches. |
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):
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> </beans>
(The implicitly registered post-processors include AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, as
well as the aforementioned RequiredAnnotationBeanPostProcessor.)
![]() | Note |
|---|---|
|
The @Required annotation applies to
bean property setter methods, as in the following example:
public class SimpleMovieLister { private MovieFinder movieFinder; @Required public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... }
This annotation simply indicates that the affected bean property 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.
As expected, you can apply the
@Autowired annotation to "traditional"
setter methods:
![]() | Note |
|---|---|
JSR 330's @Inject annotation can be used in place of Spring's
|
public class SimpleMovieLister { private MovieFinder movieFinder; @Autowired public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... }
You can also apply the annotation to methods with arbitrary names and/or multiple arguments:
public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... }
You can apply @Autowired to
constructors and fields:
public class MovieRecommender { @Autowired private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) { this.customerPreferenceDao = customerPreferenceDao; } // ... }
It is also possible to provide all beans of a
particular type from the ApplicationContext
by adding the annotation to a field or method that expects an array of
that type:
public class MovieRecommender { @Autowired private MovieCatalog[] movieCatalogs; // ... }
The same applies for typed collections:
public class MovieRecommender { private Set<MovieCatalog> movieCatalogs; @Autowired public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) { this.movieCatalogs = movieCatalogs; } // ... }
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:
public class MovieRecommender { private Map<String, MovieCatalog> movieCatalogs; @Autowired public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) { this.movieCatalogs = movieCatalogs; } // ... }
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 be changed as demonstrated below.
public class SimpleMovieLister { private MovieFinder movieFinder; @Autowired(required=false) public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... }
![]() | Note |
|---|---|
Only one annotated constructor per-class 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, that is the constructor that has the largest number of arguments.
|
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, are automatically
resolved, with no special setup necessary.
public class MovieRecommender { @Autowired private ApplicationContext context; public MovieRecommender() { } // ... }
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. 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:
![]() | Note |
|---|---|
JSR 330's |
public class MovieRecommender { @Autowired @Qualifier("main") private MovieCatalog movieCatalog; // ... }
The @Qualifier annotation can also be
specified on individual constructor arguments or method parameters:
public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(@Qualifier("main") MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... }
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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <bean class="example.SimpleMovieCatalog"> <qualifier value="main"/> <!-- inject any dependencies required by this bean --> </bean> <bean class="example.SimpleMovieCatalog"> <qualifier value="action"/> <!-- inject any dependencies required by this bean --> </bean> <bean id="movieRecommender" class="example.MovieRecommender"/> </beans>
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, 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, 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").
![]() | Tip |
|---|---|
If you intend to express annotation-driven injection by name, do not
primarily use As a specific consequence of this semantic difference, beans that
are themselves defined as a collection or map type cannot be injected
through
|
You can create your own custom qualifier annotations. Simply define an
annotation and provide the @Qualifier
annotation within your definition:
![]() | Note |
|---|---|
You can use JSR 330's |
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
String value();
}Then you can provide the custom qualifier on autowired fields and parameters:
public class MovieRecommender { @Autowired @Genre("Action") private MovieCatalog actionCatalog; private MovieCatalog comedyCatalog; @Autowired public void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog) { this.comedyCatalog = comedyCatalog; } // ... }
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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <bean class="example.SimpleMovieCatalog"> <qualifier type="Genre" value="Action"/> <!-- inject any dependencies required by this bean --> </bean> <bean class="example.SimpleMovieCatalog"> <qualifier type="example.Genre" value="Comedy"/> <!-- inject any dependencies required by this bean --> </bean> <bean id="movieRecommender" class="example.MovieRecommender"/> </beans>
In Section 3.10, “Classpath scanning and managed components”, you will see an annotation-based alternative to providing the qualifier metadata in XML. Specifically, see Section 3.10.7, “Providing qualifier metadata with annotations”.
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 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 annotation:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Offline {
}Then add the annotation to the field or property to be autowired:
public class MovieRecommender { @Autowired @Offline private MovieCatalog offlineCatalog; // ... }
Now the bean definition only needs a qualifier
type:
<bean class="example.SimpleMovieCatalog"> <qualifier type="Offline"/> <!-- inject any dependencies required by this bean --> </bean>
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 following annotation
definition:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MovieQualifier {
String genre();
Format format();
}In this case Format is an enum:
public enum Format {
VHS, DVD, BLURAY
}The fields to be autowired are annotated with the custom qualifier and
include values for both attributes: genre and
format.
public class MovieRecommender { @Autowired @MovieQualifier(format=Format.VHS, genre="Action") private MovieCatalog actionVhsCatalog; @Autowired @MovieQualifier(format=Format.VHS, genre="Comedy") private MovieCatalog comedyVhsCatalog; @Autowired @MovieQualifier(format=Format.DVD, genre="Action") private MovieCatalog actionDvdCatalog; @Autowired @MovieQualifier(format=Format.BLURAY, genre="Comedy") private MovieCatalog comedyBluRayCatalog; // ... }
Finally, the bean definitions should contain matching qualifier
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 take precedence,
but the autowiring mechanism falls back on the values provided within the
<meta/> tags if no such 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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <bean class="example.SimpleMovieCatalog"> <qualifier type="MovieQualifier"> <attribute key="format" value="VHS"/> <attribute key="genre" value="Action"/> </qualifier> <!-- inject any dependencies required by this bean --> </bean> <bean class="example.SimpleMovieCatalog"> <qualifier type="MovieQualifier"> <attribute key="format" value="VHS"/> <attribute key="genre" value="Comedy"/> </qualifier> <!-- inject any dependencies required by this bean --> </bean> <bean class="example.SimpleMovieCatalog"> <meta key="format" value="DVD"/> <meta key="genre" value="Action"/> <!-- inject any dependencies required by this bean --> </bean> <bean class="example.SimpleMovieCatalog"> <meta key="format" value="BLURAY"/> <meta key="genre" value="Comedy"/> <!-- inject any dependencies required by this bean --> </bean> </beans>
The CustomAutowireConfigurer is a
BeanFactoryPostProcessor that 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"> <property name="customQualifierTypes"> <set> <value>example.CustomQualifier</value> </set> </property> </bean>
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 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, 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.
Spring also supports injection using the JSR-250
@Resource annotation on fields or bean
property setter methods. This is a common pattern in Java EE 5 and 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 interprets that value as the bean name to be injected.
In other words, it follows by-name semantics, as
demonstrated in this example:
public class SimpleMovieLister { private MovieFinder movieFinder; @Resource(name="myMovieFinder") public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } }
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 { private MovieFinder movieFinder; @Resource public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } }
![]() | Note |
|---|---|
The name provided with the annotation is resolved as a bean name by
the |
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.
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 { @Resource private CustomerPreferenceDao customerPreferenceDao; @Resource private ApplicationContext context; public MovieRecommender() { } // ... }
The CommonAnnotationBeanPostProcessor not only
recognizes the @Resource annotation but
also the JSR-250 lifecycle annotations. Introduced in
Spring 2.5, the support for these annotations offers yet another
alternative to those described in initialization
callbacks and destruction
callbacks. Provided that the
CommonAnnotationBeanPostProcessor is registered
within the Spring ApplicationContext, a
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 { @PostConstruct public void populateMovieCache() { // populates the movie cache upon initialization... } @PreDestroy public void clearMovieCache() { // clears the movie cache upon destruction... } }
![]() | Note |
|---|---|
For details about the effects of combining various lifecycle mechanisms, see Section 3.6.1.4, “Combining lifecycle mechanisms”. |
Most examples foo bar in this chapter use XML to specify the
configuration metadata that produces each
BeanDefinition within the Spring container.
The previous section (Section 3.9, “Annotation-based container configuration”)
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.
![]() | Note |
|---|---|
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 |