Spring Framework Reference Documentation PDF
Spring Framework Reference Documentation PDF
1 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
4.3.2.RELEASE
Copyright 2004-2016
Copies of this document may be made for your own use and for distribution to others, provided that
you do not charge any fee for such copies and further provided that each copy contains this Copyright
Notice, whether distributed in print or electronically.
Table of Contents
25/08/2016 12:10
2 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
3 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
7.4. Dependencies
7.4.1. Dependency Injection
Constructor-based dependency injection
25/08/2016 12:10
4 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
5 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
6 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
8. Resources
8.1. Introduction
8.2. The Resource interface
8.3. Built-in Resource implementations
8.3.1. UrlResource
8.3.2. ClassPathResource
8.3.3. FileSystemResource
8.3.4. ServletContextResource
8.3.5. InputStreamResource
8.3.6. ByteArrayResource
25/08/2016 12:10
7 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
8 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
9 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
10 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
11 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
IV. Testing
13. Introduction to Spring Testing
14. Unit Testing
14.1. Mock Objects
14.1.1. Environment
14.1.2. JNDI
14.1.3. Servlet API
14.1.4. Portlet API
25/08/2016 12:10
12 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
13 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Test-managed transactions
Enabling and disabling transactions
Transaction rollback and commit behavior
Programmatic transaction management
Executing code outside of a transaction
Configuring a transaction manager
Demonstration of all transaction-related annotations
15.5.8. Executing SQL scripts
Executing SQL scripts programmatically
Executing SQL scripts declaratively with @Sql
15.5.9. TestContext Framework support classes
Spring JUnit 4 Runner
Spring JUnit 4 Rules
JUnit 4 support classes
TestNG support classes
V. Data Access
17. Transaction Management
17.1. Introduction to Spring Framework transaction
management
17.2. Advantages of the Spring Frameworks transaction
support model
25/08/2016 12:10
14 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
15 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
16 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
20.3. Hibernate
20.3.1. SessionFactory setup in a Spring container
20.3.2. Implementing DAOs based on plain Hibernate API
20.3.3. Declarative transaction demarcation
20.3.4. Programmatic transaction demarcation
20.3.5. Transaction management strategies
20.3.6. Comparing container-managed and locally defined resources
20.3.7. Spurious application server warnings with Hibernate
20.4. JDO
20.4.1. PersistenceManagerFactory setup
20.4.2. Implementing DAOs based on the plain JDO API
20.4.3. Transaction management
20.4.4. JdoDialect
25/08/2016 12:10
17 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
20.5. JPA
20.5.1. Three options for JPA setup in a Spring environment
LocalEntityManagerFactoryBean
Obtaining an EntityManagerFactory from JNDI
LocalContainerEntityManagerFactoryBean
Dealing with multiple persistence units
20.5.2. Implementing DAOs based on plain JPA
20.5.3. Transaction Management
20.5.4. JpaDialect
21.6. Castor
21.6.1. CastorMarshaller
21.6.2. Mapping
XML Schema-based Configuration
21.7. XMLBeans
21.7.1. XmlBeansMarshaller
XML Schema-based Configuration
21.8. JiBX
21.8.1. JibxMarshaller
XML Schema-based Configuration
21.9. XStream
21.9.1. XStreamMarshaller
18 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
19 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
20 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
21 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Simple binding
Form input generation macros
HTML escaping and XHTML compliance
23.9. XSLT
23.9.1. My First Words
Bean definitions
Standard MVC controller code
Document transformation
25/08/2016 12:10
22 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
23.11. JasperReports
23.11.1. Dependencies
23.11.2. Configuration
Configuring the ViewResolver
Configuring the Views
About Report Files
Using JasperReportsMultiFormatView
23.11.3. Populating the ModelAndView
23.11.4. Working with Sub-Reports
Configuring Sub-Report Files
Configuring Sub-Report Data Sources
23.11.5. Configuring Exporter Parameters
25/08/2016 12:10
23 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25.5.2. ParameterHandlerMapping
25.5.3. PortletModeParameterHandlerMapping
25.5.4. Adding HandlerInterceptors
25.5.5. HandlerInterceptorAdapter
25.5.6. ParameterMappingInterceptor
25/08/2016 12:10
24 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
VII. Integration
28. Remoting and web services using Spring
28.1. Introduction
28.2. Exposing services using RMI
28.2.1. Exporting the service using the RmiServiceExporter
28.2.2. Linking in the service at the client
25/08/2016 12:10
25 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
28.6. JMS
28.6.1. Server-side configuration
28.6.2. Client-side configuration
28.7. AMQP
28.8. Auto-detection is not implemented for remote
interfaces
28.9. Considerations when choosing a technology
28.10. Accessing RESTful services on the Client
28.10.1. RestTemplate
Working with the URI
Dealing with request and response headers
Jackson JSON Views support
28.10.2. HTTP Message Conversion
StringHttpMessageConverter
FormHttpMessageConverter
ByteArrayHttpMessageConverter
MarshallingHttpMessageConverter
MappingJackson2HttpMessageConverter
MappingJackson2XmlHttpMessageConverter
SourceHttpMessageConverter
BufferedImageHttpMessageConverter
28.10.3. Async RestTemplate
25/08/2016 12:10
26 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
31. JMX
31.1. Introduction
31.2. Exporting your beans to JMX
31.2.1. Creating an MBeanServer
31.2.2. Reusing an existing MBeanServer
31.2.3. Lazy-initialized MBeans
31.2.4. Automatic registration of MBeans
31.2.5. Controlling the registration behavior
25/08/2016 12:10
27 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
32.5. Transactions
33. Email
33.1. Introduction
25/08/2016 12:10
28 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
33.2. Usage
33.2.1. Basic MailSender and SimpleMailMessage usage
33.2.2. Using the JavaMailSender and the MimeMessagePreparator
25/08/2016 12:10
29 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Refreshable beans
Inline dynamic language source files
Understanding Constructor Injection in the context of dynamiclanguage-backed beans
35.3.2. JRuby beans
35.3.3. Groovy beans
Customizing Groovy objects via a callback
35.3.4. BeanShell beans
35.4. Scenarios
35.4.1. Scripted Spring MVC Controllers
35.4.2. Scripted Validators
25/08/2016 12:10
30 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
VIII. Appendices
37. Migrating to Spring Framework 4.x
38. Spring Annotation Programming Model
39. Classic Spring Usage
39.1. Classic ORM usage
39.1.1. Hibernate
The HibernateTemplate
Implementing Spring-based DAOs without callbacks
25/08/2016 12:10
31 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
32 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<jee:remote-slsb/>
41.2.4. the lang schema
41.2.5. the jms schema
41.2.6. the tx (transaction) schema
41.2.7. the aop schema
41.2.8. the context schema
<property-placeholder/>
<annotation-config/>
<component-scan/>
<load-time-weaver/>
<spring-configured/>
<mbean-export/>
41.2.9. the tool schema
41.2.10. the jdbc schema
41.2.11. the cache schema
41.2.12. the beans schema
25/08/2016 12:10
33 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
34 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 any web framework 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. Questions on the Framework itself should be asked on StackOverflow (see
https://spring.io/questions).
25/08/2016 12:10
35 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
36 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Background
"The question is, what aspect of control are [they] inverting?" Martin Fowler posed
this question about Inversion of Control (IoC) on his site in 2004. Fowler suggested
renaming the principle to make it more self-explanatory and came up with
Dependency Injection.
2.2 Modules
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, Messaging, and Test, as shown in the following
diagram.
Figure 2.1. Overview of the Spring Framework
The following sections list the available modules for each feature along with their artifact
25/08/2016 12:10
37 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
names and the topics they cover. Artifact names correlate to artifact IDs used in
Dependency Management tools.
25/08/2016 12:10
38 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 spring-aspects module provides integration with AspectJ.
The spring-instrument module provides class instrumentation support and
classloader implementations to be used in certain application servers. The
spring-instrument-tomcat module contains Springs instrumentation agent for
Tomcat.
2.2.3 Messaging
Spring Framework 4 includes a spring-messaging module with key abstractions from
the Spring Integration project such as Message , MessageChannel , MessageHandler ,
and others to serve as a foundation for messaging-based applications. The module also
includes a set of annotations for mapping messages to methods, similar to the Spring
MVC annotation based programming model.
25/08/2016 12:10
39 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
2.2.5 Web
The Web layer consists of the spring-web , spring-webmvc , spring-websocket , and
spring-webmvc-portlet modules.
The spring-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 an HTTP client and the
web-related parts of Springs remoting support.
The spring-webmvc module (also known as the Web-Servlet module) contains Springs
model-view-controller (MVC) and REST Web Services implementation for web
applications. Springs MVC framework provides a clean separation between domain
model code and web forms and integrates with all of the other features of the Spring
Framework.
The spring-webmvc-portlet module (also known as the Web-Portlet module) provides
the MVC implementation to be used in a Portlet environment and mirrors the functionality
of the spring-webmvc module.
2.2.6 Test
The spring-test module supports the unit testing and integration testing of Spring
components with JUnit or TestNG. It provides consistent loading of Spring
ApplicationContext s and caching of those contexts. It also provides mock objects that
you can use to test your code in isolation.
25/08/2016 12:10
40 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Springs 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
Springs 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. Springs ORM support is integrated with JPA, Hibernate and JDO; 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.
Figure 2.3. Spring middle-tier using a third-party web framework
25/08/2016 12:10
41 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
42 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
When you need to access existing code through web services, you can use Springs
Hessian- , Burlap- , Rmi- or JaxRpcProxyFactory classes. Enabling remote access
to existing applications is not difficult.
Figure 2.5. EJBs - Wrapping existing POJOs
25/08/2016 12:10
43 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
25/08/2016 12:10
44 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 is normally the module name concatenated with the version number (e.g. springcore-4.3.2.RELEASE.jar).
Each release of the Spring Framework will publish artifacts to the following places:
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 .
In a public Maven repository hosted specifically for Spring. In addition to the final GA
releases, this repository also hosts development snapshots and milestones. 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 deployed in Maven Central.
This repository also contains a bundle distribution zip file that contains all Spring jars
bundled together for easy download.
So the first thing you need to decide is how to manage your dependencies: we generally
recommend the use of an automated system like Maven, Gradle or Ivy, but you can also
do it manually by downloading all the jars yourself.
You will find bellow the list of Spring artifacts. For a more complete description of each
modules, see Section 2.2, Modules.
ArtifactId
Description
org.springframework spring-aop
org.springframework spring-aspects
org.springframework spring-beans
org.springframework spring-context
org.springframework spring-contextsupport
25/08/2016 12:10
45 de 1194
GroupId
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
ArtifactId
org.springframework spring-core
Description
Core utilities, used by many other
Spring modules
org.springframework spring-
expression
org.springframework springinstrument
org.springframework spring-
instrumenttomcat
org.springframework spring-jdbc
org.springframework spring-jms
org.springframework springmessaging
org.springframework spring-orm
org.springframework spring-oxm
Object/XML Mapping
org.springframework spring-test
org.springframework spring-tx
org.springframework spring-web
org.springframework spring-webmvc
org.springframework spring-webmvcportlet
25/08/2016 12:10
46 de 1194
GroupId
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
ArtifactId
org.springframework springwebsocket
Description
WebSocket and SockJS
implementations, including STOMP
support
Thats it. Note the scope can be declared as runtime if you dont need to compile against
Spring APIs, which is typically the case for basic dependency injection use cases.
25/08/2016 12:10
47 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
repository (e.g. for milestones or developer snapshots), you need to specify the repository
location in your Maven configuration. For full releases:
<repositories>
<repository>
<id>io.spring.repo.maven.release</id>
<url>http://repo.spring.io/release/</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
For milestones:
<repositories>
<repository>
<id>io.spring.repo.maven.milestone</id>
<url>http://repo.spring.io/milestone/</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
25/08/2016 12:10
48 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
An added benefit of using the BOM is that you no longer need to specify the <version>
attribute when depending on Spring Framework artifacts:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
25/08/2016 12:10
49 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you prefer to use Ivy to manage dependencies then there are similar configuration
options.
To configure Ivy to point to the Spring repository add the following resolver to your
ivysettings.xml :
<resolvers>
<ibiblio name="io.spring.repo.maven.release"
m2compatible="true"
root="http://repo.spring.io/release/"/>
</resolvers>
You can change the root URL from /release/ to /milestone/ or /snapshot/ as
appropriate.
Once configured, you can add dependencies in the usual way. For example (in
ivy.xml ):
<dependency org="org.springframework"
name="spring-core" rev="4.3.2.RELEASE" conf="compile->runtime"/>
2.3.2 Logging
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
25/08/2016 12:10
50 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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. Its 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 dont 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 thats important.
25/08/2016 12:10
51 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.2.RELEASE</version>
<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.
Using SLF4J
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-core</artifactId>
<version>4.3.2.RELEASE</version>
<exclusions>
25/08/2016 12:10
52 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<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>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</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 libraries
not four ( jcl-over-slf4j and logback ). If you do that you might also need to exclude
the slf4j-api dependency from other external dependencies (not Spring), because you
only want one version of that API on the classpath.
Using Log4J
Many people use Log4j as a logging framework for configuration and management
purposes. Its efficient and well-established, and in fact its what we use at runtime when
we build and test Spring. Spring also provides some utilities for configuring and initializing
25/08/2016 12:10
53 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
54 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
container. That option isnt 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.
25/08/2016 12:10
55 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
56 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you are a WebSphere 7 user, be sure to install the JPA 2.0 feature pack.
On WebLogic 10.3.4 or higher, install the JPA 2.0 patch that comes with it.
This turns both of those server generations into Spring 4 compatible
deployment environments.
On a more forward-looking note, Spring Framework 4.0 supports the Java EE 7 level of
applicable specifications now: in particular, JMS 2.0, JTA 1.2, JPA 2.1, Bean Validation
1.1, and JSR-236 Concurrency Utilities. As usual, this support focuses on individual use
of those specifications, e.g. on Tomcat or in standalone environments. However, it works
equally well when a Spring application is deployed to a Java EE 7 server.
Note that Hibernate 4.3 is a JPA 2.1 provider and therefore only supported as of Spring
Framework 4.0. The same applies to Hibernate Validator 5.0 as a Bean Validation 1.1
provider. Neither of the two are officially supported with Spring Framework 3.2.
25/08/2016 12:10
57 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
58 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
59 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
60 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
configuration and infrastructure abstraction; no changes are required to use the standard
annotations.
Spring 4.1 also improves its own caching abstraction significantly:
Caches can be resolved at runtime using a CacheResolver . As a result the value
argument defining the cache name(s) to use is no longer mandatory.
More operation-level customizations: cache resolver, cache manager, key generator
A new @CacheConfig class-level annotation allows common settings to be shared at
the class level without enabling any cache operation.
Better exception handling of cached methods using CacheErrorHandler
Spring 4.1 also has a breaking change in the Cache interface as a new putIfAbsent
method has been added.
25/08/2016 12:10
61 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
62 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
package.
New application context events SessionSubscribeEvent and
SessionUnsubscribeEvent published when STOMP clients subscribe and
unsubscribe.
New "websocket" scope. See Section 26.4.14, WebSocket Scope.
@SendToUser can target only a single session and does not require an authenticated
user.
@MessageMapping methods can use dot "." instead of slash "/" as path separator.
See SPR-11660.
STOMP/WebSocket monitoring info collected and logged. See Section 26.4.16,
Runtime Monitoring.
Significantly optimized and improved logging that should remain very readable and
compact even at DEBUG level.
Optimized message creation including support for temporary message mutability and
avoiding automatic message id and timestamp creation. See Javadoc of
MessageHeaderAccessor .
Close STOMP/WebSocket connections that have no activity within 60 seconds after
the WebSocket session is established. See SPR-11884.
25/08/2016 12:10
63 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
64 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
aliases for annotation attributes. The new @AliasFor annotation can be used to
declare a pair of aliased attributes within a single annotation or to declare an alias
from one attribute in a custom composed annotation to an attribute in a
meta-annotation.
The following annotations have been retrofitted with @AliasFor support in order
to provide meaningful aliases for their value attributes: @Cacheable ,
@CacheEvict , @CachePut , @ComponentScan , @ComponentScan.Filter ,
@ImportResource , @Scope , @ManagedResource , @Header , @Payload ,
@SendToUser , @ActiveProfiles , @ContextConfiguration , @Sql ,
@TestExecutionListeners , @TestPropertySource , @Transactional ,
@ControllerAdvice , @CookieValue , @CrossOrigin , @MatrixVariable ,
@RequestHeader , @RequestMapping , @RequestParam , @RequestPart ,
@ResponseStatus , @SessionAttributes , @ActionMapping ,
@RenderMapping , @EventListener , @TransactionalEventListener .
For example, @ContextConfiguration from the spring-test module is now
declared as follows:
public @interface ContextConfiguration {
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
// ...
}
25/08/2016 12:10
65 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
66 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
67 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
the extension point can also be used to plug in any URI template library.
OkHTTP integration with the RestTemplate .
Custom baseUrl alternative for methods in MvcUriComponentsBuilder .
Serialization/deserialization exception messages are now logged at WARN level.
Default JSON prefix has been changed from "{} && " to the safer ")]}', " one.
New RequestBodyAdvice extension point and built-in implementation to support
Jacksons @JsonView on @RequestBody method arguments.
When using GSON or Jackson 2.6+, the handler method return type is used to
improve serialization of parameterized types like List<Foo> .
Introduced ScriptTemplateView as a JSR-223 based mechanism for scripted web
views, with a focus on JavaScript view templating on Nashorn (JDK 8).
25/08/2016 12:10
68 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
69 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
70 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
71 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
example).
@ModelAttribute allows preventing data binding via binding=false attribute
(see reference).
Consistent exposure of Errors and custom Throwables to MVC exception handlers.
Consistent charset handling in HTTP message converters, including a UTF-8 default
for multipart text content.
Static resource handling uses the configured ContentNegotiationManager for
media type determination.
RestTemplate and AsyncRestTemplate support strict URI variable encoding via
DefaultUriTemplateHandler .
AsyncRestTemplate supports request interception.
25/08/2016 12:10
72 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
73 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 Springs integration with AspectJ (currently the richest - in terms of features and certainly most mature AOP implementation in the Java enterprise space) is also
provided.
Chapter 7, The IoC container
Chapter 8, Resources
Chapter 9, Validation, Data Binding, and Type Conversion
Chapter 10, Spring Expression Language (SpEL)
Chapter 11, Aspect Oriented Programming with Spring
Chapter 12, Spring AOP APIs
25/08/2016 12:10
74 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
exclusively in this chapter in descriptions of Springs IoC container. For more information
on using the BeanFactory instead of the ApplicationContext, refer to Section 7.16,
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.
25/08/2016 12:10
75 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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
25/08/2016 12:10
76 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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. Java
configuration typically uses @Bean annotated methods within a @Configuration class.
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
Springs 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.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.
25/08/2016 12:10
77 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
After you learn about Springs IoC container, you may want to know more
about Springs Resource abstraction, as described in Chapter 8,
Resources, which provides a convenient mechanism for reading an
InputStream from locations defined in a URI syntax. In particular,
Resource paths are used to construct applications contexts as described
in Section 8.7, Application contexts and Resource paths.
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.xsd">
<!-- services -->
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.xsd">
25/08/2016 12:10
78 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
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
25/08/2016 12:10
79 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
25/08/2016 12:10
80 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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,
Springs integration with web frameworks provides for dependency injection for various
web framework classes such as controllers and JSF-managed beans.
Explained in
class
name
scope
constructor arguments
properties
autowiring mode
25/08/2016 12:10
81 de 1194
Property
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Explained in
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
ApplicationContexts 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.
25/08/2016 12:10
82 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
83 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
Java-configuration
If you are using Java-configuration, the @Bean annotation can be used to provide
aliases see Section 7.12.3, Using the @Bean annotation for details.
25/08/2016 12:10
84 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
Inner class names. If you want to configure a bean definition for a static nested
class, you have to use the binary name of the nested class.
For example, if you have a class called Foo in the com.example package, and
this Foo class has a static nested class called Bar , the value of the 'class'
attribute on a bean definition would be
com.example.Foo$Bar
Notice the use of the $ character in the name to separate the nested class name
from the outer class name.
For details about the mechanism for supplying arguments to the constructor (if required)
25/08/2016 12:10
85 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Dependencies.
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.
25/08/2016 12:10
86 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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;
}
25/08/2016 12:10
87 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
This approach shows that the factory bean itself can be managed and configured through
dependency injection (DI). See Dependencies and configuration in detail.
7.4 Dependencies
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.
25/08/2016 12:10
88 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
25/08/2016 12:10
89 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<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 {
// Number of years to 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:
25/08/2016 12:10
90 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Keep in mind that to make this work out of the box your code must be compiled with the
debug flag enabled so that Spring can look up the parameter name from the constructor.
If you cant compile your code with debug flag (or dont want to) you can use
@ConstructorProperties JDK annotation to explicitly name your constructor arguments.
The sample class would then have to look as follows:
package examples;
public class ExampleBean {
// Fields omitted
@ConstructorProperties({"years", "ultimateAnswer"})
public ExampleBean(int years, String ultimateAnswer) {
this.years = years;
this.ultimateAnswer = ultimateAnswer;
}
}
25/08/2016 12:10
91 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
92 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
93 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
94 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<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"/>
25/08/2016 12:10
95 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 (...);
25/08/2016 12:10
96 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
return eb;
}
}
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.xsd">
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
25/08/2016 12:10
97 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 Spring 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.
25/08/2016 12:10
98 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
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.
25/08/2016 12:10
99 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 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>
The local attribute on the ref element is no longer supported in the 4.0
beans xsd since it does not provide value over a regular bean reference
anymore. Simply change your existing ref local references to
ref bean when upgrading to the 4.0 schema.
Inner beans
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
<property name="target">
<bean class="com.example.Person"> <!-- this is the inner bean -->
<property name="name" value="Fiona Apple"/>
25/08/2016 12:10
100 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
An inner bean definition does not require a defined id or name; if specified, the container
does not use such a value as an identifier. The container also ignores the scope flag on
creation: Inner beans are always anonymous and they are always created with the outer
bean. It is not possible to inject inner beans into collaborating beans other than into the
enclosing bean or to access them independently.
As a corner case, it is possible to receive destruction callbacks from a custom scope, e.g.
for a request-scoped inner bean contained within a singleton bean: The creation of the
inner bean instance will be tied to its containing bean, but destruction callbacks allow it to
participate in the request scopes lifecycle. This is not a common scenario; inner beans
typically simply share their containing beans scope.
Collections
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">[email protected]</prop>
<prop key="support">[email protected]</prop>
<prop key="development">[email protected]</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>
25/08/2016 12:10
101 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
</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
Collection merging
The Spring container also 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 collections values are the result of
merging the elements of the parent and child collections, with the childs 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">[email protected]</prop>
<prop key="support">[email protected]</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">[email protected]</prop>
<prop key="support">[email protected]</prop>
25/08/2016 12:10
102 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
</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 childs
adminEmails collection with the parents adminEmails collection.
[email protected]
[email protected]
[email protected]
The child Properties collections value set inherits all property elements from the
parent <props/> , and the childs 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 parents values precede all of the child lists 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.
Strongly-typed collection
With the introduction of generic types in Java 5, you can use strongly typed collections.
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 Springs 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 {
25/08/2016 12:10
103 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 Springs 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.
25/08/2016 12:10
104 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
</property>
</bean>
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"
25/08/2016 12:10
105 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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.
25/08/2016 12:10
106 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bar" class="x.y.Bar"/>
<bean id="baz" class="x.y.Baz"/>
<!-- traditional declaration -->
<bean id="foo" class="x.y.Foo">
<constructor-arg ref="bar"/>
<constructor-arg ref="baz"/>
<constructor-arg value="[email protected]"/>
</bean>
<!-- c-namespace declaration -->
<bean id="foo" class="x.y.Foo" c:bar-ref="bar" c:baz-ref="baz" c:email="
</beans>
The c: namespace uses the same conventions as the p: one (trailing -ref for bean
references) for setting the constructor arguments by their names. And just as well, it
needs to be declared even though it is not defined in an XSD schema (but it exists inside
the Spring core).
For the rare cases where the constructor argument names are not available (usually if the
bytecode was compiled without debugging information), one can use fallback to the
argument indexes:
<!-- c-namespace index declaration -->
<bean id="foo" class="x.y.Foo" c:_0-ref="bar" c:_1-ref="baz"/>
Due to the XML grammar, the index notation requires the presence of the
leading _ as XML attribute names cannot start with a number (even though
some IDE allow it).
25/08/2016 12:10
107 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
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" />
25/08/2016 12:10
108 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
shutdown order.
25/08/2016 12:10
109 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Explanation
(Default) No autowiring. Bean references must be defined via a
ref element. Changing the default setting is not recommended for
larger deployments, because specifying collaborators explicitly
gives greater control and clarity. To some extent, it documents the
structure of a system.
byName
byType
25/08/2016 12:10
110 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
25/08/2016 12:10
111 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
112 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
You can read more about the motivation for Method Injection in this blog entry.
25/08/2016 12:10
113 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
For this dynamic subclassing to work, the class that the Spring bean
container will subclass cannot be final , and the method to be
overridden cannot be final either.
Unit-testing a class that has an abstract method requires you to
subclass the class yourself and to supply a stub implementation of the
abstract method.
Concrete methods are also necessary for component scanning which
requires concrete classes to pick up.
A further key limitation is that lookup methods wont work with factory
methods and in particular not with @Bean methods in configuration
classes, since the container is not in charge of creating the instance in
that case and therefore cannot create a runtime-generated subclass on
the fly.
Finally, objects that have been the target of method injection cannot be
serialized.
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:
25/08/2016 12:10
114 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
115 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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
25/08/2016 12:10
116 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.
Description
(Default) Scopes a single bean definition to a single object
instance per Spring IoC container.
prototype
request
session
25/08/2016 12:10
117 de 1194
Scope
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Description
ApplicationContext .
websocket
25/08/2016 12:10
118 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Springs 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"
25/08/2016 12:10
119 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
conversational state; it was just easier for this author to reuse the core of the singleton
diagram.
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 containers 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 7.6.1, Lifecycle callbacks.)
25/08/2016 12:10
120 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
121 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
Alternatively, if there are issues with your listener setup, consider using Springs
RequestContextFilter . The filter mapping depends on the surrounding web
application configuration, so you have to change it as appropriate.
<web-app>
...
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-clas
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
Request scope
Consider the following XML configuration for a 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
25/08/2016 12:10
122 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Session scope
Consider the following XML configuration for a 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.
When using annotation-driven components or Java Config, the @SessionScope
annotation can be used to assign a component to the session scope.
@SessionScope
@Component
public class UserPreferences {
// ...
}
The globalSession scope is similar to the standard HTTP Session scope (described
25/08/2016 12:10
123 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 globalSession 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 globalSession scope, the standard HTTP Session scope is used, and no
error is raised.
Application scope
Consider the following XML configuration for a bean definition:
<bean id="appPreferences" class="com.foo.AppPreferences" scope="application"
The Spring container creates a new instance of the AppPreferences bean by using the
appPreferences bean definition once for the entire web application. That is, the
appPreferences bean is scoped at the ServletContext level, stored as a regular
ServletContext attribute. This is somewhat similar to a Spring singleton bean but
differs in two important ways: It is a singleton per ServletContext , not per Spring
'ApplicationContext' (for which there may be several in any given web application), and it
is actually exposed and therefore visible as a ServletContext attribute.
When using annotation-driven components or Java Config, the @ApplicationScope
annotation can be used to assign a component to the application scope.
@ApplicationScope
@Component
public class AppPreferences {
// ...
}
25/08/2016 12:10
124 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
You may also use <aop:scoped-proxy/> between beans that are scoped
as singleton , with the reference then going through an intermediate
proxy that is serializable and therefore able to re-obtain the target singleton
bean on deserialization.
When declaring <aop:scoped-proxy/> against a bean of scope
prototype , every method call on the shared proxy will lead to the creation
of a new target instance which the call is then being forwarded to.
Also, scoped proxies are not the only way to access beans from shorter
scopes in a lifecycle-safe fashion. You may also simply declare your
injection point (i.e. the constructor/setter argument or autowired field) as
ObjectFactory<MyTargetBean> , allowing for a getObject() call to
retrieve the current instance on demand every time it is needed - without
holding on to the instance or storing it separately.
The JSR-330 variant of this is called Provider , used with a
Provider<MyTargetBean> declaration and a corresponding get() call
for every retrieval attempt. See here for more details on JSR-330 overall.
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- an HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"
<!-- instructs the container to proxy 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>
25/08/2016 12:10
125 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
bean definition (see the section called Choosing the type of proxy to create and
Chapter 41, 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? Lets examine the following singleton bean definition
and contrast it with what you need to define for the aforementioned scopes (note that 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>
25/08/2016 12:10
126 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
CGLIB proxies only intercept public method calls! Do not call non-public
methods on such a proxy; they will not be delegated to the actual 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>
25/08/2016 12:10
127 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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
javadocs, 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 javadocs 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()
25/08/2016 12:10
128 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.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>
25/08/2016 12:10
129 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
</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>
25/08/2016 12:10
130 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Initialization callbacks
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;
25/08/2016 12:10
131 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Destruction callbacks
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, use the @PreDestroy
annotation or specify a generic method that is supported by bean definitions. With
XML-based configuration metadata, you use the destroy-method attribute on the
<bean/> . With Java config, you use the destroyMethod attribute of @Bean , see the
section called Receiving lifecycle callbacks. 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)
}
}
25/08/2016 12:10
132 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
133 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
134 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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
Any Spring-managed object may implement that interface. Then, when the
ApplicationContext itself receives start and stop signals, e.g. for a stop/restart
scenario at runtime, 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 {
25/08/2016 12:10
135 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
void onRefresh();
void onClose();
}
25/08/2016 12:10
136 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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, its 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 callbacks run() method after that implementations
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:
25/08/2016 12:10
137 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you are using Springs 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 ConfigurableApplicationContext interface:
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Boot {
public static void main(final String[] args) throws Exception {
ConfigurableApplicationContext 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...
}
}
25/08/2016 12:10
138 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The callback is invoked after population of normal bean properties but before an
initialization callback such as InitializingBean afterPropertiesSet or a custom
init-method.
25/08/2016 12:10
139 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Injected
Explained in
Dependency
ApplicationContextAware
Declaring
Section 7.6.2,
ApplicationContext
ApplicationContextAware
and BeanNameAware
ApplicationEventPublisherAware
BeanClassLoaderAware
BeanFactoryAware
enclosing
Capabilities of the
ApplicationContext
ApplicationContext
Section 7.3.2,
Instantiating beans
Declaring
Section 7.6.2,
BeanFactory
ApplicationContextAware
and BeanNameAware
BeanNameAware
Section 7.6.2,
bean
ApplicationContextAware
and BeanNameAware
BootstrapContextAware
Resource adapter
BootstrapContext
the container runs in.
Typically available only
in JCA aware
ApplicationContext s
LoadTimeWeaverAware
Section 11.8.4,
processing class
25/08/2016 12:10
140 de 1194
Name
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Injected
Explained in
Dependency
MessageSourceAware
resolving messages
Capabilities of the
ApplicationContext
parametrization and
internationalization)
NotificationPublisherAware
PortletConfigAware
Section 31.7,
publisher
Notifications
Current
PortletConfig the
Framework
Current
PortletContext the
Framework
Chapter 8, Resources
low-level access to
resources
ServletConfigAware
Current
ServletConfig the
framework
Current
ServletContext the
framework
25/08/2016 12:10
141 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 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 parents property values.
A child bean definition inherits scope, constructor argument values, property values, and
method overrides from the parent, with the option to add new values. Any scope,
initialization method, destroy method, and/or static factory method settings that you
25/08/2016 12:10
142 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The remaining settings are always taken from the child definition: depends on, autowire
mode, dependency check, singleton, 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 containers internal preInstantiateSingletons()
method ignores bean definitions that are defined as abstract.
25/08/2016 12:10
143 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
144 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
145 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The following examples show how to write, register, and use BeanPostProcessor s in an
ApplicationContext .
25/08/2016 12:10
146 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<lang:groovy id="messenger"
script-source="classpath:org/springframework/scripting/groovy/Messenger.gr
<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>
25/08/2016 12:10
147 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you want to change the actual bean instances (i.e., the objects that are
created from the configuration metadata), then you instead need to use a
BeanPostProcessor (described above in Section 7.8.1, Customizing
beans using a BeanPostProcessor). While it is technically possible to work
with bean instances within a BeanFactoryPostProcessor (e.g., using
BeanFactory.getBean() ), doing so causes premature bean instantiation,
violating the standard container lifecycle. This may cause negative side
effects such as bypassing bean post processing.
Also, BeanFactoryPostProcessor s are scoped per-container. This is only
relevant if you are using container hierarchies. If you define a
BeanFactoryPostProcessor in one container, it will only be applied to the
bean definitions in that container. Bean definitions in one container will not
25/08/2016 12:10
148 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
149 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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=root
Therefore, the string ${jdbc.username} is replaced at runtime with the value 'sa', and
the same applies for other placeholder values that match keys in the properties file. The
PropertyPlaceholderConfigurer checks for placeholders in most properties and
attributes of a bean definition. Furthermore, 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. One or more locations can
be provided as a comma-separated list in the location attribute.
<context:property-placeholder location="classpath:com/foo/jdbc.properties"/>
25/08/2016 12:10
150 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
useful when you have to pick a particular implementation class at runtime. For example:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfi
<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
to be created, which is during the preInstantiateSingletons() phase of an
ApplicationContext for a non-lazy-init bean.
For example:
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:mydb
This example file can be used with 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
25/08/2016 12:10
151 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
i. the sammy property of the bob property of the fred property of the foo bean is
set to the scalar value 123 .
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.
25/08/2016 12:10
152 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
153 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
7.9.1 @Required
The @Required annotation applies to bean property setter methods, as in the following
example:
public class SimpleMovieLister {
25/08/2016 12:10
154 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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 NullPointerException s
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.
7.9.2 @Autowired
JSR 330s @Inject annotation can be used in place of Springs
@Autowired annotation in the examples below. See here for more details.
25/08/2016 12:10
155 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
As expected, you can also apply the @Autowired annotation to "traditional" setter
methods:
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 fields as well and even mix it with constructors:
public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
25/08/2016 12:10
156 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Autowired
private MovieCatalog movieCatalog;
@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;
// ...
}
Even typed Maps can be autowired as long as the expected key type is String . The
25/08/2016 12:10
157 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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;
}
// ...
}
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.
@Autowireds required attribute is recommended over the `@Required
annotation. The required attribute indicates that the property is not required for
autowiring purposes, the property is ignored if it cannot be autowired. @Required ,
on the other hand, is stronger in that it enforces the property that was set by any
means supported by the container. If no value is injected, a corresponding
exception is raised.
25/08/2016 12:10
158 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
You can also use @Autowired for interfaces that are well-known resolvable
dependencies: BeanFactory , ApplicationContext , Environment ,
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() {
}
// ...
}
25/08/2016 12:10
159 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... }
@Bean
public MovieCatalog secondMovieCatalog() { ... }
// ...
}
With such configuration, the following MovieRecommender will be autowired with the
firstMovieCatalog .
public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
// ...
}
25/08/2016 12:10
160 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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
25/08/2016 12:10
161 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.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") .
25/08/2016 12:10
162 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
You can create your own custom qualifier annotations. Simply define an annotation and
provide the @Qualifier annotation within your definition:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
25/08/2016 12:10
163 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.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">
25/08/2016 12:10
164 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
In Section 7.10, Classpath scanning and managed components, you will see an
annotation-based alternative to providing the qualifier metadata in XML. Specifically, see
Section 7.10.8, 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 {
}
You can also define custom qualifier annotations that accept named attributes in addition
25/08/2016 12:10
165 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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();
}
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;
// ...
}
25/08/2016 12:10
166 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.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>
25/08/2016 12:10
167 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Assuming that beans above implement a generic interface, i.e. Store<String> and
Store<Integer> , you can @Autowire the Store interface and the generic will be
used as a qualifier:
@Autowired
private Store<String> s1; // <String> qualifier, injects the stringStore bean
@Autowired
private Store<Integer> s2; // <Integer> qualifier, injects the integerStore bean
Generic qualifiers also apply when autowiring Lists, Maps and Arrays:
// Inject all Store beans as long as they have an <Integer> generic
// Store<String> beans will not appear in this list
@Autowired
private List<Store<Integer>> s;
7.9.6 CustomAutowireConfigurer
The CustomAutowireConfigurer is a BeanFactoryPostProcessor that enables you
to register your own custom qualifier annotation types even if they are not annotated with
Springs @Qualifier annotation.
25/08/2016 12:10
168 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"
<property name="customQualifierTypes">
<set>
<value>example.CustomQualifier</value>
</set>
</property>
</bean>
7.9.7 @Resource
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
25/08/2016 12:10
169 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
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;
}
}
The name provided with the annotation is resolved as a bean name by the
ApplicationContext of which the
CommonAnnotationBeanPostProcessor is aware. The names can be
resolved through JNDI if you configure Springs SimpleJndiBeanFactory
explicitly. However, it is recommended that you rely on the default behavior
and simply use Springs JNDI lookup capabilities to preserve the level of
indirection.
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() {
25/08/2016 12:10
170 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
// ...
}
25/08/2016 12:10
171 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
the annotations only drive the dependency injection. This section describes an option for
implicitly detecting the candidate components by scanning the classpath. Candidate
components are classes that match against a filter criteria and have a corresponding
bean definition registered with the container. This removes the need to use XML to
perform bean registration; instead you can use annotations (for example @Component ),
AspectJ type expressions, or your own custom filter criteria to select which classes will
have bean definitions registered with the container.
Starting with Spring 3.0, many features provided by the Spring JavaConfig
project are part of the core Spring Framework. This allows you to define
beans using Java rather than using the traditional XML files. Take a look at
the @Configuration , @Bean , @Import , and @DependsOn annotations
for examples of how to use these new features.
7.10.2 Meta-annotations
Many of the annotations provided by Spring can be used as meta-annotations in your
25/08/2016 12:10
172 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
173 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Service
@SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
public class SessionScopedUserService implements UserService {
// ...
}
To autodetect these classes and register the corresponding beans, you need to add
@ComponentScan to your @Configuration class, where the basePackages attribute is
a common parent package for the two classes. (Alternatively, you can specify a
comma/semicolon/space-separated list that includes the parent package of each class.)
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
...
}
25/08/2016 12:10
174 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
for concision, the above may have used the value attribute of the
annotation, i.e. ComponentScan("org.example")
25/08/2016 12:10
175 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Example Expression
Description
Type
annotation
org.example.SomeAnnotation
(default)
assignable
org.example.SomeClass
aspectj
org.example..*Service+
regex
org\.example\.Default.*
custom
org.example.MyTypeFilter
org.springframework.core.type .TypeFilt
interface.
The following example shows the configuration ignoring all @Repository annotations
and using "stub" repositories instead.
25/08/2016 12:10
176 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Configuration
@ComponentScan(basePackages = "org.example",
includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repositor
excludeFilters = @Filter(Repository.class))
public class AppConfig {
...
}
25/08/2016 12:10
177 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
}
This class is a Spring component that has application-specific code contained in its
doWork() method. However, it also contributes a bean definition that has a factory
method referring to the method publicInstance() . The @Bean annotation identifies
the factory method and other bean definition properties, such as a qualifier value through
the @Qualifier annotation. Other method level annotations that can be specified are
@Scope , @Lazy , and custom qualifier annotations.
In addition to its role for component initialization, the @Lazy annotation may
also be placed on injection points marked with @Autowired or @Inject .
In this context, it leads to the injection of a lazy-resolution proxy.
Autowired fields and methods are supported as previously discussed, with additional
support for autowiring of @Bean methods:
@Component
public class FactoryMethodComponent {
private static int i;
@Bean
@Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
// use of a custom qualifier and autowiring of method parameters
@Bean
protected TestBean protectedInstance(
@Qualifier("public") TestBean spouse,
@Value("#{privateInstance.age}") String country) {
TestBean tb = new TestBean("protectedInstance", 1);
tb.setSpouse(spouse);
tb.setCountry(country);
return tb;
}
@Bean
private TestBean privateInstance() {
return new TestBean("privateInstance", i++);
25/08/2016 12:10
178 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
@Bean
@RequestScope
public TestBean requestScopedInstance() {
return new TestBean("requestScopedInstance", 3);
}
}
The example autowires the String method parameter country to the value of the Age
property on another bean named privateInstance . A Spring Expression Language
element defines the value of the property through the notation #{ <expression> } . For
@Value annotations, an expression resolver is preconfigured to look for bean names
when resolving expression text.
The @Bean methods in a Spring component are processed differently than their
counterparts inside a Spring @Configuration class. The difference is that @Component
classes are not enhanced with CGLIB to intercept the invocation of methods and fields.
CGLIB proxying is the means by which invoking methods or fields within @Bean methods
in @Configuration classes creates bean metadata references to collaborating objects;
such methods are not invoked with normal Java semantics but rather go through the
container in order to provide the usual lifecycle management and proxying of Spring
beans even when referring to other beans via programmatic calls to @Bean methods. In
contrast, invoking a method or field in an @Bean method within a plain @Component
class has standard Java semantics, with no special CGLIB processing or other
constraints applying.
25/08/2016 12:10
179 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
180 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you do not want to rely on the default bean-naming strategy, you can
provide a custom bean-naming strategy. First, implement the
BeanNameGenerator interface, and be sure to include a default no-arg
constructor. Then, provide the fully-qualified class name when configuring
the scanner:
@Configuration
@ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
public class AppConfig {
...
}
<beans>
<context:component-scan base-package="org.example"
name-generator="org.example.MyNameGenerator" />
</beans>
As a general rule, consider specifying the name with the annotation whenever other
components may be making explicit references to it. On the other hand, the
auto-generated names are adequate whenever the container is responsible for wiring.
For details on web-specific scopes, see Section 7.5.4, Request, session, global session,
application, and WebSocket scopes.
To provide a custom strategy for scope resolution rather than relying on the
25/08/2016 12:10
181 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Configuration
@ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
public class AppConfig {
...
}
<beans>
<context:component-scan base-package="org.example"
scope-resolver="org.example.MyScopeResolver" />
</beans>
When using certain non-singleton scopes, it may be necessary to generate proxies for the
scoped objects. The reasoning is described in the section called Scoped beans as
dependencies. For this purpose, a scoped-proxy attribute is available on the
component-scan element. The three possible values are: no, interfaces, and targetClass.
For example, the following configuration will result in standard JDK dynamic proxies:
@Configuration
@ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
public class AppConfig {
...
}
<beans>
<context:component-scan base-package="org.example"
scoped-proxy="interfaces" />
</beans>
25/08/2016 12:10
182 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
183 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
As with @Autowired , it is possible to use @Inject at the field level, method level and
constructor-argument level. Furthermore, you may declare your injection point as a
Provider , allowing for on-demand access to beans of shorter scopes or lazy access to
other beans through a Provider.get() call. As a variant of the example above:
import javax.inject.Inject;
import javax.inject.Provider;
public class SimpleMovieLister {
private Provider<MovieFinder> movieFinder;
public void listMovies() {
this.movieFinder.get().findMovies(...);
...
}
}
If you would like to use a qualified name for the dependency that should be injected, you
should use the @Named annotation as follows:
import javax.inject.Inject;
import javax.inject.Named;
public class SimpleMovieLister {
25/08/2016 12:10
184 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
It is very common to use @Component without specifying a name for the component.
@Named can be used in a similar fashion:
import javax.inject.Inject;
import javax.inject.Named;
@Named
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Inject
public void setMovieFinder(MovieFinder movieFinder) {
25/08/2016 12:10
185 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
// ...
}
When using @Named , it is possible to use component scanning in the exact same way as
when using Spring annotations:
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
...
}
javax.inject.*
@Inject
@Component
@Named
@Scope("singleton") @Singleton
25/08/2016 12:10
186 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Spring
javax.inject.*
@Qualifier
@Qualifier /
javax.inject.Qualifier is just a
@Named
@Value
no equivalent
@Required
no equivalent
@Lazy
no equivalent
ObjectFactory
Provider
javax.inject.Provider is a direct
alternative to Springs ObjectFactory ,
just with a shorter get() method
name. It can also be used in
combination with Springs @Autowired
or with non-annotated constructors and
setter methods.
25/08/2016 12:10
187 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
initializes a new object to be managed by the Spring IoC container. For those familiar with
Springs <beans/> XML configuration the @Bean annotation plays the same role as the
<bean/> element. You can use @Bean annotated methods with any Spring
@Component , however, they are most often used with @Configuration beans.
Annotating a class with @Configuration indicates that its primary purpose is as a
source of bean definitions. Furthermore, @Configuration classes allow inter-bean
dependencies to be defined by simply calling other @Bean methods in the same class.
The simplest possible @Configuration class would read as follows:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
The AppConfig class above would be equivalent to the following Spring <beans/>
XML:
<beans>
<bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
25/08/2016 12:10
188 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Java-based configuration.
Simple construction
In much the same way that Spring XML files are used as input when instantiating a
ClassPathXmlApplicationContext , @Configuration classes may be used as input
when instantiating an AnnotationConfigApplicationContext . This allows for
completely XML-free usage of the Spring container:
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
The above assumes that MyServiceImpl , Dependency1 and Dependency2 use Spring
25/08/2016 12:10
189 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
In the example above, the com.acme package will be scanned, looking for any
@Component -annotated classes, and those classes will be registered as Spring bean
definitions within the container. AnnotationConfigApplicationContext exposes the
scan(String) method to allow for the same component-scanning functionality:
25/08/2016 12:10
190 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<web-app>
<!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationCont
</param-value>
</context-param>
<!-- Bootstrap the root application context as usual using ContextLoaderListener <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>dispatcher</servlet-name>
25/08/2016 12:10
191 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-clas
<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplication
</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma- or space-delim
and fully-qualified @Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.acme.web.MvcConfig</param-value>
</init-param>
</servlet>
<!-- map all requests for /app/* to the dispatcher servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
Declaring a bean
To declare a bean, simply annotate a method with the @Bean annotation. You use this
method to register a bean definition within an ApplicationContext of the type specified
as the methods return value. By default, the bean name will be the same as the method
name. The following is a simple example of a @Bean method declaration:
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
25/08/2016 12:10
192 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Bean dependencies
A @Bean annotated method can have an arbitrary number of parameters describing the
dependencies required to build that bean. For instance if our TransferService requires
an AccountRepository we can materialize that dependency via a method parameter:
@Configuration
public class AppConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}
25/08/2016 12:10
193 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
By default, beans defined using Java config that have a public close or
shutdown method are automatically enlisted with a destruction callback. If
you have a public close or shutdown method and you do not wish for it
to be called when the container shuts down, simply add
@Bean(destroyMethod="") to your bean definition to disable the default
(inferred) mode.
You may want to do that by default for a resource that you acquire via JNDI
as its lifecycle is managed outside the application. In particular, make sure
to always do it for a DataSource as it is known to be problematic on Java
EE application servers.
@Bean(destroyMethod="")
25/08/2016 12:10
194 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Also, with @Bean methods, you will typically choose to use programmatic
JNDI lookups: either using Springs
JndiTemplate / JndiLocatorDelegate helpers or straight JNDI
InitialContext usage, but not the JndiObjectFactoryBean variant
which would force you to declare the return type as the FactoryBean type
instead of the actual target type, making it harder to use for cross-reference
calls in other @Bean methods that intend to refer to the provided resource
here.
Of course, in the case of Foo above, it would be equally as valid to call the init()
method directly during construction:
@Configuration
public class AppConfig {
@Bean
public Foo foo() {
Foo foo = new Foo();
foo.init();
return foo;
}
// ...
}
When you work directly in Java, you can do anything you like with your
objects and do not always need to rely on the container lifecycle!
25/08/2016 12:10
195 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Configuration
public class MyConfiguration {
@Bean
@Scope("prototype")
public Encryptor encryptor() {
// ...
}
}
25/08/2016 12:10
196 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Bean(name = "myFoo")
public Foo foo() {
return new Foo();
}
}
Bean aliasing
As discussed in Section 7.3.1, Naming beans, it is sometimes desirable to give a single
bean multiple names, otherwise known as bean aliasing. The name attribute of the
@Bean annotation accepts a String array for this purpose.
@Configuration
public class AppConfig {
@Bean(name = { "dataSource", "subsystemA-dataSource", "subsystemB-dataSource" })
public DataSource dataSource() {
// instantiate, configure and return DataSource bean...
}
}
Bean description
Sometimes it is helpful to provide a more detailed textual description of a bean. This can
be particularly useful when beans are exposed (perhaps via JMX) for monitoring
purposes.
To add a description to a @Bean the @Description annotation can be used:
@Configuration
public class AppConfig {
@Bean
@Description("Provides a basic example of a bean")
public Foo foo() {
return new Foo();
}
}
25/08/2016 12:10
197 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
In the example above, the foo bean receives a reference to bar via constructor
injection.
25/08/2016 12:10
198 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Bean
public CommandManager commandManager() {
// return new anonymous implementation of CommandManager with command() overridden
// to return a new prototype Command object
return new CommandManager() {
protected Command createCommand() {
return asyncCommand();
}
}
}
25/08/2016 12:10
199 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
return clientService;
}
@Bean
public ClientService clientService2() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientDao clientDao() {
return new ClientDaoImpl();
}
}
There are a few restrictions due to the fact that CGLIB dynamically adds
features at startup-time:
Configuration classes should not be final
They should have a constructor with no arguments
25/08/2016 12:10
200 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Much as the <import/> element is used within Spring XML files to aid in modularizing
configurations, the @Import annotation allows for loading @Bean definitions from
another configuration class:
@Configuration
public class ConfigA {
@Bean
public A a() {
return new A();
}
}
@Configuration
@Import(ConfigA.class)
public class ConfigB {
@Bean
public B b() {
return new B();
}
}
Now, rather than needing to specify both ConfigA.class and ConfigB.class when
instantiating the context, only ConfigB needs to be supplied explicitly:
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.
// now both beans A and B will be available...
A a = ctx.getBean(A.class);
B b = ctx.getBean(B.class);
}
This approach simplifies container instantiation, as only one class needs to be dealt with,
rather than requiring the developer to remember a potentially large number of
@Configuration classes during construction.
25/08/2016 12:10
201 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
ref="someBean" and trust that Spring will work it out during container initialization. Of
course, when using @Configuration classes, the Java compiler places constraints on
the configuration model, in that references to other beans must be valid Java syntax.
Fortunately, solving this problem is simple. As we already discussed, @Bean method can
have an arbitrary number of parameters describing the bean dependencies. Lets
consider a more real-world scenario with several @Configuration classes, each
depending on beans declared in the others:
@Configuration
public class ServiceConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}
@Configuration
public class RepositoryConfig {
@Bean
public AccountRepository accountRepository(DataSource dataSource) {
return new JdbcAccountRepository(dataSource);
}
}
@Configuration
@Import({ServiceConfig.class, RepositoryConfig.class})
public class SystemTestConfig {
@Bean
public DataSource dataSource() {
// return new DataSource
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.
// everything wires up across configuration classes...
TransferService transferService = ctx.getBean(TransferService.class);
transferService.transfer(100.00, "A123", "C456");
}
25/08/2016 12:10
202 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
There is another way to achieve the same result. Remember that @Configuration
classes are ultimately just another bean in the container: This means that they can take
advantage of @Autowired and @Value injection etc just like any other bean!
Make sure that the dependencies you inject that way are of the simplest
kind only. @Configuration classes are processed quite early during the
initialization of the context and forcing a dependency to be injected this way
may lead to unexpected early initialization. Whenever possible, resort to
parameter-based injection as in the example above.
Also, be particularly careful with BeanPostProcessor and
BeanFactoryPostProcessor definitions via @Bean . Those should usually
be declared as static @Bean methods, not triggering the instantiation of
their containing configuration class. Otherwise, @Autowired and @Value
wont work on the configuration class itself since it is being created as a
bean instance too early.
@Configuration
public class ServiceConfig {
@Autowired
private AccountRepository accountRepository;
@Bean
public TransferService transferService() {
return new TransferServiceImpl(accountRepository);
}
}
@Configuration
public class RepositoryConfig {
private final DataSource dataSource;
@Autowired
public RepositoryConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public AccountRepository accountRepository() {
return new JdbcAccountRepository(dataSource);
}
25/08/2016 12:10
203 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
@Configuration
@Import({ServiceConfig.class, RepositoryConfig.class})
public class SystemTestConfig {
@Bean
public DataSource dataSource() {
// return new DataSource
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.
// everything wires up across configuration classes...
TransferService transferService = ctx.getBean(TransferService.class);
transferService.transfer(100.00, "A123", "C456");
}
In the scenario above, using @Autowired works well and provides the desired
modularity, but determining exactly where the autowired bean definitions are declared is
still somewhat ambiguous. For example, as a developer looking at ServiceConfig , how
do you know exactly where the @Autowired AccountRepository bean is declared? Its
not explicit in the code, and this may be just fine. Remember that the Spring Tool Suite
provides tooling that can render graphs showing how everything is wired up - that may be
all you need. Also, your Java IDE can easily find all declarations and uses of the
AccountRepository type, and will quickly show you the location of @Bean methods
that return that type.
In cases where this ambiguity is not acceptable and you wish to have direct navigation
from within your IDE from one @Configuration class to another, consider autowiring
the configuration classes themselves:
@Configuration
public class ServiceConfig {
25/08/2016 12:10
204 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Autowired
private RepositoryConfig repositoryConfig;
@Bean
public TransferService transferService() {
// navigate 'through' the config class to the @Bean method!
return new TransferServiceImpl(repositoryConfig.accountRepository());
}
}
25/08/2016 12:10
205 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Configuration
@Import({ServiceConfig.class, DefaultRepositoryConfig.class}) // import the concrete c
public class SystemTestConfig {
@Bean
public DataSource dataSource() {
// return DataSource
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.
TransferService transferService = ctx.getBean(TransferService.class);
transferService.transfer(100.00, "A123", "C456");
}
25/08/2016 12:10
206 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
if (attrs != null) {
for (Object value : attrs.get("value")) {
if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
return true;
}
}
return false;
}
}
return true;
}
25/08/2016 12:10
207 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Bean
public AccountRepository accountRepository() {
return new JdbcAccountRepository(dataSource);
}
@Bean
public TransferService transferService() {
return new TransferService(accountRepository());
}
}
system-test-config.xml:
<beans>
<!-- enable processing of annotations such as @Autowired and @Configuration -->
<context:annotation-config/>
<context:property-placeholder location="classpath:/com/acme/jdbc.properties"
<bean class="com.acme.AppConfig"/>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
jdbc.properties:
jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
jdbc.username=sa
jdbc.password=
25/08/2016 12:10
208 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Because @Configuration is meta-annotated with @Component , @Configuration annotated classes are automatically candidates for component scanning. Using the same
scenario as above, we can redefine system-test-config.xml to take advantage of
component-scanning. Note that in this case, we dont need to explicitly declare
<context:annotation-config/> , because <context:component-scan/> enables
the same functionality.
system-test-config.xml:
<beans>
<!-- picks up and registers AppConfig as a bean definition -->
<context:component-scan base-package="com.acme"/>
<context:property-placeholder location="classpath:/com/acme/jdbc.properties"
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
25/08/2016 12:10
209 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource() {
return new DriverManagerDataSource(url, username, password);
}
}
properties-config.xml
<beans>
<context:property-placeholder location="classpath:/com/acme/jdbc.properties"
</beans>
jdbc.properties
jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
jdbc.username=sa
jdbc.password=
25/08/2016 12:10
210 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
from them.
Lets now consider how this application will be deployed into a QA or production
environment, assuming that the datasource for the application will be registered with the
production application servers JNDI directory. Our dataSource bean now looks like this:
@Bean(destroyMethod="")
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
The problem is how to switch between using these two variations based on the current
environment. Over time, Spring users have devised a number of ways to get this done,
usually relying on a combination of system environment variables and XML <import/>
statements containing ${placeholder} tokens that resolve to the correct configuration
file path depending on the value of an environment variable. Bean definition profiles is a
core container feature that provides a solution to this problem.
25/08/2016 12:10
211 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Profile
The @Profile annotation allows you to indicate that a component is eligible for
registration when one or more specified profiles are active. Using our example above, we
can rewrite the dataSource configuration as follows:
@Configuration
@Profile("dev")
public class StandaloneDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
@Configuration
@Profile("production")
public class JndiDataConfig {
@Bean(destroyMethod="")
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
As mentioned before, with @Bean methods, you will typically choose to use
programmatic JNDI lookups: either using Springs
JndiTemplate / JndiLocatorDelegate helpers or the straight JNDI
InitialContext usage shown above, but not the
JndiObjectFactoryBean variant which would force you to declare the
return type as the FactoryBean type.
25/08/2016 12:10
212 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Profile can also be declared at the method level to include only one particular bean of
a configuration class:
@Configuration
public class AppConfig {
@Bean
@Profile("dev")
public DataSource devDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
@Bean
@Profile("production")
public DataSource productionDataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
25/08/2016 12:10
213 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
It is also possible to avoid that split and nest <beans/> elements within the same file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
25/08/2016 12:10
214 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="...">
<!-- other bean definitions -->
<beans profile="dev">
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:com/bank/config/sql/schema.sql"
<jdbc:script location="classpath:com/bank/config/sql/test-data.sql"
</jdbc:embedded-database>
</beans>
<beans profile="production">
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"
</beans>
</beans>
The spring-bean.xsd has been constrained to allow such elements only as the last
ones in the file. This should help provide flexibility without incurring clutter in the XML
files.
Activating a profile
Now that we have updated our configuration, we still need to instruct Spring which profile
is active. If we started our sample application right now, we would see a
NoSuchBeanDefinitionException thrown, because the container could not find the
Spring bean named dataSource .
Activating a profile can be done in several ways, but the most straightforward is to do it
programmatically against the Environment API which is available via an
ApplicationContext :
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("dev");
ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class
ctx.refresh();
25/08/2016 12:10
215 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Note that profiles are not an "either-or" proposition; it is possible to activate multiple
profiles at once. Programmatically, simply provide multiple profile names to the
setActiveProfiles() method, which accepts String varargs:
ctx.getEnvironment().setActiveProfiles("profile1", "profile2");
Default profile
The default profile represents the profile that is enabled by default. Consider the
following:
@Configuration
@Profile("default")
public class DefaultDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.build();
}
}
If no profile is active, the dataSource above will be created; this can be seen as a way
to provide a default definition for one or more beans. If any profile is enabled, the default
profile will not apply.
The name of the default profile can be changed using setDefaultProfiles() on the
Environment or declaratively using the spring.profiles.default property.
25/08/2016 12:10
216 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
In the snippet above, we see a high-level way of asking Spring whether the foo property
is defined for the current environment. To answer this question, the Environment object
performs a search over a set of PropertySource objects. A PropertySource is a
simple abstraction over any source of key-value pairs, and Springs
StandardEnvironment is configured with two PropertySource objectsone
representing the set of JVM system properties (a la System.getProperties() ) and one
representing the set of system environment variables (a la System.getenv() ).
Most importantly, the entire mechanism is configurable. Perhaps you have a custom
source of properties that youd like to integrate into this search. No problemsimply
25/08/2016 12:10
217 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
implement and instantiate your own PropertySource and add it to the set of
PropertySources for the current Environment :
ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new MyPropertySource());
In the code above, MyPropertySource has been added with highest precedence in the
search. If it contains a foo property, it will be detected and returned ahead of any foo
property in any other PropertySource . The MutablePropertySources API exposes a
number of methods that allow for precise manipulation of the set of property sources.
7.13.4 @PropertySource
The @PropertySource annotation provides a convenient and declarative mechanism for
adding a PropertySource to Springs Environment .
Given a file "app.properties" containing the key/value pair testbean.name=myTestBean ,
the following @Configuration class uses @PropertySource in such a way that a call
to testBean.getName() will return "myTestBean".
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
25/08/2016 12:10
218 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
25/08/2016 12:10
219 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
220 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
HierarchicalBeanFactory interface.
25/08/2016 12:10
221 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
</beans>
In the example it is assumed you have three resource bundles defined in your classpath
called format , exceptions and windows . Any request to resolve a message will be
handled in the JDK standard way of resolving messages through ResourceBundles. For
the purposes of the example, assume the contents of two of the above resource bundle
files are
# in format.properties
message=Alligators rock!
# in exceptions.properties
argument.required=The {0} argument is required.
25/08/2016 12:10
222 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<beans>
The resulting output from the invocation of the execute() method will be
The userDao argument is required.
25/08/2016 12:10
223 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The resulting output from the running of the above program will be
Ebagum lad, the 'userDao' argument is required, I say, required.
You can also use the MessageSourceAware interface to acquire a reference to any
MessageSource that has been defined. Any bean that is defined in an
ApplicationContext that implements the MessageSourceAware interface is injected
with the application contexts MessageSource when the bean is created and configured.
25/08/2016 12:10
224 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Explanation
Published when the ApplicationContext is
initialized or refreshed, for example, using the
refresh() method on the
ConfigurableApplicationContext interface.
"Initialized" here means that all beans are loaded,
post-processor beans are detected and activated,
singletons are pre-instantiated, and the
ApplicationContext object is ready for use. As
long as the context has not been closed, a refresh
can be triggered multiple times, provided that the
chosen ApplicationContext actually supports
such "hot" refreshes. For example,
XmlWebApplicationContext supports hot
refreshes, but GenericApplicationContext
does not.
ContextStartedEvent
ContextStoppedEvent
ContextClosedEvent
25/08/2016 12:10
225 de 1194
Event
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Explanation
"Closed" here means that all singleton beans are
destroyed. A closed context reaches its end of life;
it cannot be refreshed or restarted.
RequestHandledEvent
You can also create and publish your own custom events. This example demonstrates a
simple class that extends Springs ApplicationEvent base class:
public class BlackListEvent extends ApplicationEvent {
private final String address;
private final String test;
public BlackListEvent(Object source, String address, String test) {
super(source);
this.address = address;
this.test = test;
}
// accessor and other methods...
}
25/08/2016 12:10
226 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
At configuration time, the Spring container will detect that EmailService implements
ApplicationEventPublisherAware and will automatically call
setApplicationEventPublisher() . In reality, the parameter passed in will be the
Spring container itself; youre simply interacting with the application context via its
ApplicationEventPublisher interface.
To receive the custom ApplicationEvent , create a class that implements
ApplicationListener and register it as a Spring bean. The following example
demonstrates such a class:
public class BlackListNotifier implements ApplicationListener<BlackListEvent> {
private String notificationAddress;
public void setNotificationAddress(String notificationAddress) {
this.notificationAddress = notificationAddress;
}
public void onApplicationEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress...
}
}
25/08/2016 12:10
227 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
finished processing the event. One advantage of this synchronous and single-threaded
approach is that when a listener receives an event, it operates inside the transaction
context of the publisher if a transaction context is available. If another strategy for event
publication becomes necessary, refer to the JavaDoc for Springs
ApplicationEventMulticaster interface.
The following example shows the bean definitions used to register and configure each of
the classes above:
<bean id="emailService" class="example.EmailService">
<property name="blackList">
<list>
<value>[email protected]</value>
<value>[email protected]</value>
<value>[email protected]</value>
</list>
</property>
</bean>
<bean id="blackListNotifier" class="example.BlackListNotifier">
<property name="notificationAddress" value="[email protected]"/>
</bean>
Putting it all together, when the sendEmail() method of the emailService bean is
called, if there are any emails that should be blacklisted, a custom event of type
BlackListEvent is published. The blackListNotifier bean is registered as an
ApplicationListener and thus receives the BlackListEvent , at which point it can
notify appropriate parties.
25/08/2016 12:10
228 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
As you can see above, the method signature actually infer which even type it listens to.
This also works for nested generics as long as the actual event resolves the generics
parameter you would filter on.
If your method should listen to several events or if you want to define it with no parameter
at all, the event type(s) can also be specified on the annotation itself:
@EventListener({ContextStartedEvent.class, ContextRefreshedEvent.class})
public void handleContextStart() {
}
It is also possible to add additional runtime filtering via the condition attribute of the
annotation that defines a SpEL expression that should match to actually invoke the
method for a particular event.
For instance, our notifier can be rewritten to be only invoked if the test attribute of the
event is equal to foo :
@EventListener(condition = "#event.test == 'foo'")
public void processBlackListEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress...
}
Each SpEL expression evaluates again a dedicated context. The next table lists the
items made available to the context so one can use them for conditional event
processing:
25/08/2016 12:10
229 de 1194
Name
Location
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Description
Example
event
root object
#root.event
args
root object
#root.args[0]
evaluation
name
context
notation as an
alias).
Note that #root.event allows you to access to the underlying event, even if your
method signature actually refers to an arbitrary object that was published.
If you need to publish an event as the result of processing another, just change the
method signature to return the event that should be published, something like:
@EventListener
public ListUpdateEvent handleBlackListEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress and
// then publish a ListUpdateEvent...
}
This new method will publish a new ListUpdateEvent for every BlackListEvent
handled by the method above. If you need to publish several events, just return a
Collection of events instead.
Asynchronous Listeners
If you want a particular listener to process events asynchronously, simply reuse the
regular @Async support:
@EventListener
25/08/2016 12:10
230 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Async
public void processBlackListEvent(BlackListEvent event) {
// BlackListEvent is processed in a separate thread
}
Ordering Listeners
If you need the listener to be invoked before another one, just add the @Order
annotation to the method declaration:
@EventListener
@Order(42)
public void processBlackListEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress...
}
Generic Events
You may also use generics to further define the structure of your event. Consider an
EntityCreatedEvent<T> where T is the type of the actual entity that got created. You
can create the following listener definition to only receive EntityCreatedEvent for a
Person :
@EventListener
public void onPersonCreated(EntityCreatedEvent<Person> event) {
...
}
Due to type erasure, this will only work if the event that is fired resolves the generic
parameter(s) on which the event listener filters on (that is something like
class PersonCreatedEvent extends EntityCreatedEvent<Person> { } ).
In certain circumstances, this may become quite tedious if all events follow the same
structure (as it should be the case for the event above). In such a case, you can
implement ResolvableTypeProvider to guide the framework beyond what the runtime
25/08/2016 12:10
231 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
This works not only for ApplicationEvent but any arbitrary object that
youd send as an event.
25/08/2016 12:10
232 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-cl
</listener>
The listener inspects the contextConfigLocation parameter. If the parameter does not
exist, the listener uses /WEB-INF/applicationContext.xml as a default. When the
parameter does exist, the listener separates the String by using predefined delimiters
(comma, semicolon and whitespace) and uses the values as locations where application
contexts will be searched. Ant-style path patterns are supported as well. Examples are
/WEB-INF/*Context.xml for all files with names ending with "Context.xml", residing in
the "WEB-INF" directory, and /WEB-INF/**/*Context.xml , for all such files in any
subdirectory of "WEB-INF".
25/08/2016 12:10
233 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
just hosted in Java EE environment, being able to access the Java EE servers facilities.
RAR deployment is more natural alternative to scenario of deploying a headless WAR file,
in effect, a WAR file without any HTTP entry points that is used only for bootstrapping a
Spring ApplicationContext in a Java EE environment.
RAR deployment is ideal for application contexts that do not need HTTP entry points but
rather consist only of message endpoints and scheduled jobs. Beans in such a context
can use application server resources such as the JTA transaction manager and
JNDI-bound JDBC DataSources and JMS ConnectionFactory instances, and may also
register with the platforms JMX server - all through Springs standard transaction
management and JNDI and JMX support facilities. Application components can also
interact with the application servers JCA WorkManager through Springs TaskExecutor
abstraction.
Check out the JavaDoc of the SpringContextResourceAdapter class for the
configuration details involved in RAR deployment.
For a simple deployment of a Spring ApplicationContext as a Java EE RAR file: package
all application classes into a RAR file, which is a standard JAR file with a different file
extension. Add all required library JARs into the root of the RAR archive. Add a "METAINF/ra.xml" deployment descriptor (as shown in SpringContextResourceAdapter s
JavaDoc) and the corresponding Spring XML bean definition file(s) (typically "METAINF/applicationContext.xml"), and drop the resulting RAR file into your application
servers deployment directory.
Such RAR deployment units are usually self-contained; they do not expose
components to the outside world, not even to other modules of the same
application. Interaction with a RAR-based ApplicationContext usually occurs
through JMS destinations that it shares with other modules. A RAR-based
ApplicationContext may also, for example, schedule some jobs, reacting to
new files in the file system (or the like). If it needs to allow synchronous
access from the outside, it could for example export RMI endpoints, which
of course may be used by other application modules on the same machine.
25/08/2016 12:10
234 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
BeanFactory
ApplicationContext
Bean instantiation/wiring
Yes
Yes
Automatic BeanPostProcessor
No
Yes
No
Yes
registration
Automatic
BeanFactoryPostProcessor
registration
25/08/2016 12:10
235 de 1194
Feature
Convenient MessageSource
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
BeanFactory
ApplicationContext
No
Yes
No
Yes
In both cases, the explicit registration step is inconvenient, which is one reason why the
various ApplicationContext implementations are preferred above plain BeanFactory
implementations in the vast majority of Spring-backed applications, especially when using
BeanFactoryPostProcessor s and BeanPostProcessor s. These mechanisms
implement important functionality such as property placeholder replacement and AOP.
25/08/2016 12:10
236 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
code is served out of a Spring IoC container, has its own dependencies supplied by the
container when it is created, and is completely unaware of the container. However, for the
small glue layers of code that are sometimes needed to tie other code together, you
sometimes need a singleton (or quasi-singleton) style access to a Spring IoC container.
For example, third-party code may try to construct new objects directly (
Class.forName() style), without the ability to get these objects out of a Spring IoC
container.If the object constructed by the third-party code is a small stub or proxy, which
then uses a singleton style access to a Spring IoC container to get a real object to
delegate to, then inversion of control has still been achieved for the majority of the code
(the object coming out of the container). Thus most code is still unaware of the container
or how it is accessed, and remains decoupled from other code, with all ensuing benefits.
EJBs may also use this stub/proxy approach to delegate to a plain Java implementation
object, retrieved from a Spring IoC container. While the Spring IoC container itself ideally
does not have to be a singleton, it may be unrealistic in terms of memory usage or
initialization times (when using beans in the Spring IoC container such as a Hibernate
SessionFactory ) for each bean to use its own, non-singleton Spring IoC container.
Looking up the application context in a service locator style is sometimes the only option
for accessing shared Spring-managed components, such as in an EJB 2.1 environment,
or when you want to share a single ApplicationContext as a parent to
WebApplicationContexts across WAR files. In this case you should look into using the
utility class ContextSingletonBeanFactoryLocator locator that is described in this
Spring team blog entry.
[1]
[2]
See Background
See Section 7.4.1, Dependency Injection
8. Resources
8.1 Introduction
Javas standard java.net.URL class and standard handlers for various URL prefixes
unfortunately are not quite adequate enough for all access to low-level resources. For
example, there is no standardized URL implementation that may be used to access a
resource that needs to be obtained from the classpath, or relative to a ServletContext .
While it is possible to register new handlers for specialized URL prefixes (similar to
existing handlers for prefixes such as http: ), this is generally quite complicated, and the
URL
25/08/2016 12:10
237 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Some of the most important methods from the Resource interface are:
getInputStream() : locates and opens the resource, returning an InputStream
for reading from the resource. It is expected that each invocation returns a fresh
InputStream . It is the responsibility of the caller to close the stream.
exists() : returns a boolean indicating whether this resource actually exists in
physical form.
isOpen() : returns a boolean indicating whether this resource represents a handle
with an open stream. If true , the InputStream cannot be read multiple times, and
must be read once only and then closed to avoid resource leaks. Will be false for
all usual resource implementations, with the exception of InputStreamResource .
getDescription() : returns a description for this resource, to be used for error
25/08/2016 12:10
238 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
8.3.1 UrlResource
The UrlResource wraps a java.net.URL , and may be used to access any object that
is normally accessible via a URL, such as files, an HTTP target, an FTP target, etc. All
URLs have a standardized String representation, such that appropriate standardized
prefixes are used to indicate one URL type from another. This includes file: for
accessing filesystem paths, http: for accessing resources via the HTTP protocol, ftp:
for accessing resources via FTP, etc.
A UrlResource is created by Java code explicitly using the UrlResource constructor,
but will often be created implicitly when you call an API method which takes a String
argument which is meant to represent a path. For the latter case, a JavaBeans
PropertyEditor will ultimately decide which type of Resource to create. If the path
25/08/2016 12:10
239 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
string contains a few well-known (to it, that is) prefixes such as classpath: , it will create
an appropriate specialized Resource for that prefix. However, if it doesnt recognize the
prefix, it will assume the this is just a standard URL string, and will create a
UrlResource .
8.3.2 ClassPathResource
This class represents a resource which should be obtained from the classpath. This uses
either the thread context class loader, a given class loader, or a given class for loading
resources.
This Resource implementation supports resolution as java.io.File if the class path
resource resides in the file system, but not for classpath resources which reside in a jar
and have not been expanded (by the servlet engine, or whatever the environment is) to
the filesystem. To address this the various Resource implementations always support
resolution as a java.net.URL .
A ClassPathResource is created by Java code explicitly using the
ClassPathResource constructor, but will often be created implicitly when you call an
API method which takes a String argument which is meant to represent a path. For the
latter case, a JavaBeans PropertyEditor will recognize the special prefix classpath:
on the string path, and create a ClassPathResource in that case.
8.3.3 FileSystemResource
This is a Resource implementation for java.io.File handles. It obviously supports
resolution as a File , and as a URL .
8.3.4 ServletContextResource
This is a Resource implementation for ServletContext resources, interpreting relative
paths within the relevant web applications root directory.
This always supports stream access and URL access, but only allows java.io.File
access when the web application archive is expanded and the resource is physically on
the filesystem. Whether or not its expanded and on the filesystem like this, or accessed
directly from the JAR or somewhere else like a DB (its conceivable) is actually dependent
on the Servlet container.
25/08/2016 12:10
240 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
8.3.5 InputStreamResource
A Resource implementation for a given InputStream . This should only be used if no
specific Resource implementation is applicable. In particular, prefer
ByteArrayResource or any of the file-based Resource implementations where
possible.
In contrast to other Resource implementations, this is a descriptor for an already opened
resource - therefore returning true from isOpen() . Do not use it if you need to keep
the resource descriptor somewhere, or if you need to read a stream multiple times.
8.3.6 ByteArrayResource
This is a Resource implementation for a given byte array. It creates a
ByteArrayInputStream for the given byte array.
Its useful for loading content from any given byte array, without having to resort to a
single-use InputStreamResource .
All application contexts implement the ResourceLoader interface, and therefore all
application contexts may be used to obtain Resource instances.
When you call getResource() on a specific application context, and the location path
specified doesnt have a specific prefix, you will get back a Resource type that is
appropriate to that particular application context. For example, assume the following
snippet of code was executed against a ClassPathXmlApplicationContext instance:
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
25/08/2016 12:10
241 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Similarly, one can force a UrlResource to be used by specifying any of the standard
java.net.URL prefixes:
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt"
Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt"
The following table summarizes the strategy for converting String s to Resource s:
Example
Explanation
classpath:
classpath:com/myapp/config.xml
file:
file:///data/config.xml
http:
http://myserver/logo.png
Loaded as a URL .
(none)
/data/config.xml
[1]
25/08/2016 12:10
242 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
243 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Note that the resource path has no prefix, so because the application context itself is
going to be used as the ResourceLoader , the resource itself will be loaded via a
ClassPathResource , FileSystemResource , or ServletContextResource (as
appropriate) depending on the exact type of the context.
If there is a need to force a specific Resource type to be used, then a prefix may be
used. The following two examples show how to force a ClassPathResource and a
UrlResource (the latter being used to access a filesystem file).
<property name="template" value="classpath:some/resource/path/myTemplate.txt"
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>
The bean definitions will be loaded from the classpath, as a ClassPathResource will be
used. But if you create a FileSystemXmlApplicationContext as follows:
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/appContext.xml");
The bean definition will be loaded from a filesystem location, in this case relative to the
25/08/2016 12:10
244 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
i. will actually load its bean definitions from the classpath. However, it is still a
FileSystemXmlApplicationContext . If it is subsequently used as a
ResourceLoader , any unprefixed paths will still be treated as filesystem paths.
25/08/2016 12:10
245 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
One use for this mechanism is when doing component-style application assembly. All
components can 'publish' context definition fragments to a well-known location path, and
when the final application context is created using the same path prefixed via
classpath*: , all component fragments will be picked up automatically.
Note that this wildcarding is specific to use of resource paths in application context
constructors (or when using the PathMatcher utility class hierarchy directly), and is
resolved at construction time. It has nothing to do with the Resource type itself. Its not
possible to use the classpath*: prefix to construct an actual Resource , as a resource
points to just one resource at a time.
Ant-style Patterns
When the path location contains an Ant-style pattern, for example:
/WEB-INF/*-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/*-context.xml
classpath:com/mycompany/**/applicationContext.xml
i. the resolver follows a more complex but defined procedure to try to resolve the
wildcard. It produces a Resource for the path up to the last non-wildcard segment
and obtains a URL from it. If this URL is not a "jar:" URL or container-specific variant
(e.g. "
zip:`" in WebLogic, " `wsjar`" in WebSphere, etc.), then a `java.io.File
is obtained from it and used to resolve the wildcard by traversing the filesystem. In
the case of a jar URL, the resolver either gets a java.net.JarURLConnection from
it or manually parses the jar URL and then traverses the contents of the jar file to
resolve the wildcards.
Implications on portability
If the specified path is already a file URL (either explicitly, or implicitly because the base
ResourceLoader is a filesystem one, then wildcarding is guaranteed to work in a
completely portable fashion.
If the specified path is a classpath location, then the resolver must obtain the last
non-wildcard path segment URL via a Classloader.getResource() call. Since this is
just a node of the path (not the file at the end) it is actually undefined (in the
ClassLoader javadocs) exactly what sort of a URL is returned in this case. In practice, it
is always a java.io.File representing the directory, where the classpath resource
resolves to a filesystem location, or a jar URL of some sort, where the classpath resource
resolves to a jar location. Still, there is a portability concern on this operation.
25/08/2016 12:10
246 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If a jar URL is obtained for the last non-wildcard segment, the resolver must be able to
get a java.net.JarURLConnection from it, or manually parse the jar URL, to be able to
walk the contents of the jar, and resolve the wildcard. This will work in most environments,
but will fail in others, and it is strongly recommended that the wildcard resolution of
resources coming from jars be thoroughly tested in your specific environment before you
rely on it.
This special prefix specifies that all classpath resources that match the given name must
be obtained (internally, this essentially happens via a ClassLoader.getResources()
call), and then merged to form the final application context definition.
25/08/2016 12:10
247 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
files reside in the file system. This means that a pattern like "
classpath*:*.xml`" will not retrieve files from the root of jar files but rather
method which only returns file system locations for a passed-in empty string (indicating
potential roots to search).
Ant-style patterns with " `classpath:`" resources are not guaranteed to find matching
resources if the root package to search is available in multiple class path locations. This is
because a resource such as
com/mycompany/package1/service-context.xml
is used to try to resolve it, the resolver will work off the (first) URL returned by
getResource("com/mycompany") ;. If this base package node exists in multiple
classloader locations, the actual end resource may not be underneath. Therefore,
preferably, use " `classpath*:`" with the same Ant-style pattern in such a case, which will
search all class path locations that contain the root package.
As are the following: (Even though it would make sense for them to be different, as one
case is relative and the other absolute.)
FileSystemXmlApplicationContext ctx = ...;
25/08/2016 12:10
248 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
ctx.getResource("some/resource/path/myTemplate.txt");
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("/some/resource/path/myTemplate.txt");
In practice, if true absolute filesystem paths are needed, it is better to forgo the use of
absolute paths with FileSystemResource / FileSystemXmlApplicationContext ,
and just force the use of a UrlResource , by using the file: URL prefix.
// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt");
25/08/2016 12:10
249 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
model of an application (or whatever objects you use to process user input). Spring
provides the so-called DataBinder to do exactly that. The Validator and the
DataBinder make up the validation package, which is primarily used in but not
limited to the MVC framework.
The BeanWrapper is a fundamental concept in the Spring Framework and is used in a lot
of places. However, you probably will not have the need to use the BeanWrapper
directly. Because this is reference documentation however, we felt that some explanation
might be in order. We will explain the BeanWrapper in this chapter since, if you were
going to use it at all, you would most likely do so when trying to bind data to objects.
Springs DataBinder and the lower-level BeanWrapper both use PropertyEditors to parse
and format property values. The PropertyEditor concept is part of the JavaBeans
specification, and is also explained in this chapter. Spring 3 introduces a "core.convert"
package that provides a general type conversion facility, as well as a higher-level "format"
package for formatting UI field values. These new packages may be used as simpler
alternatives to PropertyEditors, and will also be discussed in this chapter.
Were going to provide validation behavior for the Person class by implementing the
following two methods of the org.springframework.validation.Validator interface:
supports(Class) - Can this Validator validate instances of the supplied
Class ?
validate(Object, org.springframework.validation.Errors) - validates the
given object and in case of validation errors, registers those with the given Errors
object
25/08/2016 12:10
250 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
251 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
/**
* This Validator validates Customer instances, and any subclasses of Customer too
*/
public boolean supports(Class clazz) {
return Customer.class.isAssignableFrom(clazz);
}
Validation errors are reported to the Errors object passed to the validator. In case of
Spring Web MVC you can use <spring:bind/> tag to inspect the error messages, but
of course you can also inspect the errors object yourself. More information about the
methods it offers can be found in the javadocs.
25/08/2016 12:10
252 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
the code youve passed in, but also a number of additional error codes. What error codes
it registers is determined by the MessageCodesResolver that is used. By default, the
DefaultMessageCodesResolver is used, which for example not only registers a
message with the code you gave, but also messages that include the field name you
passed to the reject method. So in case you reject a field using
rejectValue("age", "too.darn.old") , apart from the too.darn.old code, Spring
will also register too.darn.old.age and too.darn.old.age.int (so the first will
include the field name and the second will include the type of the field); this is done as a
convenience to aid developers in targeting error messages and suchlike.
More information on the MessageCodesResolver and the default strategy can be found
online in the javadocs of MessageCodesResolver and
DefaultMessageCodesResolver , respectively.
25/08/2016 12:10
253 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Explanation
Indicates the property name corresponding to the
methods getName() or isName() and
setName(..)
account.name
account[2]
account[COMPANYNAME]
Below youll find some examples of working with the BeanWrapper to get and set
properties.
(This next section is not vitally important to you if youre not planning to work with the
BeanWrapper directly. If youre just using the DataBinder and the BeanFactory and
their out-of-the-box implementation, you should skip ahead to the section about
PropertyEditors .)
Consider the following two classes:
public class Company {
private String name;
private Employee managingDirector;
25/08/2016 12:10
254 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The following code snippets show some examples of how to retrieve and manipulate
some of the properties of instantiated Companies and Employees :
BeanWrapper company = new BeanWrapperImpl(new Company());
// setting the company name..
company.setPropertyValue("name", "Some Company Inc.");
// ... can also be done like this:
25/08/2016 12:10
255 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
256 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Explanation
Editor for byte arrays. Strings will simply be
converted to their corresponding byte
representations. Registered by default by
BeanWrapperImpl .
ClassEditor
CustomBooleanEditor
CustomCollectionEditor
CustomDateEditor
CustomNumberEditor
FileEditor
InputStreamEditor
25/08/2016 12:10
257 de 1194
Class
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Explanation
ResourceEditor and Resource ) an
InputStream , so InputStream properties may
be directly set as Strings. Note that the default
usage will not close the InputStream for you!
Registered by default by BeanWrapperImpl .
LocaleEditor
PatternEditor
PropertiesEditor
StringTrimmerEditor
URLEditor
25/08/2016 12:10
258 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
FooEditor class to be recognized and used as the PropertyEditor for Foo -typed
properties.
com
chank
pop
Foo
FooEditor // the PropertyEditor for the Foo class
Note that you can also use the standard BeanInfo JavaBeans mechanism here as well
(described in not-amazing-detail here). Find below an example of using the BeanInfo
mechanism for explicitly registering one or more PropertyEditor instances with the
properties of an associated class.
com
chank
pop
Foo
FooBeanInfo // the BeanInfo for the Foo class
Here is the Java source code for the referenced FooBeanInfo class. This would
associate a CustomNumberEditor with the age property of the Foo class.
public class FooBeanInfo extends SimpleBeanInfo {
public PropertyDescriptor[] getPropertyDescriptors() {
try {
final PropertyEditor numberPE = new CustomNumberEditor(Integer.class
PropertyDescriptor ageDescriptor = new PropertyDescriptor("age", Foo.
public PropertyEditor createPropertyEditor(Object bean) {
return numberPE;
};
};
return new PropertyDescriptor[] { ageDescriptor };
}
catch (IntrospectionException ex) {
throw new Error(ex.toString());
}
}
}
25/08/2016 12:10
259 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
260 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
this.type = type;
}
}
When things are properly set up, we want to be able to assign the type property as a
string, which a PropertyEditor will behind the scenes convert into an actual
ExoticType instance:
<bean id="sample" class="example.DependsOnExoticType">
<property name="type" value="aNameForExoticType"/>
</bean>
Using PropertyEditorRegistrars
Another mechanism for registering property editors with the Spring container is to create
and use a PropertyEditorRegistrar . This interface is particularly useful when you
need to use the same set of property editors in several different situations: write a
corresponding registrar and reuse that in each case. PropertyEditorRegistrars work
in conjunction with an interface called PropertyEditorRegistry , an interface that is
implemented by the Spring BeanWrapper (and DataBinder ).
PropertyEditorRegistrars are particularly convenient when used in conjunction with
25/08/2016 12:10
261 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Finally, and in a bit of a departure from the focus of this chapter, for those of you using
Springs MVC web framework, using PropertyEditorRegistrars in conjunction with
data-binding Controllers (such as SimpleFormController ) can be very convenient.
25/08/2016 12:10
262 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
This style of PropertyEditor registration can lead to concise code (the implementation
of initBinder(..) is just one line long!), and allows common PropertyEditor
registration code to be encapsulated in a class and then shared amongst as many
Controllers as needed.
25/08/2016 12:10
263 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
To create your own converter, simply implement the interface above. Parameterize S as
the type you are converting from, and T as the type you are converting to. Such a
converter can also be applied transparently if a collection or array of S needs to be
converted to an array or collection of T , provided that a delegating array/collection
converter has been registered as well (which DefaultConversionService does by
default).
For each call to convert(S) , the source argument is guaranteed to be NOT null. Your
Converter may throw any unchecked exception if conversion fails; specifically, an
IllegalArgumentException should be thrown to report an invalid source value. Take
care to ensure that your Converter implementation is thread-safe.
Several converter implementations are provided in the core.convert.support
package as a convenience. These include converters from Strings to Numbers and other
common types. Consider StringToInteger as an example for a typical Converter
implementation:
package org.springframework.core.convert.support;
final class StringToInteger implements Converter<String, Integer> {
public Integer convert(String source) {
return Integer.valueOf(source);
}
}
9.5.2 ConverterFactory
When you need to centralize the conversion logic for an entire class hierarchy, for
example, when converting from String to java.lang.Enum objects, implement
ConverterFactory :
package org.springframework.core.convert.converter;
public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
25/08/2016 12:10
264 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
the range of classes you can convert to. Then implement getConverter(Class<T>), where
T is a subclass of R.
Consider the StringToEnum ConverterFactory as an example:
package org.springframework.core.convert.support;
final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToEnumConverter(targetType);
}
9.5.3 GenericConverter
When you require a sophisticated Converter implementation, consider the
GenericConverter interface. With a more flexible but less strongly typed signature, a
GenericConverter supports converting between multiple source and target types. In
addition, a GenericConverter makes available source and target field context you can use
when implementing your conversion logic. Such context allows a type conversion to be
driven by a field annotation, or generic information declared on a field signature.
package org.springframework.core.convert.converter;
public interface GenericConverter {
public Set<ConvertiblePair> getConvertibleTypes();
25/08/2016 12:10
265 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
ConditionalGenericConverter
Sometimes you only want a Converter to execute if a specific condition holds true. For
example, you might only want to execute a Converter if a specific annotation is present
on the target field. Or you might only want to execute a Converter if a specific method,
such as a static valueOf method, is defined on the target class.
ConditionalGenericConverter is the union of the GenericConverter and
ConditionalConverter interfaces that allows you to define such custom matching
criteria:
public interface ConditionalGenericConverter
extends GenericConverter, ConditionalConverter {
boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}
266 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The ConversionService defines a unified API for executing type conversion logic at
runtime. Converters are often executed behind this facade interface:
package org.springframework.core.convert;
public interface ConversionService {
boolean canConvert(Class<?> sourceType, Class<?> targetType);
<T> T convert(Object source, Class<T> targetType);
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
To register a default ConversionService with Spring, add the following bean definition with
id conversionService :
25/08/2016 12:10
267 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
class="org.springframework.context.support.ConversionServiceFactoryBean"
For most use cases, the convert method specifying the targetType can be used but it
will not work with more complex types such as a collection of a parameterized element. If
you want to convert a List of Integer to a List of String programmatically, for
25/08/2016 12:10
268 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
instance, you need to provide a formal definition of the source and target types.
Fortunately, TypeDescriptor provides various options to make that straightforward:
DefaultConversionService cs = new DefaultConversionService();
List<Integer> input = ....
cs.convert(input,
TypeDescriptor.forObject(input), // List<Integer> type descriptor
TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class
25/08/2016 12:10
269 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
java.lang.Long. Use the Formatter SPI when youre working in a client environment, such
as a web application, and need to parse and print localized field values. The
ConversionService provides a unified type conversion API for both SPIs.
Where Formatter extends from the Printer and Parser building-block interfaces:
public interface Printer<T> {
String print(T fieldValue, Locale locale);
}
import java.text.ParseException;
public interface Parser<T> {
T parse(String clientValue, Locale locale) throws ParseException;
}
To create your own Formatter, simply implement the Formatter interface above.
Parameterize T to be the type of object you wish to format, for example,
java.util.Date . Implement the print() operation to print an instance of T for display
in the client locale. Implement the parse() operation to parse an instance of T from the
formatted representation returned from the client locale. Your Formatter should throw a
ParseException or IllegalArgumentException if a parse attempt fails. Take care to ensure
your Formatter implementation is thread-safe.
Several Formatter implementations are provided in format subpackages as a
convenience. The number package provides a NumberFormatter ,
CurrencyFormatter , and PercentFormatter to format java.lang.Number objects
using a java.text.NumberFormat . The datetime package provides a
DateFormatter to format java.util.Date objects with a java.text.DateFormat .
The datetime.joda package provides comprehensive datetime formatting support
based on the Joda Time library.
Consider DateFormatter as an example Formatter implementation:
25/08/2016 12:10
270 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
package org.springframework.format.datetime;
public final class DateFormatter implements Formatter<Date> {
private String pattern;
public DateFormatter(String pattern) {
this.pattern = pattern;
}
public String print(Date date, Locale locale) {
if (date == null) {
return "";
}
return getDateFormat(locale).format(date);
}
public Date parse(String formatted, Locale locale) throws ParseException {
if (formatted.length() == 0) {
return null;
}
return getDateFormat(locale).parse(formatted);
}
protected DateFormat getDateFormat(Locale locale) {
DateFormat dateFormat = new SimpleDateFormat(this.pattern, locale);
dateFormat.setLenient(false);
return dateFormat;
}
}
25/08/2016 12:10
271 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Parameterize A to be the field annotationType you wish to associate formatting logic with,
for example org.springframework.format.annotation.DateTimeFormat . Have
getFieldTypes() return the types of fields the annotation may be used on. Have
getPrinter() return a Printer to print the value of an annotated field. Have
getParser() return a Parser to parse a clientValue for an annotated field.
The example AnnotationFormatterFactory implementation below binds the
@NumberFormat Annotation to a formatter. This annotation allows either a number style
or pattern to be specified:
public final class NumberFormatAnnotationFormatterFactory
implements AnnotationFormatterFactory<NumberFormat> {
public Set<Class<?>> getFieldTypes() {
return new HashSet<Class<?>>(asList(new Class<?>[] {
Short.class, Integer.class, Long.class, Float.class,
Double.class, BigDecimal.class, BigInteger.class }));
}
public Printer<Number> getPrinter(NumberFormat annotation, Class<?> fieldType) {
return configureFormatterFrom(annotation, fieldType);
}
public Parser<Number> getParser(NumberFormat annotation, Class<?> fieldType) {
return configureFormatterFrom(annotation, fieldType);
}
private Formatter<Number> configureFormatterFrom(NumberFormat annotation,
Class<?> fieldType) {
if (!annotation.pattern().isEmpty()) {
return new NumberFormatter(annotation.pattern());
} else {
Style style = annotation.style();
if (style == Style.PERCENT) {
return new PercentFormatter();
} else if (style == Style.CURRENCY) {
return new CurrencyFormatter();
} else {
return new NumberFormatter();
}
25/08/2016 12:10
272 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
}
}
25/08/2016 12:10
273 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
274 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
275 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
http://www.springframework.org/schema/beans/spring-beans.xsd>
Joda Time provides separate distinct types to represent date , time and
date-time values. The dateFormatter , timeFormatter and
dateTimeFormatter properties of the JodaTimeFormatterRegistrar
should be used to configure the different formats for each type. The
DateTimeFormatterFactoryBean provides a convenient way to create
formatters.
If you are using Spring MVC remember to explicitly configure the conversion service that
is used. For Java based @Configuration this means extending the
WebMvcConfigurationSupport class and overriding the mvcConversionService()
method. For XML you should use the 'conversion-service' attribute of the
mvc:annotation-driven element. See Section 22.16.3, Conversion and Formatting
for details.
25/08/2016 12:10
276 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
JSR-303 allows you to define declarative validation constraints against such properties:
public class PersonForm {
@NotNull
@Size(max=64)
private String name;
@Min(0)
private int age;
}
When an instance of this class is validated by a JSR-303 Validator, these constraints will
be enforced.
For general information on JSR-303/JSR-349, see the Bean Validation website. For
information on the specific capabilities of the default reference implementation, see the
Hibernate Validator documentation. To learn how to setup a Bean Validation provider as a
Spring bean, keep reading.
25/08/2016 12:10
277 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
application.
Use the LocalValidatorFactoryBean to configure a default Validator as a Spring
bean:
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
The basic configuration above will trigger Bean Validation to initialize using its default
bootstrap mechanism. A JSR-303/JSR-349 provider, such as Hibernate Validator, is
expected to be present in the classpath and will be detected automatically.
Injecting a Validator
LocalValidatorFactoryBean implements both
javax.validation.ValidatorFactory and javax.validation.Validator , as well
as Springs org.springframework.validation.Validator . You may inject a
reference to either of these interfaces into beans that need to invoke validation logic.
Inject a reference to javax.validation.Validator if you prefer to work with the Bean
Validation API directly:
import javax.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;
25/08/2016 12:10
278 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Each Bean Validation constraint consists of two parts. First, a @Constraint annotation
that declares the constraint and its configurable properties. Second, an implementation of
the javax.validation.ConstraintValidator interface that implements the
constraints behavior. To associate a declaration with an implementation, each
@Constraint annotation references a corresponding ValidationConstraint
implementation class. At runtime, a ConstraintValidatorFactory instantiates the
referenced implementation when the constraint annotation is encountered in your domain
model.
By default, the LocalValidatorFactoryBean configures a
SpringConstraintValidatorFactory that uses Spring to create ConstraintValidator
instances. This allows your custom ConstraintValidators to benefit from dependency
injection like any other Spring bean.
Shown below is an example of a custom @Constraint declaration, followed by an
associated ConstraintValidator implementation that uses Spring for dependency
injection:
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MyConstraintValidator.class)
public @interface MyConstraint {
}
import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
@Autowired;
private Foo aDependency;
...
}
25/08/2016 12:10
279 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcess
In order to be eligible for Spring-driven method validation, all target classes need to be
annotated with Springs @Validated annotation, optionally declaring the validation
groups to use. Check out the MethodValidationPostProcessor javadocs for setup
details with Hibernate Validator and Bean Validation 1.1 providers.
280 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
281 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
282 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
SpEL also supports nested properties using standard dot notation, i.e. prop1.prop2.prop3
and the setting of property values
Public fields may also be accessed.
ExpressionParser parser = new SpelExpressionParser();
// invokes 'getBytes().length'
Expression exp = parser.parseExpression("'Hello World'.bytes.length");
int length = (Integer) exp.getValue();
25/08/2016 12:10
283 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The more common usage of SpEL is to provide an expression string that is evaluated
against a specific object instance (called the root object). There are two options here and
which to choose depends on whether the object against which the expression is being
evaluated will be changing with each call to evaluate the expression. In the following
example we retrieve the name property from an instance of the Inventor class.
// Create and set a calendar
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
// The constructor arguments are name, birthday, and nationality.
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name");
EvaluationContext context = new StandardEvaluationContext(tesla);
String name = (String) exp.getValue(context);
In the last line, the value of the string variable name will be set to "Nikola Tesla". The
class StandardEvaluationContext is where you can specify which object the "name"
property will be evaluated against. This is the mechanism to use if the root object is
unlikely to change, it can simply be set once in the evaluation context. If the root object is
likely to change repeatedly, it can be supplied on each call to getValue , as this next
example shows:
/ Create and set a calendar
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
// The constructor arguments are name, birthday, and nationality.
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name");
String name = (String) exp.getValue(tesla);
In this case the inventor tesla has been supplied directly to getValue and the
expression evaluation infrastructure creates and manages a default evaluation context
internally - it did not require one to be supplied.
The StandardEvaluationContext is relatively expensive to construct and during repeated
usage it builds up cached state that enables subsequent expression evaluations to be
performed more quickly. For this reason it is better to cache and reuse them where
25/08/2016 12:10
284 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
In some cases it can be desirable to use a configured evaluation context and yet still
supply a different root object on each call to getValue . getValue allows both to be
specified on the same call. In these situations the root object passed on the call is
considered to override any (which maybe null) specified on the evaluation context.
As a final introductory example, the use of a boolean operator is shown using the Inventor
object in the previous example.
Expression exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(context, Boolean.class); // evaluates to true
Type Conversion
25/08/2016 12:10
285 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
286 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
// Turn on:
// - auto null reference initialization
// - auto collection growing
SpelParserConfiguration config = new SpelParserConfiguration(true,true);
ExpressionParser parser = new SpelExpressionParser(config);
Expression expression = parser.parseExpression("list[3]");
Demo demo = new Demo();
Object o = expression.getValue(demo);
// demo.list will now be a real collection of 4 entries
// Each entry is a new empty String
25/08/2016 12:10
287 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
iterations, it was taking 75ms to evaluate using only the interpreter and just 3ms using the
compiled version of the expression.
Compiler configuration
The compiler is not turned on by default, but there are two ways to turn it on. It can be
turned on using the parser configuration process discussed earlier or via a system
property when SpEL usage is embedded inside another component. This section
discusses both of these options.
Is is important to understand that there are a few modes the compiler can operate in,
captured in an enum ( org.springframework.expression.spel.SpelCompilerMode ).
The modes are as follows:
OFF - The compiler is switched off; this is the default.
IMMEDIATE - In immediate mode the expressions are compiled as soon as possible.
This is typically after the first interpreted evaluation. If the compiled expression fails
(typically due to a type changing, as described above) then the caller of the
expression evaluation will receive an exception.
MIXED - In mixed mode the expressions silently switch between interpreted and
compiled mode over time. After some number of interpreted runs they will switch to
compiled form and if something goes wrong with the compiled form (like a type
changing, as described above) then the expression will automatically switch back to
interpreted form again. Sometime later it may generate another compiled form and
switch to it. Basically the exception that the user gets in IMMEDIATE mode is instead
handled internally.
IMMEDIATE mode exists because MIXED mode could cause issues for expressions that
have side effects. If a compiled expression blows up after partially succeeding it may
have already done something that has affected the state of the system. If this has
happened the caller may not want it to silently re-run in interpreted mode since part of the
expression may be running twice.
After selecting a mode, use the SpelParserConfiguration to configure the parser:
25/08/2016 12:10
288 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
When specifying the compiler mode it is also possible to specify a classloader (passing
null is allowed). Compiled expressions will be defined in a child classloader created under
any that is supplied. It is important to ensure if a classloader is specified it can see all the
types involved in the expression evaluation process. If none is specified then a default
classloader will be used (typically the context classloader for the thread that is running
during expression evaluation).
The second way to configure the compiler is for use when SpEL is embedded inside
some other component and it may not be possible to configure via a configuration object.
In these cases it is possible to use a system property. The property
spring.expression.compiler.mode can be set to one of the SpelCompilerMode
enum values ( off , immediate , or mixed ).
Compiler limitations
With Spring Framework 4.1 the basic compilation framework is in place. However, the
framework does not yet support compiling every kind of expression. The initial focus has
been on the common expressions that are likely to be used in performance critical
contexts. These kinds of expression cannot be compiled at the moment:
expressions involving assignment
expressions relying on the conversion service
expressions using custom resolvers or accessors
expressions using selection or projection
More and more types of expression will be compilable in the future.
25/08/2016 12:10
289 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
You can also refer to other bean properties by name, for example.
<bean id="numberGuess" class="org.spring.samples.NumberGuess">
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"
<!-- other properties -->
</bean>
<bean id="shapeGuess" class="org.spring.samples.ShapeGuess">
<property name="initialShapeSeed" value="#{ numberGuess.randomNumber }"/>
<!-- other properties -->
</bean>
25/08/2016 12:10
290 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Autowired methods and constructors can also use the @Value annotation.
public class SimpleMovieLister {
private MovieFinder movieFinder;
private String defaultLocale;
@Autowired
public void configure(MovieFinder movieFinder,
@Value("#{ systemProperties['user.region'] }") String defaultLocale) {
this.movieFinder = movieFinder;
this.defaultLocale = defaultLocale;
}
// ...
}
public class MovieRecommender {
private String defaultLocale;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
25/08/2016 12:10
291 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Numbers support the use of the negative sign, exponential notation, and decimal points.
By default real numbers are parsed using Double.parseDouble().
25/08/2016 12:10
292 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Teslas year of birth and Pupins city of birth the following expressions are used.
// evals to 1856
int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context)
String city = (String) parser.parseExpression("placeOfBirth.City").getValue(context);
Case insensitivity is allowed for the first letter of property names. The contents of arrays
and lists are obtained using square bracket notation.
ExpressionParser parser = new SpelExpressionParser();
// Inventions Array
StandardEvaluationContext teslaContext = new StandardEvaluationContext(tesla);
// evaluates to "Induction motor"
String invention = parser.parseExpression("inventions[3]").getValue(
teslaContext, String.class);
// Members List
StandardEvaluationContext societyContext = new StandardEvaluationContext(ieee);
// evaluates to "Nikola Tesla"
String name = parser.parseExpression("Members[0].Name").getValue(
societyContext, String.class);
// List and Array navigation
// evaluates to "Wireless communication"
String invention = parser.parseExpression("Members[0].Inventions[6]").getValue(
societyContext, String.class);
The contents of maps are obtained by specifying the literal key value within the brackets.
In this case, because keys for the Officers map are strings, we can specify string literals.
// Officer's Dictionary
Inventor pupin = parser.parseExpression("Officers['president']").getValue(
societyContext, Inventor.class);
// evaluates to "Idvor"
String city = parser.parseExpression("Officers['president'].PlaceOfBirth.City"
societyContext, String.class);
// setting values
parser.parseExpression("Officers['advisors'][0].PlaceOfBirth.Country").setValue(
societyContext, "Croatia");
25/08/2016 12:10
293 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
{} by itself means an empty list. For performance reasons, if the list is itself entirely
composed of fixed literals then a constant list is created to represent the expression,
rather than building a new list on each evaluation.
{:} by itself means an empty map. For performance reasons, if the map is itself
composed of fixed literals or other nested constant structures (lists or maps) then a
constant map is created to represent the expression, rather than building a new map on
each evaluation. Quoting of the map keys is optional, the examples above are not using
quoted keys.
25/08/2016 12:10
294 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
10.5.6 Methods
Methods are invoked using typical Java programming syntax. You may also invoke
methods on literals. Varargs are also supported.
// string literal, evaluates to "bc"
String c = parser.parseExpression("'abc'.substring(2, 3)").getValue(String.class
// evaluates to true
boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(
societyContext, Boolean.class);
10.5.7 Operators
Relational operators
The relational operators; equal, not equal, less than, less than or equal, greater than, and
greater than or equal are supported using standard operator notation.
// evaluates to true
boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class);
// evaluates to false
boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class
// evaluates to true
boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.
In addition to standard relational operators SpEL supports the instanceof and regular
expression based matches operator.
// evaluates to false
boolean falseValue = parser.parseExpression(
"'xyz' instanceof T(Integer.class)").getValue(Boolean.class);
// evaluates to true
boolean trueValue = parser.parseExpression(
"'5.00' matches '\^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
//evaluates to false
boolean falseValue = parser.parseExpression(
"'5.0067' matches '\^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
25/08/2016 12:10
295 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Each symbolic operator can also be specified as a purely alphabetic equivalent. This
avoids problems where the symbols used have special meaning for the document type in
which the expression is embedded (eg. an XML document). The textual equivalents are
shown here: lt ( < ), gt ( > ), le ( ), ge ( >= ), eq ( == ), ne ( != ), div ( / ), mod
( % ), not ( ! ). These are case insensitive.
Logical operators
The logical operators that are supported are and, or, and not. Their use is demonstrated
below.
// -- AND -// evaluates to false
boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.
// evaluates to true
String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')"
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolea
// -- OR -// evaluates to true
boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.
// evaluates to true
String expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')"
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolea
// -- NOT -// evaluates to false
boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class);
// -- AND and NOT -String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')"
boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boole
Mathematical operators
25/08/2016 12:10
296 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The addition operator can be used on both numbers and strings. Subtraction,
multiplication and division can be used only on numbers. Other mathematical operators
supported are modulus (%) and exponential power (^). Standard operator precedence is
enforced. These operators are demonstrated below.
// Addition
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2
String testString = parser.parseExpression(
"'test' + ' ' + 'string'").getValue(String.class); // 'test string'
// Subtraction
int four = parser.parseExpression("1 - -3").getValue(Integer.class); // 4
double d = parser.parseExpression("1000.00 - 1e4").getValue(Double.class); // -9000
// Multiplication
int six = parser.parseExpression("-2 * -3").getValue(Integer.class); // 6
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.
// Division
int minusTwo = parser.parseExpression("6 / -3").getValue(Integer.class); // -2
double one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double.class);
// Modulus
int three = parser.parseExpression("7 % 4").getValue(Integer.class); // 3
int one = parser.parseExpression("8 / 5 % 2").getValue(Integer.class); // 1
// Operator precedence
int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class
10.5.8 Assignment
Setting of a property is done by using the assignment operator. This would typically be
done within a call to setValue but can also be done inside a call to getValue .
Inventor inventor = new Inventor();
StandardEvaluationContext inventorContext = new StandardEvaluationContext(inventor);
parser.parseExpression("Name").setValue(inventorContext, "Alexander Seovic2"
// alternatively
25/08/2016 12:10
297 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
10.5.9 Types
The special T operator can be used to specify an instance of java.lang.Class (the type).
Static methods are invoked using this operator as well. The
StandardEvaluationContext uses a TypeLocator to find types and the
StandardTypeLocator (which can be replaced) is built with an understanding of the
java.lang package. This means T() references to types within java.lang do not need to be
fully qualified, but all other type references must be.
Class dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class.
Class stringClass = parser.parseExpression("T(String)").getValue(Class.class
boolean trueValue = parser.parseExpression(
"T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR"
.getValue(Boolean.class);
10.5.10 Constructors
Constructors can be invoked using the new operator. The fully qualified class name
should be used for all but the primitive type and String (where int, float, etc, can be used).
Inventor einstein = p.parseExpression(
"new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')"
.getValue(Inventor.class);
//create new inventor instance within add method of List
p.parseExpression(
"Members.add(new org.spring.samples.spel.inventor.Inventor(
'Albert Einstein', 'German'))").getValue(societyContext);
10.5.11 Variables
Variables can be referenced in the expression using the syntax #variableName .
Variables are set using the method setVariable on the StandardEvaluationContext .
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
StandardEvaluationContext context = new StandardEvaluationContext(tesla);
25/08/2016 12:10
298 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
10.5.12 Functions
You can extend SpEL by registering user defined functions that can be called within the
expression string. The function is registered with the StandardEvaluationContext
using the method.
public void registerFunction(String name, Method m)
A reference to a Java Method provides the implementation of the function. For example, a
utility method to reverse a string is shown below.
public abstract class StringUtils {
public static String reverseString(String input) {
StringBuilder backwards = new StringBuilder();
for (int i = 0; i < input.length(); i++)
backwards.append(input.charAt(input.length() - 1 - i));
25/08/2016 12:10
299 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
return backwards.toString();
}
}
This method is then registered with the evaluation context and can be used within an
expression string.
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.registerFunction("reverseString",
StringUtils.class.getDeclaredMethod("reverseString", new Class[] { String.
String helloWorldReversed = parser.parseExpression(
"#reverseString('hello')").getValue(context, String.class);
To access a factory bean itself, the bean name should instead be prefixed with a (&)
symbol.
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new MyBeanResolver());
25/08/2016 12:10
300 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
In this case, the boolean false results in returning the string value 'falseExp'. A more
realistic example is shown below.
parser.parseExpression("Name").setValue(societyContext, "IEEE");
societyContext.setVariable("queryName", "Nikola Tesla");
Also see the next section on the Elvis operator for an even shorter syntax for the ternary
operator.
Instead you can use the Elvis operator, named for the resemblance to Elvis' hair style.
ExpressionParser parser = new SpelExpressionParser();
String name = parser.parseExpression("name?:'Unknown'").getValue(String.class
System.out.println(name); // 'Unknown'
25/08/2016 12:10
301 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The Elvis operator can be used to apply default values in expressions, e.g.
in an @Value expression:
@Value("#{systemProperties['pop3.port'] ?: 25}")
25/08/2016 12:10
302 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Selection uses the syntax ?[selectionExpression] . This will filter the collection and
return a new collection containing a subset of the original elements. For example,
selection would allow us to easily get a list of Serbian inventors:
List<Inventor> list = (List<Inventor>) parser.parseExpression(
"Members.?[Nationality == 'Serbian']").getValue(societyContext);
Selection is possible upon both lists and maps. In the former case the selection criteria is
evaluated against each individual list element whilst against a map the selection criteria is
evaluated against each map entry (objects of the Java type Map.Entry ). Map entries
have their key and value accessible as properties for use in the selection.
This expression will return a new map consisting of those elements of the original map
where the entry value is less than 27.
Map newMap = parser.parseExpression("map.?[value<27]").getValue();
In addition to returning all the selected elements, it is possible to retrieve just the first or
the last value. To obtain the first entry matching the selection the syntax is ^[] whilst to
obtain the last matching selection the syntax is $[] .
A map can also be used to drive projection and in this case the projection expression is
evaluated against each entry in the map (represented as a Java Map.Entry ). The result
of a projection across a map is a list consisting of the evaluation of the projection
expression against each map entry.
25/08/2016 12:10
303 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The string is evaluated by concatenating the literal text 'random number is ' with the result
of evaluating the expression inside the #{ } delimiter, in this case the result of calling that
random() method. The second argument to the method parseExpression() is of the
type ParserContext . The ParserContext interface is used to influence how the
expression is parsed in order to support the expression templating functionality. The
definition of TemplateParserContext is shown below.
public class TemplateParserContext implements ParserContext {
public String getExpressionPrefix() {
return "#{";
}
public String getExpressionSuffix() {
return "}";
}
public boolean isTemplate() {
return true;
}
}
25/08/2016 12:10
304 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
305 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
public void setInventions(String[] inventions) {
this.inventions = inventions;
}
public String[] getInventions() {
return inventions;
}
}
PlaceOfBirth.java
package org.spring.samples.spel.inventor;
public class PlaceOfBirth {
private String city;
private String country;
public PlaceOfBirth(String city) {
this.city=city;
}
public PlaceOfBirth(String city, String country) {
this(city);
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String s) {
this.city = s;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
25/08/2016 12:10
306 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
package org.spring.samples.spel.inventor;
import java.util.*;
public class Society {
private String name;
public static String Advisors = "advisors";
public static String President = "president";
private List<Inventor> members = new ArrayList<Inventor>();
private Map officers = new HashMap();
public List getMembers() {
return members;
}
public Map getOfficers() {
return officers;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isMember(String name) {
for (Inventor inventor : members) {
if (inventor.getName().equals(name)) {
return true;
}
}
return false;
}
}
307 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
308 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
309 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
310 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
is not to provide the most complete AOP implementation (although Spring AOP is quite
capable); it is rather to provide a close integration between AOP implementation and
Spring IoC to help solve common problems in enterprise applications.
Thus, for example, the Spring Frameworks AOP functionality is normally used in
conjunction with the Spring IoC container. Aspects are configured using normal bean
definition syntax (although this allows powerful "autoproxying" capabilities): this is a
crucial difference from other AOP implementations. There are some things you cannot do
easily or efficiently with Spring AOP, such as advise very fine-grained objects (such as
domain objects typically): AspectJ is the best choice in such cases. However, our
experience is that Spring AOP provides an excellent solution to most problems in
enterprise Java applications that are amenable to AOP.
Spring AOP will never strive to compete with AspectJ to provide a comprehensive AOP
solution. We believe that both proxy-based frameworks like Spring AOP and full-blown
frameworks such as AspectJ are valuable, and that they are complementary, rather than
in competition. Spring seamlessly integrates Spring AOP and IoC with AspectJ, to enable
all uses of AOP to be catered for within a consistent Spring-based application
architecture. This integration does not affect the Spring AOP API or the AOP Alliance API:
Spring AOP remains backward-compatible. See the following chapter for a discussion of
the Spring AOP APIs.
25/08/2016 12:10
311 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
See Section 11.4, Choosing which AOP declaration style to use for a more
complete discussion of the whys and wherefores of each style.
Using the AspectJ compiler and weaver enables use of the full AspectJ
language, and is discussed in Section 11.8, Using AspectJ with Spring
applications.
25/08/2016 12:10
312 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
generate a proxy for that bean to intercept method invocations and ensure that advice is
executed as needed.
The @AspectJ support can be enabled with XML or Java style configuration. In either
case you will also need to ensure that AspectJs aspectjweaver.jar library is on the
classpath of your application (version 1.6.8 or later). This library is available in the 'lib'
directory of an AspectJ distribution or via the Maven Central repository.
This assumes that you are using schema support as described in Chapter 41, XML
Schema-based configuration. See Section 41.2.7, the aop schema for how to import the
tags in the aop namespace.
25/08/2016 12:10
313 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Aspects (classes annotated with @Aspect ) may have methods and fields just like any
other class. They may also contain pointcut, advice, and introduction (inter-type)
declarations.
You may register aspect classes as regular beans in your Spring XML
configuration, or autodetect them through classpath scanning - just like any
other Spring-managed bean. However, note that the @Aspect annotation is
not sufficient for autodetection in the classpath: For that purpose, you need
to add a separate @Component annotation (or alternatively a custom
stereotype annotation that qualifies, as per the rules of Springs component
scanner).
25/08/2016 12:10
314 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
An example will help make this distinction between a pointcut signature and a pointcut
expression clear. The following example defines a pointcut named 'anyOldTransfer'
that will match the execution of any method named 'transfer' :
@Pointcut("execution(* transfer(..))")// the pointcut expression
private void anyOldTransfer() {}// the pointcut signature
The pointcut expression that forms the value of the @Pointcut annotation is a regular
AspectJ 5 pointcut expression. For a full discussion of AspectJs pointcut language, see
the AspectJ Programming Guide (and for extensions, the AspectJ 5 Developers
Notebook) or one of the books on AspectJ such as "Eclipse AspectJ" by Colyer et. al. or
"AspectJ in Action" by Ramnivas Laddad.
The full AspectJ pointcut language supports additional pointcut designators that are
not supported in Spring. These are:
call, get, set, preinitialization, staticinitialization, initialization, handle
and @withincode . Use of these pointcut designators in pointcut expressions
interpreted by Spring AOP will result in an IllegalArgumentException being
thrown.
The set of pointcut designators supported by Spring AOP may be extended in future
releases to support more of the AspectJ pointcut designators.
execution - for matching method execution join points, this is the primary pointcut
designator you will use when working with Spring AOP
within - limits matching to join points within certain types (simply the execution of a
method declared within a matching type when using Spring AOP)
this - limits matching to join points (the execution of methods when using Spring
AOP) where the bean reference (Spring AOP proxy) is an instance of the given type
target - limits matching to join points (the execution of methods when using Spring
AOP) where the target object (application object being proxied) is an instance of the
given type
args - limits matching to join points (the execution of methods when using Spring
AOP) where the arguments are instances of the given types
@target - limits matching to join points (the execution of methods when using Spring
25/08/2016 12:10
315 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
AOP) where the class of the executing object has an annotation of the given type
@args - limits matching to join points (the execution of methods when using Spring
AOP) where the runtime type of the actual arguments passed have annotations of the
given type(s)
@within - limits matching to join points within types that have the given annotation
(the execution of methods declared in types with the given annotation when using
Spring AOP)
@annotation - limits matching to join points where the subject of the join point
(method being executed in Spring AOP) has the given annotation
Because Spring AOP limits matching to only method execution join points, the discussion
of the pointcut designators above gives a narrower definition than you will find in the
AspectJ programming guide. In addition, AspectJ itself has type-based semantics and at
an execution join point both this and target refer to the same object - the object
executing the method. Spring AOP is a proxy-based system and differentiates between
the proxy object itself (bound to this ) and the target object behind the proxy (bound to
target ).
Spring AOP also supports an additional PCD named bean . This PCD allows you to limit
the matching of join points to a particular named Spring bean, or to a set of named Spring
beans (when using wildcards). The bean PCD has the following form:
bean(idOrNameOfBean)
The idOrNameOfBean token can be the name of any Spring bean: limited wildcard
support using the * character is provided, so if you establish some naming conventions
for your Spring beans you can quite easily write a bean PCD expression to pick them
out. As is the case with other pointcut designators, the bean PCD can be &&'ed, ||'ed,
25/08/2016 12:10
316 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Please note that the bean PCD is only supported in Spring AOP - and not
in native AspectJ weaving. It is a Spring-specific extension to the standard
PCDs that AspectJ defines and therefore not available for aspects declared
in the @Aspect model.
The bean PCD operates at the instance level (building on the Spring bean
name concept) rather than at the type level only (which is what
weaving-based AOP is limited to). Instance-based pointcut designators are
a special capability of Springs proxy-based AOP framework and its close
integration with the Spring bean factory, where it is natural and
straightforward to identify specific beans by name.
It is a best practice to build more complex pointcut expressions out of smaller named
components as shown above. When referring to pointcuts by name, normal Java visibility
rules apply (you can see private pointcuts in the same type, protected pointcuts in the
hierarchy, public pointcuts anywhere and so on). Visibility does not affect pointcut
matching.
25/08/2016 12:10
317 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
package com.xyz.someapp;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class SystemArchitecture {
/**
* A join point is in the web layer if the method is defined
* in a type in the com.xyz.someapp.web package or any sub-package
* under that.
*/
@Pointcut("within(com.xyz.someapp.web..*)")
public void inWebLayer() {}
/**
* A join point is in the service layer if the method is defined
* in a type in the com.xyz.someapp.service package or any sub-package
* under that.
*/
@Pointcut("within(com.xyz.someapp.service..*)")
public void inServiceLayer() {}
/**
* A join point is in the data access layer if the method is defined
* in a type in the com.xyz.someapp.dao package or any sub-package
* under that.
*/
@Pointcut("within(com.xyz.someapp.dao..*)")
public void inDataAccessLayer() {}
/**
* A business service is the execution of any method defined on a service
* interface. This definition assumes that interfaces are placed in the
* "service" package, and that implementation types are in sub-packages.
*
* If you group service interfaces by functional area (for example,
* in packages com.xyz.someapp.abc.service and com.xyz.someapp.def.service) then
* the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))"
* could be used instead.
*
* Alternatively, you can write the expression using the 'bean'
* PCD, like so "bean(*Service)". (This assumes that you have
* named your Spring service beans in a consistent fashion.)
*/
@Pointcut("execution(* com.xyz.someapp..service.*.*(..))")
25/08/2016 12:10
318 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
/**
* A data access operation is the execution of any method defined on a
* dao interface. This definition assumes that interfaces are placed in the
* "dao" package, and that implementation types are in sub-packages.
*/
@Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")
public void dataAccessOperation() {}
}
The pointcuts defined in such an aspect can be referred to anywhere that you need a
pointcut expression. For example, to make the service layer transactional, you could
write:
<aop:config>
<aop:advisor
pointcut="com.xyz.someapp.SystemArchitecture.businessService()"
advice-ref="tx-advice"/>
</aop:config>
<tx:advice id="tx-advice">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
Examples
Spring AOP users are likely to use the execution pointcut designator the most often.
The format of an execution expression is:
All parts except the returning type pattern (ret-type-pattern in the snippet above), name
pattern, and parameters pattern are optional. The returning type pattern determines what
the return type of the method must be in order for a join point to be matched. Most
frequently you will use * as the returning type pattern, which matches any return type. A
fully-qualified type name will match only when the method returns the given type. The
25/08/2016 12:10
319 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
name pattern. If specifying a declaring type pattern then include a trailing . to join it to
the name pattern component. The parameters pattern is slightly more complex: ()
matches a method that takes no parameters, whereas (..) matches any number of
parameters (zero or more). The pattern (*) matches a method taking one parameter of
any type, (*,String) matches a method taking two parameters, the first can be of any
type, the second must be a String. Consult the Language Semantics section of the
AspectJ Programming Guide for more information.
Some examples of common pointcut expressions are given below.
the execution of any public method:
execution(public * *(..))
any join point (method execution only in Spring AOP) within the service package:
within(com.xyz.service.*)
any join point (method execution only in Spring AOP) within the service package or a
sub-package:
within(com.xyz.service..*)
any join point (method execution only in Spring AOP) where the proxy implements
the AccountService interface:
this(com.xyz.service.AccountService)
25/08/2016 12:10
320 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
'this' is more commonly used in a binding form :- see the following section
on advice for how to make the proxy object available in the advice body.
any join point (method execution only in Spring AOP) where the target object
implements the AccountService interface:
target(com.xyz.service.AccountService)
'target' is more commonly used in a binding form :- see the following section
on advice for how to make the target object available in the advice body.
any join point (method execution only in Spring AOP) which takes a single parameter,
and where the argument passed at runtime is Serializable :
args(java.io.Serializable)
'args' is more commonly used in a binding form :- see the following section
on advice for how to make the method arguments available in the advice
body.
'@target' can also be used in a binding form :- see the following section on
advice for how to make the annotation object available in the advice body.
any join point (method execution only in Spring AOP) where the declared type of the
target object has an @Transactional annotation:
25/08/2016 12:10
321 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
'@within' can also be used in a binding form :- see the following section on
advice for how to make the annotation object available in the advice body.
any join point (method execution only in Spring AOP) where the executing method
has an @Transactional annotation:
@annotation(org.springframework.transaction.annotation.Transactional)
any join point (method execution only in Spring AOP) which takes a single parameter,
and where the runtime type of the argument passed has the @Classified
annotation:
@args(com.xyz.security.Classified)
'@args' can also be used in a binding form :- see the following section on
advice for how to make the annotation object(s) available in the advice
body.
any join point (method execution only in Spring AOP) on a Spring bean named
tradeService :
bean(tradeService)
any join point (method execution only in Spring AOP) on Spring beans having names
that match the wildcard expression *Service :
bean(*Service)
25/08/2016 12:10
322 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
determine if there is an actual match when the code is running). On first encountering a
pointcut declaration, AspectJ will rewrite it into an optimal form for the matching process.
What does this mean? Basically pointcuts are rewritten in DNF (Disjunctive Normal Form)
and the components of the pointcut are sorted such that those components that are
cheaper to evaluate are checked first. This means you do not have to worry about
understanding the performance of various pointcut designators and may supply them in
any order in a pointcut declaration.
However, AspectJ can only work with what it is told, and for optimal performance of
matching you should think about what they are trying to achieve and narrow the search
space for matches as much as possible in the definition. The existing designators
naturally fall into one of three groups: kinded, scoping and context:
Kinded designators are those which select a particular kind of join point. For example:
execution, get, set, call, handler
Scoping designators are those which select a group of join points of interest (of
probably many kinds). For example: within, withincode
Contextual designators are those that match (and optionally bind) based on context.
For example: this, target, @annotation
A well written pointcut should try and include at least the first two types (kinded and
scoping), whilst the contextual designators may be included if wishing to match based on
join point context, or bind that context for use in the advice. Supplying either just a kinded
designator or just a contextual designator will work but could affect weaving performance
(time and memory used) due to all the extra processing and analysis. Scoping
designators are very fast to match and their usage means AspectJ can very quickly
dismiss groups of join points that should not be further processed - that is why a good
pointcut should always include one if possible.
Before advice
Before advice is declared in an aspect using the @Before annotation:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
25/08/2016 12:10
323 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Aspect
public class BeforeExample {
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
}
If using an in-place pointcut expression we could rewrite the above example as:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class BeforeExample {
@Before("execution(* com.xyz.myapp.dao.*.*(..))")
public void doAccessCheck() {
// ...
}
}
25/08/2016 12:10
324 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
members as well, all inside the same aspect. Were just showing a single
advice declaration in these examples to focus on the issue under discussion
at the time.
Sometimes you need access in the advice body to the actual value that was returned.
You can use the form of @AfterReturning that binds the return value for this:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
@Aspect
public class AfterReturningExample {
@AfterReturning(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
returning="retVal")
public void doAccessCheck(Object retVal) {
// ...
}
}
The name used in the returning attribute must correspond to the name of a parameter
in the advice method. When a method execution returns, the return value will be passed
to the advice method as the corresponding argument value. A returning clause also
restricts matching to only those method executions that return a value of the specified
type ( Object in this case, which will match any return value).
Please note that it is not possible to return a totally different reference when using afterreturning advice.
25/08/2016 12:10
325 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
// ...
}
}
Often you want the advice to run only when exceptions of a given type are thrown, and
you also often need access to the thrown exception in the advice body. Use the
throwing attribute to both restrict matching (if desired, use Throwable as the
exception type otherwise) and bind the thrown exception to an advice parameter.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
@Aspect
public class AfterThrowingExample {
@AfterThrowing(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
throwing="ex")
public void doRecoveryActions(DataAccessException ex) {
// ...
}
}
The name used in the throwing attribute must correspond to the name of a parameter
in the advice method. When a method execution exits by throwing an exception, the
exception will be passed to the advice method as the corresponding argument value. A
throwing clause also restricts matching to only those method executions that throw an
exception of the specified type ( DataAccessException in this case).
25/08/2016 12:10
326 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
// ...
}
}
Around advice
The final kind of advice is around advice. Around advice runs "around" a matched method
execution. It has the opportunity to do work both before and after the method executes,
and to determine when, how, and even if, the method actually gets to execute at all.
Around advice is often used if you need to share state before and after a method
execution in a thread-safe manner (starting and stopping a timer for example). Always
use the least powerful form of advice that meets your requirements (i.e. dont use around
advice if simple before advice would do).
Around advice is declared using the @Around annotation. The first parameter of the
advice method must be of type ProceedingJoinPoint . Within the body of the advice,
calling proceed() on the ProceedingJoinPoint causes the underlying method to
execute. The proceed method may also be called passing in an Object[] - the values
in the array will be used as the arguments to the method execution when it proceeds.
The behavior of proceed when called with an Object[] is a little different than
the behavior of proceed for around advice compiled by the AspectJ
compiler. For around advice written using the traditional AspectJ language,
the number of arguments passed to proceed must match the number of
arguments passed to the around advice (not the number of arguments
taken by the underlying join point), and the value passed to proceed in a
given argument position supplants the original value at the join point for the
entity the value was bound to (Dont worry if this doesnt make sense right
now!). The approach taken by Spring is simpler and a better match to its
proxy-based, execution only semantics. You only need to be aware of this
difference if you are compiling @AspectJ aspects written for Spring and
using proceed with arguments with the AspectJ compiler and weaver. There
is a way to write such aspects that is 100% compatible across both Spring
AOP and AspectJ, and this is discussed in the following section on advice
parameters.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
25/08/2016 12:10
327 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Aspect
public class AroundExample {
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
The value returned by the around advice will be the return value seen by the caller of the
method. A simple caching aspect for example could return a value from a cache if it has
one, and invoke proceed() if it does not. Note that proceed may be invoked once, many
times, or not at all within the body of the around advice, all of these are quite legal.
Advice parameters
Spring offers fully typed advice - meaning that you declare the parameters you need in
the advice signature (as we saw for the returning and throwing examples above) rather
than work with Object[] arrays all the time. Well see how to make argument and other
contextual values available to the advice body in a moment. First lets take a look at how
to write generic advice that can find out about the method the advice is currently advising.
25/08/2016 12:10
328 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
type name in an args expression, then the value of the corresponding argument will be
passed as the parameter value when the advice is invoked. An example should make this
clearer. Suppose you want to advise the execution of dao operations that take an Account
object as the first parameter, and you need access to the account in the advice body. You
could write the following:
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account) {
// ...
}
The args(account,..) part of the pointcut expression serves two purposes: firstly, it
restricts matching to only those method executions where the method takes at least one
parameter, and the argument passed to that parameter is an instance of Account ;
secondly, it makes the actual Account object available to the advice via the account
parameter.
Another way of writing this is to declare a pointcut that "provides" the Account object
value when it matches a join point, and then just refer to the named pointcut from the
advice. This would look as follows:
The interested reader is once more referred to the AspectJ programming guide for more
details.
The proxy object ( this ), target object ( target ), and annotations (
@within, @target, @annotation, @args ) can all be bound in a similar fashion. The
following example shows how you could match the execution of methods annotated with
an @Auditable annotation, and extract the audit code.
First the definition of the @Auditable annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditable {
AuditCode value();
}
25/08/2016 12:10
329 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
And then the advice that matches the execution of @Auditable methods:
@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable) {
AuditCode code = auditable.value();
// ...
}
You can restrict interception of method types to certain parameter types by simply typing
the advice parameter to the parameter type you want to intercept the method for:
@Before("execution(* ..Sample+.sampleGenericMethod(*)) && args(param)")
public void beforeSampleMethod(MyType param) {
// Advice implementation
}
That this works is pretty obvious as we already discussed above. However, its worth
pointing out that this wont work for generic collections. So you cannot define a pointcut
like this:
@Before("execution(* ..Sample+.sampleGenericCollectionMethod(*)) && args(param)")
public void beforeSampleMethod(Collection<MyType> param) {
// Advice implementation
}
To make this work we would have to inspect every element of the collection, which is not
reasonable as we also cannot decide how to treat null values in general. To achieve
something similar to this you have to type the parameter to Collection<?> and
manually check the type of the elements.
25/08/2016 12:10
330 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Parameter names are not available through Java reflection, so Spring AOP uses the
following strategies to determine parameter names:
If the parameter names have been specified by the user explicitly, then the specified
parameter names are used: both the advice and the pointcut annotations have an
optional "argNames" attribute which can be used to specify the argument names of
the annotated method - these argument names are available at runtime. For
example:
Using the 'argNames' attribute is a little clumsy, so if the 'argNames' attribute has
not been specified, then Spring AOP will look at the debug information for the class
and try to determine the parameter names from the local variable table. This
information will be present as long as the classes have been compiled with debug
25/08/2016 12:10
331 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
flag on are: (1) your code will be slightly easier to understand (reverse engineer), (2)
the class file sizes will be very slightly bigger (typically inconsequential), (3) the
optimization to remove unused local variables will not be applied by your compiler. In
other words, you should encounter no difficulties building with this flag on.
If the code has been compiled without the necessary debug information, then Spring
AOP will attempt to deduce the pairing of binding variables to parameters (for
example, if only one variable is bound in the pointcut expression, and the advice
method only takes one parameter, the pairing is obvious!). If the binding of variables
is ambiguous given the available information, then an
AmbiguousBindingException will be thrown.
If all of the above strategies fail then an IllegalArgumentException will be
thrown.
In many cases you will be doing this binding anyway (as in the example above).
Advice ordering
What happens when multiple pieces of advice all want to run at the same join point?
Spring AOP follows the same precedence rules as AspectJ to determine the order of
advice execution. The highest precedence advice runs first "on the way in" (so given two
pieces of before advice, the one with highest precedence runs first). "On the way out"
25/08/2016 12:10
332 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
from a join point, the highest precedence advice runs last (so given two pieces of after
advice, the one with the highest precedence will run second).
When two pieces of advice defined in different aspects both need to run at the same join
point, unless you specify otherwise the order of execution is undefined. You can control
the order of execution by specifying precedence. This is done in the normal Spring way
by either implementing the org.springframework.core.Ordered interface in the
aspect class or annotating it with the Order annotation. Given two aspects, the aspect
returning the lower value from Ordered.getValue() (or the annotation value) has the
higher precedence.
When two pieces of advice defined in the same aspect both need to run at the same join
point, the ordering is undefined (since there is no way to retrieve the declaration order via
reflection for javac-compiled classes). Consider collapsing such advice methods into one
advice method per join point in each aspect class, or refactor the pieces of advice into
separate aspect classes - which can be ordered at the aspect level.
11.2.5 Introductions
Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare
that advised objects implement a given interface, and to provide an implementation of
that interface on behalf of those objects.
An introduction is made using the @DeclareParents annotation. This annotation is used
to declare that matching types have a new parent (hence the name). For example, given
an interface UsageTracked , and an implementation of that interface
DefaultUsageTracked , the following aspect declares that all implementors of service
interfaces also implement the UsageTracked interface. (In order to expose statistics via
JMX for example.)
@Aspect
public class UsageTracking {
@DeclareParents(value="com.xzy.myapp.service.*+", defaultImpl=DefaultUsageTracked.
public static UsageTracked mixin;
25/08/2016 12:10
333 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The interface to be implemented is determined by the type of the annotated field. The
value attribute of the @DeclareParents annotation is an AspectJ type pattern :- any
bean of a matching type will implement the UsageTracked interface. Note that in the
before advice of the above example, service beans can be directly used as
implementations of the UsageTracked interface. If accessing a bean programmatically
you would write the following:
UsageTracked usageTracked = (UsageTracked) context.getBean("myService");
By default there will be a single instance of each aspect within the application context.
AspectJ calls this the singleton instantiation model. It is possible to define aspects with
alternate lifecycles :- Spring supports AspectJs perthis and pertarget instantiation
models ( percflow, percflowbelow, and pertypewithin are not currently
supported).
A "perthis" aspect is declared by specifying a perthis clause in the @Aspect
annotation. Lets look at an example, and then well explain how it works.
@Aspect("perthis(com.xyz.myapp.SystemArchitecture.businessService())")
public class MyAspect {
private int someState;
@Before(com.xyz.myapp.SystemArchitecture.businessService())
public void recordServiceUsage() {
// ...
}
}
The effect of the 'perthis' clause is that one aspect instance will be created for each
unique service object executing a business service (each unique object bound to 'this' at
join points matched by the pointcut expression). The aspect instance is created the first
time that a method is invoked on the service object. The aspect goes out of scope when
the service object goes out of scope. Before the aspect instance is created, none of the
25/08/2016 12:10
334 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
declared within it will execute at matched join points, but only when the service object is
the one this aspect is associated with. See the AspectJ programming guide for more
information on per-clauses.
The 'pertarget' instantiation model works in exactly the same way as perthis, but
creates one aspect instance for each unique target object at matched join points.
11.2.7 Example
Now that you have seen how all the constituent parts work, lets put them together to do
something useful!
The execution of business services can sometimes fail due to concurrency issues (for
example, deadlock loser). If the operation is retried, it is quite likely to succeed next time
round. For business services where it is appropriate to retry in such conditions
(idempotent operations that dont need to go back to the user for conflict resolution), wed
like to transparently retry the operation to avoid the client seeing a
PessimisticLockingFailureException . This is a requirement that clearly cuts across
multiple services in the service layer, and hence is ideal for implementing via an aspect.
Because we want to retry the operation, we will need to use around advice so that we can
call proceed multiple times. Heres how the basic aspect implementation looks:
@Aspect
public class ConcurrentOperationExecutor implements Ordered {
private static final int DEFAULT_MAX_RETRIES = 2;
private int maxRetries = DEFAULT_MAX_RETRIES;
private int order = 1;
public void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
}
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
25/08/2016 12:10
335 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Note that the aspect implements the Ordered interface so we can set the precedence of
the aspect higher than the transaction advice (we want a fresh transaction each time we
retry). The maxRetries and order properties will both be configured by Spring. The
main action happens in the doConcurrentOperation around advice. Notice that for the
moment were applying the retry logic to all businessService()s . We try to proceed,
and if we fail with an PessimisticLockingFailureException we simply try again
unless we have exhausted all of our retry attempts.
The corresponding Spring configuration is:
<aop:aspectj-autoproxy/>
To refine the aspect so that it only retries idempotent operations, we might define an
Idempotent annotation:
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
// marker annotation
}
and use the annotation to annotate the implementation of service operations. The change
to the aspect to only retry idempotent operations simply involves refining the pointcut
expression so that only @Idempotent operations match:
25/08/2016 12:10
336 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
337 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
...
</aop:aspect>
</aop:config>
<bean id="aBean" class="...">
...
</bean>
The bean backing the aspect (" `aBean`" in this case) can of course be configured and
dependency injected just like any other Spring bean.
Note that the pointcut expression itself is using the same AspectJ pointcut expression
language as described in Section 11.2, @AspectJ support. If you are using the schema
based declaration style, you can refer to named pointcuts defined in types (@Aspects)
within the pointcut expression. Another way of defining the above pointcut would be:
<aop:config>
<aop:pointcut id="businessService"
expression="com.xyz.myapp.SystemArchitecture.businessService()"/>
</aop:config>
25/08/2016 12:10
338 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
<aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..))"/>
...
</aop:aspect>
</aop:config>
Much the same way in an @AspectJ aspect, pointcuts declared using the schema based
definition style may collect join point context. For example, the following pointcut collects
the 'this' object as the join point context and passes it to advice:
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
<aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..)) && this(ser
<aop:before pointcut-ref="businessService" method="monitor"/>
...
</aop:aspect>
</aop:config>
The advice must be declared to receive the collected join point context by including
parameters of the matching names:
public void monitor(Object service) {
...
}
When combining pointcut sub-expressions, '&&' is awkward within an XML document, and
so the keywords 'and', 'or' and 'not' can be used in place of '&&', '||' and '!' respectively.
For example, the previous pointcut may be better written as:
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
25/08/2016 12:10
339 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..)) **and** this(servic
<aop:before pointcut-ref="businessService" method="monitor"/>
...
</aop:aspect>
</aop:config>
Note that pointcuts defined in this way are referred to by their XML id and cannot be used
as named pointcuts to form composite pointcuts. The named pointcut support in the
schema based definition style is thus more limited than that offered by the @AspectJ
style.
Before advice
Before advice runs before a matched method execution. It is declared inside an
<aop:aspect> using the <aop:before> element.
<aop:aspect id="beforeExample" ref="aBean">
<aop:before
pointcut-ref="dataAccessOperation"
method="doAccessCheck"/>
...
</aop:aspect>
25/08/2016 12:10
340 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
...
</aop:aspect>
As we noted in the discussion of the @AspectJ style, using named pointcuts can
significantly improve the readability of your code.
The method attribute identifies a method ( doAccessCheck ) that provides the body of the
advice. This method must be defined for the bean referenced by the aspect element
containing the advice. Before a data access operation is executed (a method execution
join point matched by the pointcut expression), the "doAccessCheck" method on the
aspect bean will be invoked.
Just as in the @AspectJ style, it is possible to get hold of the return value within the
advice body. Use the returning attribute to specify the name of the parameter to which the
return value should be passed:
<aop:aspect id="afterReturningExample" ref="aBean">
<aop:after-returning
pointcut-ref="dataAccessOperation"
returning="retVal"
method="doAccessCheck"/>
...
</aop:aspect>
The doAccessCheck method must declare a parameter named retVal . The type of this
25/08/2016 12:10
341 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
parameter constrains matching in the same way as described for @AfterReturning. For
example, the method signature may be declared as:
public void doAccessCheck(Object retVal) {...
Just as in the @AspectJ style, it is possible to get hold of the thrown exception within the
advice body. Use the throwing attribute to specify the name of the parameter to which the
exception should be passed:
<aop:aspect id="afterThrowingExample" ref="aBean">
<aop:after-throwing
pointcut-ref="dataAccessOperation"
throwing="dataAccessEx"
method="doRecoveryActions"/>
...
</aop:aspect>
25/08/2016 12:10
342 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Around advice
The final kind of advice is around advice. Around advice runs "around" a matched method
execution. It has the opportunity to do work both before and after the method executes,
and to determine when, how, and even if, the method actually gets to execute at all.
Around advice is often used if you need to share state before and after a method
execution in a thread-safe manner (starting and stopping a timer for example). Always
use the least powerful form of advice that meets your requirements; dont use around
advice if simple before advice would do.
Around advice is declared using the aop:around element. The first parameter of the
advice method must be of type ProceedingJoinPoint . Within the body of the advice,
calling proceed() on the ProceedingJoinPoint causes the underlying method to
execute. The proceed method may also be calling passing in an Object[] - the values
in the array will be used as the arguments to the method execution when it proceeds. See
the section called Around advice for notes on calling proceed with an Object[] .
<aop:aspect id="aroundExample" ref="aBean">
<aop:around
pointcut-ref="businessService"
method="doBasicProfiling"/>
...
</aop:aspect>
25/08/2016 12:10
343 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Advice parameters
The schema based declaration style supports fully typed advice in the same way as
described for the @AspectJ support - by matching pointcut parameters by name against
advice method parameters. See the section called Advice parameters for details. If you
wish to explicitly specify argument names for the advice methods (not relying on the
detection strategies previously described) then this is done using the arg-names
attribute of the advice element, which is treated in the same manner to the "argNames"
attribute in an advice annotation as described in the section called Determining argument
names. For example:
<aop:before
pointcut="com.xyz.lib.Pointcuts.anyPublicMethod() and @annotation(auditable)"
method="audit"
arg-names="auditable"/>
Next up is the aspect. Notice the fact that the profile(..) method accepts a number of
strongly-typed parameters, the first of which happens to be the join point used to proceed
with the method call: the presence of this parameter is an indication that the
profile(..) is to be used as around advice:
25/08/2016 12:10
344 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
package x.y;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.util.StopWatch;
public class SimpleProfiler {
public Object profile(ProceedingJoinPoint call, String name, int age) throws
StopWatch clock = new StopWatch("Profiling for '" + name + "' and '"
try {
clock.start(call.toShortString());
return call.proceed();
} finally {
clock.stop();
System.out.println(clock.prettyPrint());
}
}
}
Finally, here is the XML configuration that is required to effect the execution of the above
advice for a particular join point:
<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/sch
http://www.springframework.org/schema/aop http://www.springframework.org/schem
<!-- this is the object that will be proxied by Spring's AOP infrastructure -->
<bean id="fooService" class="x.y.service.DefaultFooService"/>
<!-- this is the actual advice itself -->
<bean id="profiler" class="x.y.SimpleProfiler"/>
<aop:config>
<aop:aspect ref="profiler">
<aop:pointcut id="theExecutionOfSomeFooServiceMethod"
expression="execution(* x.y.service.FooService.getFoo(String,int))
and args(name, age)"/>
<aop:around pointcut-ref="theExecutionOfSomeFooServiceMethod"
method="profile"/>
</aop:aspect>
</aop:config>
25/08/2016 12:10
345 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
</beans>
If we had the following driver script, we would get output something like this on standard
output:
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import x.y.service.FooService;
public final class Boot {
public static void main(final String[] args) throws Exception {
BeanFactory ctx = new ClassPathXmlApplicationContext("x/y/plain.xml"
FooService foo = (FooService) ctx.getBean("fooService");
foo.getFoo("Pengo", 12);
}
}
StopWatch 'Profiling for 'Pengo' and '12'': running time (millis) = 0
----------------------------------------ms
%
Task name
----------------------------------------00000 ? execution(getFoo)
Advice ordering
When multiple advice needs to execute at the same join point (executing method) the
ordering rules are as described in the section called Advice ordering. The precedence
between aspects is determined by either adding the Order annotation to the bean
backing the aspect or by having the bean implement the Ordered interface.
11.3.4 Introductions
Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare
that advised objects implement a given interface, and to provide an implementation of
that interface on behalf of those objects.
An introduction is made using the aop:declare-parents element inside an
aop:aspect This element is used to declare that matching types have a new parent
(hence the name). For example, given an interface UsageTracked , and an
implementation of that interface DefaultUsageTracked , the following aspect declares
that all implementors of service interfaces also implement the UsageTracked interface.
(In order to expose statistics via JMX for example.)
25/08/2016 12:10
346 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<aop:declare-parents
types-matching="com.xzy.myapp.service.*+"
implement-interface="com.xyz.myapp.service.tracking.UsageTracked"
default-impl="com.xyz.myapp.service.tracking.DefaultUsageTracked"/>
<aop:before
pointcut="com.xyz.myapp.SystemArchitecture.businessService()
and this(usageTracked)"
method="recordUsage"/>
</aop:aspect>
The class backing the usageTracking bean would contain the method:
public void recordUsage(UsageTracked usageTracked) {
usageTracked.incrementUseCount();
}
11.3.6 Advisors
The concept of "advisors" is brought forward from the AOP support defined in Spring 1.2
and does not have a direct equivalent in AspectJ. An advisor is like a small self-contained
aspect that has a single piece of advice. The advice itself is represented by a bean, and
must implement one of the advice interfaces described in Section 12.3.2, Advice types in
Spring. Advisors can take advantage of AspectJ pointcut expressions though.
Spring supports the advisor concept with the <aop:advisor> element. You will most
25/08/2016 12:10
347 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
As well as the pointcut-ref attribute used in the above example, you can also use the
pointcut attribute to define a pointcut expression inline.
To define the precedence of an advisor so that the advice can participate in ordering, use
the order attribute to define the Ordered value of the advisor.
11.3.7 Example
Lets see how the concurrent locking failure retry example from Section 11.2.7, Example
looks when rewritten using the schema support.
The execution of business services can sometimes fail due to concurrency issues (for
example, deadlock loser). If the operation is retried, it is quite likely it will succeed next
time round. For business services where it is appropriate to retry in such conditions
(idempotent operations that dont need to go back to the user for conflict resolution), wed
like to transparently retry the operation to avoid the client seeing a
PessimisticLockingFailureException . This is a requirement that clearly cuts across
multiple services in the service layer, and hence is ideal for implementing via an aspect.
Because we want to retry the operation, well need to use around advice so that we can
call proceed multiple times. Heres how the basic aspect implementation looks (its just a
regular Java class using the schema support):
public class ConcurrentOperationExecutor implements Ordered {
25/08/2016 12:10
348 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Note that the aspect implements the Ordered interface so we can set the precedence of
the aspect higher than the transaction advice (we want a fresh transaction each time we
retry). The maxRetries and order properties will both be configured by Spring. The
main action happens in the doConcurrentOperation around advice method. We try to
proceed, and if we fail with a PessimisticLockingFailureException we simply try
again unless we have exhausted all of our retry attempts.
This class is identical to the one used in the @AspectJ example, but with
the annotations removed.
25/08/2016 12:10
349 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<aop:config>
<aop:aspect id="concurrentOperationRetry" ref="concurrentOperationExecutor"
<aop:pointcut id="idempotentOperation"
expression="execution(* com.xyz.myapp.service.*.*(..))"/>
<aop:around
pointcut-ref="idempotentOperation"
method="doConcurrentOperation"/>
</aop:aspect>
</aop:config>
<bean id="concurrentOperationExecutor"
class="com.xyz.myapp.service.impl.ConcurrentOperationExecutor">
<property name="maxRetries" value="3"/>
<property name="order" value="100"/>
</bean>
Notice that for the time being we assume that all business services are idempotent. If this
is not the case we can refine the aspect so that it only retries genuinely idempotent
operations, by introducing an Idempotent annotation:
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
// marker annotation
}
and using the annotation to annotate the implementation of service operations. The
change to the aspect to retry only idempotent operations simply involves refining the
pointcut expression so that only @Idempotent operations match:
<aop:pointcut id="idempotentOperation"
expression="execution(* com.xyz.myapp.service.*.*(..)) and
@annotation(com.xyz.myapp.service.Idempotent)"/>
25/08/2016 12:10
350 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
351 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
- the aspect - in which this information is encapsulated. Secondly, the XML style is slightly
more limited in what it can express than the @AspectJ style: only the "singleton" aspect
instantiation model is supported, and it is not possible to combine named pointcuts
declared in XML. For example, in the @AspectJ style you can write something like:
@Pointcut(execution(* get*()))
public void propertyAccess() {}
@Pointcut(execution(org.xyz.Account+ *(..))
public void operationReturningAnAccount() {}
@Pointcut(propertyAccess() && operationReturningAnAccount())
public void accountPropertyAccess() {}
The downside of the XML approach is that you cannot define the
accountPropertyAccess pointcut by combining these definitions.
The @AspectJ style supports additional instantiation models, and richer pointcut
composition. It has the advantage of keeping the aspect as a modular unit. It also has the
advantage the @AspectJ aspects can be understood (and thus consumed) both by
Spring AOP and by AspectJ - so if you later decide you need the capabilities of AspectJ
to implement additional requirements then it is very easy to migrate to an AspectJ-based
approach. On balance the Spring team prefer the @AspectJ style whenever you have
aspects that do more than simple "configuration" of enterprise services.
25/08/2016 12:10
352 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
To force CGLIB proxying when using the @AspectJ autoproxy support, set the
'proxy-target-class' attribute of the <aop:aspectj-autoproxy> element to true :
<aop:aspectj-autoproxy proxy-target-class="true"/>
25/08/2016 12:10
353 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<aop:config/> elements will force the use of CGLIB proxies for all three
of them.
If you invoke a method on an object reference, the method is invoked directly on that
object reference, as can be seen below.
25/08/2016 12:10
354 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
}
Things change slightly when the reference that client code has is a proxy. Consider the
following diagram and code snippet.
The key thing to understand here is that the client code inside the main(..) of the
Main class has a reference to the proxy. This means that method calls on that object
reference will be calls on the proxy, and as such the proxy will be able to delegate to all of
the interceptors (advice) that are relevant to that particular method call. However, once
the call has finally reached the target object, the SimplePojo reference in this case, any
method calls that it may make on itself, such as this.bar() or this.foo() , are going
to be invoked against the this reference, and not the proxy. This has important
implications. It means that self-invocation is not going to result in the advice associated
with a method invocation getting a chance to execute.
Okay, so what is to be done about this? The best approach (the term best is used loosely
here) is to refactor your code such that the self-invocation does not happen. For sure, this
does entail some work on your part, but it is the best, least-invasive approach. The next
approach is absolutely horrendous, and I am almost reticent to point it out precisely
25/08/2016 12:10
355 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
because it is so horrendous. You can (choke!) totally tie the logic within your class to
Spring AOP by doing this:
public class SimplePojo implements Pojo {
public void foo() {
// this works, but... gah!
((Pojo) AopContext.currentProxy()).bar();
}
public void bar() {
// some logic...
}
}
This totally couples your code to Spring AOP, and it makes the class itself aware of the
fact that it is being used in an AOP context, which flies in the face of AOP. It also requires
some additional configuration when the proxy is being created:
public class Main {
public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.adddInterface(Pojo.class);
factory.addAdvice(new RetryAdvice());
factory.setExposeProxy(true);
Pojo pojo = (Pojo) factory.getProxy();
// this is a method call on the proxy!
pojo.foo();
}
}
Finally, it must be noted that AspectJ does not have this self-invocation issue because it
is not a proxy-based AOP framework.
25/08/2016 12:10
356 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
// you can also add existing aspect instances, the type of the object supplied must be
factory.addAspect(usageTracker);
// now get the proxy object...
MyInterfaceType proxy = factory.getProxy();
25/08/2016 12:10
357 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
to allow dependency injection of any object. The support is intended to be used for
objects created outside of the control of any container. Domain objects often fall into this
category because they are often created programmatically using the new operator, or by
an ORM tool as a result of a database query.
The @Configurable annotation marks a class as eligible for Spring-driven configuration.
In the simplest case it can be used just as a marker annotation:
package com.xyz.myapp.domain;
import org.springframework.beans.factory.annotation.Configurable;
@Configurable
public class Account {
// ...
}
When used as a marker interface in this way, Spring will configure new instances of the
annotated type ( Account in this case) using a bean definition (typically prototypescoped) with the same name as the fully-qualified type name (
com.xyz.myapp.domain.Account ). Since the default name for a bean is the fullyqualified name of its type, a convenient way to declare the prototype definition is simply to
omit the id attribute:
<bean class="com.xyz.myapp.domain.Account" scope="prototype">
<property name="fundsTransferService" ref="fundsTransferService"/>
</bean>
If you want to explicitly specify the name of the prototype bean definition to use, you can
do so directly in the annotation:
package com.xyz.myapp.domain;
import org.springframework.beans.factory.annotation.Configurable;
@Configurable("account")
public class Account {
// ...
}
Spring will now look for a bean definition named "account" and use that as the definition
to configure new Account instances.
You can also use autowiring to avoid having to specify a dedicated bean definition at all.
25/08/2016 12:10
358 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
One of the key phrases in the above paragraph is 'in essence'. For most
cases, the exact semantics of 'after returning from the initialization of a new
object' will be fine in this context, 'after initialization' means that the
dependencies will be injected after the object has been constructed - this
means that the dependencies will not be available for use in the constructor
bodies of the class. If you want the dependencies to be injected before the
constructor bodies execute, and thus be available for use in the body of the
constructors, then you need to define this on the @Configurable
declaration like so:
@Configurable(preConstruction=true)
You can find out more information about the language semantics of the
various pointcut types in AspectJ in this appendix of the AspectJ
Programming Guide.
For this to work the annotated types must be woven with the AspectJ weaver - you can
either use a build-time Ant or Maven task to do this (see for example the AspectJ
Development Environment Guide) or load-time weaving (see Section 11.8.4, Load-time
25/08/2016 12:10
359 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you prefer XML based configuration, the Spring context namespace defines a
convenient context:spring-configured element:
<context:spring-configured/>
Instances of @Configurable objects created before the aspect has been configured will
result in a message being issued to the debug log and no configuration of the object
taking place. An example might be a bean in the Spring configuration that creates domain
objects when it is initialized by Spring. In this case you can use the "depends-on" bean
attribute to manually specify that the bean depends on the configuration aspect.
<bean id="myService"
class="com.xzy.myapp.service.MyService"
depends-on="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurer
<!-- ... -->
</bean>
25/08/2016 12:10
360 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Configurable types have not been woven by AspectJ then the annotation has no
affect during unit testing, and you can simply set mock or stub property references in the
object under test and proceed as normal. If @Configurable types have been woven by
AspectJ then you can still unit test outside of the container as normal, but you will see a
warning message each time that you construct an @Configurable object indicating that
it has not been configured by Spring.
25/08/2016 12:10
361 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
want to use the Spring Frameworks transaction support outside of the Spring container.
The aspect that interprets @Transactional annotations is the
AnnotationTransactionAspect . When using this aspect, you must annotate the
implementation class (and/or methods within that class), not the interface (if any) that the
class implements. AspectJ follows Javas rule that annotations on interfaces are not
inherited.
A @Transactional annotation on a class specifies the default transaction semantics for
the execution of any public operation in the class.
A @Transactional annotation on a method within the class overrides the default
transaction semantics given by the class annotation (if present). Methods of any visibility
may be annotated, including private methods. Annotating non-public methods directly is
the only way to get transaction demarcation for the execution of such methods.
For AspectJ programmers that want to use the Spring configuration and transaction
management support but dont want to (or cannot) use annotations,
spring-aspects.jar also contains abstract aspects you can extend to provide your
own pointcut definitions. See the sources for the AbstractBeanConfigurerAspect and
AbstractTransactionAspect aspects for more information. As an example, the
following excerpt shows how you could write an aspect to configure all instances of
objects defined in the domain model using prototype bean definitions that match the fullyqualified class names:
public aspect DomainObjectConfiguration extends AbstractBeanConfigurerAspect {
public DomainObjectConfiguration() {
setBeanWiringInfoResolver(new ClassNameBeanWiringInfoResolver());
}
// the creation of a new bean (any object in the domain model)
protected pointcut beanCreation(Object beanInstance) :
initialization(new(..)) &&
SystemArchitecture.inDomainModel() &&
this(beanInstance);
25/08/2016 12:10
362 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
363 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
A first example
Let us assume that you are an application developer who has been tasked with
25/08/2016 12:10
364 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
a profiling tool, what we are going to do is switch on a simple profiling aspect that will
enable us to very quickly get some performance metrics, so that we can then apply a
finer-grained profiling tool to that specific area immediately afterwards.
Here is the profiling aspect. Nothing too fancy, just a quick-and-dirty time-based profiler,
using the @AspectJ-style of aspect declaration.
package foo;
import
import
import
import
import
import
org.aspectj.lang.ProceedingJoinPoint;
org.aspectj.lang.annotation.Aspect;
org.aspectj.lang.annotation.Around;
org.aspectj.lang.annotation.Pointcut;
org.springframework.util.StopWatch;
org.springframework.core.annotation.Order;
@Aspect
public class ProfilingAspect {
@Around("methodsToBeProfiled()")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
StopWatch sw = new StopWatch(getClass().getSimpleName());
try {
sw.start(pjp.getSignature().getName());
return pjp.proceed();
} finally {
sw.stop();
System.out.println(sw.prettyPrint());
}
}
@Pointcut("execution(public * foo..*.*(..))")
public void methodsToBeProfiled(){}
}
We will also need to create an META-INF/aop.xml file, to inform the AspectJ weaver
that we want to weave our ProfilingAspect into our classes. This file convention,
namely the presence of a file (or files) on the Java classpath called META-INF/aop.xml
is standard AspectJ.
25/08/2016 12:10
365 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Now that all the required artifacts are in place - the aspect, the META-INF/aop.xml file,
and the Spring configuration -, let us create a simple driver class with a main(..)
method to demonstrate the LTW in action.
package foo;
25/08/2016 12:10
366 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"
EntitlementCalculationService entitlementCalculationService
= (EntitlementCalculationService) ctx.getBean("entitlementCalculationServi
// the profiling aspect is 'woven' around this method execution
entitlementCalculationService.calculateEntitlement();
}
}
There is one last thing to do. The introduction to this section did say that one could switch
on LTW selectively on a per- ClassLoader basis with Spring, and this is true. However,
just for this example, we are going to use a Java agent (supplied with Spring) to switch on
the LTW. This is the command line we will use to run the above Main class:
java -javaagent:C:/projects/foo/lib/global/spring-instrument.jar foo.Main
The -javaagent is a flag for specifying and enabling agents to instrument programs
running on the JVM. The Spring Framework ships with such an agent, the
InstrumentationSavingAgent , which is packaged in the spring-instrument.jar
that was supplied as the value of the -javaagent argument in the above example.
The output from the execution of the Main program will look something like that below. (I
have introduced a Thread.sleep(..) statement into the calculateEntitlement()
implementation so that the profiler actually captures something other than 0 milliseconds the 01234 milliseconds is not an overhead introduced by the AOP :) )
Calculating entitlement
StopWatch 'ProfilingAspect': running time (millis) = 1234
------ ----- ---------------------------ms
%
Task name
------ ----- ---------------------------01234 100% calculateEntitlement
Since this LTW is effected using full-blown AspectJ, we are not just limited to advising
Spring beans; the following slight variation on the Main program will yield the same
result.
package foo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
25/08/2016 12:10
367 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Notice how in the above program we are simply bootstrapping the Spring container, and
then creating a new instance of the StubEntitlementCalculationService totally
outside the context of Spring the profiling advice still gets woven in.
The example admittedly is simplistic however the basics of the LTW support in Spring
have all been introduced in the above example, and the rest of this section will explain the
'why' behind each bit of configuration and usage in detail.
Aspects
The aspects that you use in LTW have to be AspectJ aspects. They can be written in
either the AspectJ language itself or you can write your aspects in the @AspectJ-style. It
means that your aspects are then both valid AspectJ and Spring AOP aspects.
Furthermore, the compiled aspect classes need to be available on the classpath.
'META-INF/aop.xml'
The AspectJ LTW infrastructure is configured using one or more META-INF/aop.xml
files, that are on the Java classpath (either directly, or more typically in jar files).
The structure and contents of this file is detailed in the main AspectJ reference
documentation, and the interested reader is referred to that resource. (I appreciate that
this section is brief, but the aop.xml file is 100% AspectJ - there is no Spring-specific
25/08/2016 12:10
368 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
information or semantics that apply to it, and so there is no extra value that I can
contribute either as a result), so rather than rehash the quite satisfactory section that the
AspectJ developers wrote, I am just directing you there.)
Spring configuration
The key component in Springs LTW support is the LoadTimeWeaver interface (in the
org.springframework.instrument.classloading package), and the numerous
implementations of it that ship with the Spring distribution. A LoadTimeWeaver is
responsible for adding one or more java.lang.instrument.ClassFileTransformers
to a ClassLoader at runtime, which opens the door to all manner of interesting
applications, one of which happens to be the LTW of aspects.
If you are unfamiliar with the idea of runtime class file transformation, you
are encouraged to read the javadoc API documentation for the
java.lang.instrument package before continuing. This is not a huge
chore because there is - rather annoyingly - precious little documentation
there the key interfaces and classes will at least be laid out in front of you
for reference as you read through this section.
25/08/2016 12:10
369 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Configuration
@EnableLoadTimeWeaving
public class AppConfig {
}
The above configuration will define and register a number of LTW-specific infrastructure
beans for you automatically, such as a LoadTimeWeaver and an
AspectJWeavingEnabler . The default LoadTimeWeaver is the
DefaultContextLoadTimeWeaver class, which attempts to decorate an automatically
detected LoadTimeWeaver : the exact type of LoadTimeWeaver that will be
'automatically detected' is dependent upon your runtime environment (summarized in the
following table).
LoadTimeWeaver
implementation
WebLogicLoadTimeWeaver
GlassFishLoadTimeWeaver
TomcatLoadTimeWeaver
JBossLoadTimeWeaver
25/08/2016 12:10
370 de 1194
Runtime Environment
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
LoadTimeWeaver
implementation
WildFly
Running in IBMs WebSphere
WebSphereLoadTimeWeaver
InstrumentationLoadTimeWeaver
InstrumentationSavingAgent (java
-javaagent:path/to/spring-instrument.jar)
Fallback, expecting the underlying
ReflectiveLoadTimeWeaver
Note that these are just the LoadTimeWeavers that are autodetected when using the
DefaultContextLoadTimeWeaver : it is of course possible to specify exactly which
LoadTimeWeaver implementation that you wish to use.
To specify a specific LoadTimeWeaver with Java configuration implement the
LoadTimeWeavingConfigurer interface and override the getLoadTimeWeaver()
method:
@Configuration
@EnableLoadTimeWeaving
public class AppConfig implements LoadTimeWeavingConfigurer {
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
return new ReflectiveLoadTimeWeaver();
}
}
If you are using XML based configuration you can specify the fully-qualified classname as
the value of the weaver-class attribute on the <context:load-time-weaver/>
element:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
25/08/2016 12:10
371 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:load-time-weaver
weaver-class="org.springframework.instrument.classloading.ReflectiveLoadTi
</beans>
The LoadTimeWeaver that is defined and registered by the configuration can be later
retrieved from the Spring container using the well-known name loadTimeWeaver .
Remember that the LoadTimeWeaver exists just as a mechanism for Springs LTW
infrastructure to add one or more ClassFileTransformers . The actual
ClassFileTransformer that does the LTW is the ClassPreProcessorAgentAdapter
(from the org.aspectj.weaver.loadtime package) class. See the class-level javadocs
of the ClassPreProcessorAgentAdapter class for further details, because the specifics
of how the weaving is actually effected is beyond the scope of this section.
There is one final attribute of the configuration left to discuss: the aspectjWeaving
attribute (or aspectj-weaving if you are using XML). This is a simple attribute that
controls whether LTW is enabled or not; it is as simple as that. It accepts one of three
possible values, summarized below, with the default value being autodetect if the
attribute is not present.
XML Value
Explanation
Value
ENABLED
on
DISABLED
off
AUTODETECT
autodetect
25/08/2016 12:10
372 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Environment-specific configuration
This last section contains any additional settings and configuration that you will need
when using Springs LTW support in environments such as application servers and web
containers.
Tomcat
Historically, Apache Tomcat's default class loader did not support class transformation
which is why Spring provides an enhanced implementation that addresses this need.
Named TomcatInstrumentableClassLoader , the loader works on Tomcat 6.0 and
above.
25/08/2016 12:10
373 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
will impact only applications that use the custom class loader and does not require any
changes to the server configuration. See the Tomcat 6.0.x documentation for more details
about available context locations.
Alternatively, consider the use of the Spring-provided generic VM agent, to be specified in
Tomcats launch script (see above). This will make instrumentation available to all
deployed web applications, no matter what ClassLoader they happen to run on.
Note that this requires modification of the VM launch script which may prevent you from
using this in application server environments (depending on your operation policies).
25/08/2016 12:10
374 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Additionally, the JDK agent will instrument the entire VM which can prove expensive.
For performance reasons, it is recommended to use this configuration only if your target
environment (such as Jetty) does not have (or does not support) a dedicated LTW.
12.2.1 Concepts
Springs pointcut model enables pointcut reuse independent of advice types. Its possible
to target different advice using the same pointcut.
The org.springframework.aop.Pointcut interface is the central interface, used to
25/08/2016 12:10
375 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Splitting the Pointcut interface into two parts allows reuse of class and method
matching parts, and fine-grained composition operations (such as performing a "union"
with another method matcher).
The ClassFilter interface is used to restrict the pointcut to a given set of target
classes. If the matches() method always returns true, all target classes will be matched:
public interface ClassFilter {
boolean matches(Class clazz);
}
The matches(Method, Class) method is used to test whether this pointcut will ever
match a given method on a target class. This evaluation can be performed when an AOP
proxy is created, to avoid the need for a test on every method invocation. If the
2-argument matches method returns true for a given method, and the isRuntime()
method for the MethodMatcher returns true, the 3-argument matches method will be
invoked on every method invocation. This enables a pointcut to look at the arguments
passed to the method invocation immediately before the target advice is to execute.
Most MethodMatchers are static, meaning that their isRuntime() method returns false.
In this case, the 3-argument matches method will never be invoked.
25/08/2016 12:10
376 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Static pointcuts
Static pointcuts are based on method and target class, and cannot take into account the
methods arguments. Static pointcuts are sufficient - and best - for most usages. Its
possible for Spring to evaluate a static pointcut only once, when a method is first invoked:
after that, there is no need to evaluate the pointcut again with each method invocation.
Lets consider some static pointcut implementations included with Spring.
25/08/2016 12:10
377 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
One obvious way to specify static pointcuts is regular expressions. Several AOP
frameworks besides Spring make this possible.
org.springframework.aop.support.JdkRegexpMethodPointcut is a generic regular
expression pointcut, using the regular expression support in JDK 1.4+.
Using the JdkRegexpMethodPointcut class, you can provide a list of pattern Strings. If
any of these is a match, the pointcut will evaluate to true. (So the result is effectively the
union of these pointcuts.)
The usage is shown below:
<bean id="settersAndAbsquatulatePointcut"
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns">
<list>
<value>.*set.*</value>
<value>.*absquatulate</value>
</list>
</property>
</bean>
Attribute-driven pointcuts
An important type of static pointcut is a metadata-driven pointcut. This uses the values of
25/08/2016 12:10
378 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Dynamic pointcuts
Dynamic pointcuts are costlier to evaluate than static pointcuts. They take into account
method arguments, as well as static information. This means that they must be evaluated
with every method invocation; the result cannot be cached, as arguments will vary.
The main example is the control flow pointcut.
25/08/2016 12:10
379 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
You can use custom pointcuts with any advice type in Spring 1.0 RC2 and above.
25/08/2016 12:10
380 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The MethodInvocation argument to the invoke() method exposes the method being
invoked; the target join point; the AOP proxy; and the arguments to the method. The
invoke() method should return the invocations result: the return value of the join point.
A simple MethodInterceptor implementation looks as follows:
public class DebugInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Before: invocation=[" + invocation + "]");
Object rval = invocation.proceed();
System.out.println("Invocation returned");
return rval;
}
}
Note the call to the MethodInvocations proceed() method. This proceeds down the
interceptor chain towards the join point. Most interceptors will invoke this method, and
return its return value. However, a MethodInterceptor, like any around advice, can return
a different value or throw an exception rather than invoke the proceed method. However,
you dont want to do this without good reason!
25/08/2016 12:10
381 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Before advice
A simpler advice type is a before advice. This does not need a MethodInvocation
object, since it will only be called before entering the method.
The main advantage of a before advice is that there is no need to invoke the proceed()
method, and therefore no possibility of inadvertently failing to proceed down the
interceptor chain.
The MethodBeforeAdvice interface is shown below. (Springs API design would allow
for field before advice, although the usual objects apply to field interception and its
unlikely that Spring will ever implement it).
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method m, Object[] args, Object target) throws Throwable;
}
Note the return type is void . Before advice can insert custom behavior before the join
point executes, but cannot change the return value. If a before advice throws an
exception, this will abort further execution of the interceptor chain. The exception will
propagate back up the interceptor chain. If it is unchecked, or on the signature of the
invoked method, it will be passed directly to the client; otherwise it will be wrapped in an
unchecked exception by the AOP proxy.
An example of a before advice in Spring, which counts all method invocations:
public class CountingBeforeAdvice implements MethodBeforeAdvice {
private int count;
public void before(Method m, Object[] args, Object target) throws Throwable {
++count;
}
public int getCount() {
return count;
}
}
Throws advice
25/08/2016 12:10
382 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Throws advice is invoked after the return of the join point if the join point threw an
exception. Spring offers typed throws advice. Note that this means that the
org.springframework.aop.ThrowsAdvice interface does not contain any methods: It
is a tag interface identifying that the given object implements one or more typed throws
advice methods. These should be in the form of:
afterThrowing([Method, args, target], subclassOfThrowable)
Only the last argument is required. The method signatures may have either one or four
arguments, depending on whether the advice method is interested in the method and
arguments. The following classes are examples of throws advice.
The advice below is invoked if a RemoteException is thrown (including subclasses):
public class RemoteThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(RemoteException ex) throws Throwable {
// Do something with remote exception
}
}
The final example illustrates how these two methods could be used in a single class,
which handles both RemoteException and ServletException . Any number of throws
advice methods can be combined in a single class.
public static class CombinedThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(RemoteException ex) throws Throwable {
// Do something with remote exception
}
25/08/2016 12:10
383 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
An after returning advice has access to the return value (which it cannot modify), invoked
method, methods arguments and target.
The following after returning advice counts all successful method invocations that have
not thrown exceptions:
public class CountingAfterReturningAdvice implements AfterReturningAdvice {
private int count;
25/08/2016 12:10
384 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
}
}
This advice doesnt change the execution path. If it throws an exception, this will be
thrown up the interceptor chain instead of the return value.
Introduction advice
Spring treats introduction advice as a special kind of interception advice.
Introduction requires an IntroductionAdvisor , and an IntroductionInterceptor ,
implementing the following interface:
public interface IntroductionInterceptor extends MethodInterceptor {
boolean implementsInterface(Class intf);
}
The invoke() method inherited from the AOP Alliance MethodInterceptor interface
must implement the introduction: that is, if the invoked method is on an introduced
interface, the introduction interceptor is responsible for handling the method call - it
cannot invoke proceed() .
Introduction advice cannot be used with any pointcut, as it applies only at class, rather
than method, level. You can only use introduction advice with the
IntroductionAdvisor , which has the following methods:
public interface IntroductionAdvisor extends Advisor, IntroductionInfo {
ClassFilter getClassFilter();
void validateInterfaces() throws IllegalArgumentException;
}
public interface IntroductionInfo {
Class[] getInterfaces();
}
25/08/2016 12:10
385 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
This illustrates a mixin. We want to be able to cast advised objects to Lockable, whatever
their type, and call lock and unlock methods. If we call the lock() method, we want all
setter methods to throw a LockedException . Thus we can add an aspect that provides
the ability to make objects immutable, without them having any knowledge of it: a good
example of AOP.
Firstly, well need an IntroductionInterceptor that does the heavy lifting. In this
case, we extend the
org.springframework.aop.support.DelegatingIntroductionInterceptor
convenience class. We could implement IntroductionInterceptor directly, but using
DelegatingIntroductionInterceptor is best for most cases.
The DelegatingIntroductionInterceptor is designed to delegate an introduction to
an actual implementation of the introduced interface(s), concealing the use of interception
to do so. The delegate can be set to any object using a constructor argument; the default
delegate (when the no-arg constructor is used) is this. Thus in the example below, the
delegate is the LockMixin subclass of DelegatingIntroductionInterceptor . Given
a delegate (by default itself), a DelegatingIntroductionInterceptor instance looks
for all interfaces implemented by the delegate (other than IntroductionInterceptor), and
will support introductions against any of them. Its possible for subclasses such as
LockMixin to call the suppressInterface(Class intf) method to suppress
interfaces that should not be exposed. However, no matter how many interfaces an
IntroductionInterceptor is prepared to support, the IntroductionAdvisor used
will control which interfaces are actually exposed. An introduced interface will conceal any
implementation of the same interface by the target.
Thus LockMixin extends DelegatingIntroductionInterceptor and implements
25/08/2016 12:10
386 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
for introduction, so we dont need to specify that. We could introduce any number of
interfaces in this way.
Note the use of the locked instance variable. This effectively adds additional state to
that held in the target object.
25/08/2016 12:10
387 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
public LockMixinAdvisor() {
super(new LockMixin(), Lockable.class);
}
}
The Spring AOP support also uses factory beans under the covers.
25/08/2016 12:10
388 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
12.5.1 Basics
The ProxyFactoryBean , like other Spring FactoryBean implementations, introduces a
level of indirection. If you define a ProxyFactoryBean with name foo , what objects
referencing foo see is not the ProxyFactoryBean instance itself, but an object created
by the ProxyFactoryBeans implementation of the `getObject() method. This
method will create an AOP proxy wrapping a target object.
One of the most important benefits of using a ProxyFactoryBean or another IoC-aware
class to create AOP proxies, is that it means that advices and pointcuts can also be
managed by IoC. This is a powerful feature, enabling certain approaches that are hard to
achieve with other AOP frameworks. For example, an advice may itself reference
application objects (besides the target, which should be available in any AOP framework),
benefiting from all the pluggability provided by Dependency Injection.
25/08/2016 12:10
389 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
no longer allowed. This is useful both as a slight optimization and for those cases
when you dont want callers to be able to manipulate the proxy (via the Advised
interface) after the proxy has been created. The default value of this property is
false , so changes such as adding additional advice are allowed.
exposeProxy : determines whether or not the current proxy should be exposed in a
ThreadLocal so that it can be accessed by the target. If a target needs to obtain the
proxy and the exposeProxy property is set to true , the target can use the
AopContext.currentProxy() method.
Other properties specific to ProxyFactoryBean include:
proxyInterfaces : array of String interface names. If this isnt supplied, a CGLIB
proxy for the target class will be used (but see also Section 12.5.3, JDK- and
CGLIB-based proxies).
interceptorNames : String array of Advisor , interceptor or other advice names to
apply. Ordering is significant, on a first come-first served basis. That is to say that the
first interceptor in the list will be the first to be able to intercept the invocation.
The names are bean names in the current factory, including bean names from ancestor
factories. You cant mention bean references here since doing so would result in the
ProxyFactoryBean ignoring the singleton setting of the advice.
You can append an interceptor name with an asterisk ( * ). This will result in the
application of all advisor beans with names starting with the part before the asterisk to be
applied. An example of using this feature can be found in Section 12.5.6, Using 'global'
advisors.
singleton: whether or not the factory should return a single object, no matter how
often the getObject() method is called. Several FactoryBean implementations
offer such a method. The default value is true . If you want to use stateful advice for example, for stateful mixins - use prototype advices along with a singleton value of
false .
25/08/2016 12:10
390 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If the class of a target object that is to be proxied (hereafter simply referred to as the
target class) doesnt implement any interfaces, then a CGLIB-based proxy will be created.
This is the easiest scenario, because JDK proxies are interface based, and no interfaces
means JDK proxying isnt even possible. One simply plugs in the target bean, and
specifies the list of interceptors via the interceptorNames property. Note that a
CGLIB-based proxy will be created even if the proxyTargetClass property of the
ProxyFactoryBean has been set to false . (Obviously this makes no sense, and is
best removed from the bean definition because it is at best redundant, and at worst
confusing.)
If the target class implements one (or more) interfaces, then the type of proxy that is
created depends on the configuration of the ProxyFactoryBean .
If the proxyTargetClass property of the ProxyFactoryBean has been set to true ,
then a CGLIB-based proxy will be created. This makes sense, and is in keeping with the
principle of least surprise. Even if the proxyInterfaces property of the
ProxyFactoryBean has been set to one or more fully qualified interface names, the fact
that the proxyTargetClass property is set to true will cause CGLIB-based proxying to
be in effect.
If the proxyInterfaces property of the ProxyFactoryBean has been set to one or
more fully qualified interface names, then a JDK-based proxy will be created. The created
proxy will implement all of the interfaces that were specified in the proxyInterfaces
property; if the target class happens to implement a whole lot more interfaces than those
specified in the proxyInterfaces property, that is all well and good but those additional
interfaces will not be implemented by the returned proxy.
If the proxyInterfaces property of the ProxyFactoryBean has not been set, but the
target class does implement one (or more) interfaces, then the ProxyFactoryBean will
auto-detect the fact that the target class does actually implement at least one interface,
and a JDK-based proxy will be created. The interfaces that are actually proxied will be all
of the interfaces that the target class implements; in effect, this is the same as simply
supplying a list of each and every interface that the target class implements to the
proxyInterfaces property. However, it is significantly less work, and less prone to
typos.
25/08/2016 12:10
391 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Note that the interceptorNames property takes a list of String: the bean names of the
interceptor or advisors in the current factory. Advisors, interceptors, before, after returning
and throws advice objects can be used. The ordering of advisors is significant.
You might be wondering why the list doesnt hold bean references. The
reason for this is that if the ProxyFactoryBeans singleton property is set to
false, it must be able to return independent proxy instances. If any of the
advisors is itself a prototype, an independent instance would need to be
returned, so its necessary to be able to obtain an instance of the prototype
25/08/2016 12:10
392 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The "person" bean definition above can be used in place of a Person implementation, as
follows:
Person person = (Person) factory.getBean("person");
Other beans in the same IoC context can express a strongly typed dependency on it, as
with an ordinary Java object:
<bean id="personUser" class="com.mycompany.PersonUser">
<property name="person"><ref bean="person"/></property>
</bean>
The PersonUser class in this example would expose a property of type Person. As far
as its concerned, the AOP proxy can be used transparently in place of a "real" person
implementation. However, its class would be a dynamic proxy class. It would be possible
to cast it to the Advised interface (discussed below).
Its possible to conceal the distinction between target and proxy using an anonymous
inner bean, as follows. Only the ProxyFactoryBean definition is different; the advice is
included only for completeness:
<bean id="myAdvisor" class="com.mycompany.MyAdvisor">
<property name="someProperty" value="Custom string property value"/>
</bean>
25/08/2016 12:10
393 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
This has the advantage that theres only one object of type Person : useful if we want to
prevent users of the application context from obtaining a reference to the un-advised
object, or need to avoid any ambiguity with Spring IoC autowiring. Theres also arguably
an advantage in that the ProxyFactoryBean definition is self-contained. However, there
are times when being able to obtain the un-advised target from the factory might actually
be an advantage: for example, in certain test scenarios.
25/08/2016 12:10
394 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
the part before the asterisk, will be added to the advisor chain. This can come in handy if
you need to add a standard set of 'global' advisors:
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="service"/>
<property name="interceptorNames">
<list>
<value>global*</value>
</list>
</property>
</bean>
This will never be instantiated itself, so may actually be incomplete. Then each proxy
which needs to be created is just a child bean definition, which wraps the target of the
proxy as an inner bean definition, since the target will never be used on its own anyway.
<bean id="myService" parent="txProxyTemplate">
<property name="target">
<bean class="org.springframework.samples.MyServiceImpl">
</bean>
</property>
</bean>
25/08/2016 12:10
395 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Note that in the example above, we have explicitly marked the parent bean definition as
abstract by using the abstract attribute, as described previously, so that it may not actually
ever be instantiated. Application contexts (but not simple bean factories) will by default
pre-instantiate all singletons. It is therefore important (at least for singleton beans) that if
you have a (parent) bean definition which you intend to use only as a template, and this
definition specifies a class, you must make sure to set the abstract attribute to true,
otherwise the application context will actually try to pre-instantiate it.
25/08/2016 12:10
396 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
alternate constructor.
You can add advices (with interceptors as a specialized kind of advice) and/or advisors,
and manipulate them for the life of the ProxyFactory. If you add an
IntroductionInterceptionAroundAdvisor, you can cause the proxy to implement additional
interfaces.
There are also convenience methods on ProxyFactory (inherited from AdvisedSupport )
which allow you to add other advice types such as before and throws advice.
AdvisedSupport is the superclass of both ProxyFactory and ProxyFactoryBean.
Integrating AOP proxy creation with the IoC framework is best practice in
most applications. We recommend that you externalize configuration from
Java code with AOP, as in general.
25/08/2016 12:10
397 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
advice type that has been added to the factory. If you added an Advisor, the returned
advisor at this index will be the object that you added. If you added an interceptor or other
advice type, Spring will have wrapped this in an advisor with a pointcut that always
returns true. Thus if you added a MethodInterceptor , the advisor returned for this
index will be an DefaultPointcutAdvisor returning your MethodInterceptor and a
pointcut that matches all classes and methods.
The addAdvisor() methods can be used to add any Advisor. Usually the advisor
holding pointcut and advice will be the generic DefaultPointcutAdvisor , which can be
used with any advice or pointcut (but not for introductions).
By default, its possible to add or remove advisors or interceptors even once a proxy has
been created. The only restriction is that its impossible to add or remove an introduction
advisor, as existing proxies from the factory will not show the interface change. (You can
obtain a new proxy from the factory to avoid this problem.)
A simple example of casting an AOP proxy to the Advised interface and examining and
manipulating its advice:
Advised advised = (Advised) myObject;
Advisor[] advisors = advised.getAdvisors();
int oldAdvisorCount = advisors.length;
System.out.println(oldAdvisorCount + " advisors");
// Add an advice like an interceptor without a pointcut
// Will match all proxied methods
// Can use for interceptors, before, after returning or throws advice
advised.addAdvice(new DebugInterceptor());
// Add selective advice using a pointcut
advised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice));
25/08/2016 12:10
398 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Its questionable whether its advisable (no pun intended) to modify advice
on a business object in production, although there are no doubt legitimate
usage cases. However, it can be very useful in development: for example,
in tests. I have sometimes found it very useful to be able to add test code in
the form of an interceptor or other advice, getting inside a method
invocation I want to test. (For example, the advice can get inside a
transaction created for that method: for example, to run SQL to check that a
database was correctly updated, before marking the transaction for roll
back.)
Depending on how you created the proxy, you can usually set a frozen flag, in which
case the Advised isFrozen() method will return true, and any attempts to modify
advice through addition or removal will result in an AopConfigException . The ability to
freeze the state of an advised object is useful in some cases, for example, to prevent
calling code removing a security interceptor. It may also be used in Spring 1.1 to allow
aggressive optimization if runtime advice modification is known not to be required.
25/08/2016 12:10
399 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
BeanNameAutoProxyCreator
The BeanNameAutoProxyCreator class is a BeanPostProcessor that automatically
creates AOP proxies for beans with names matching literal values or wildcards.
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
<property name="beanNames" value="jdk*,onlyJdk"/>
<property name="interceptorNames">
<list>
<value>myInterceptor</value>
</list>
</property>
</bean>
DefaultAdvisorAutoProxyCreator
A more general and extremely powerful auto proxy creator is
DefaultAdvisorAutoProxyCreator . This will automagically apply eligible advisors in
the current context, without the need to include specific bean names in the auto-proxy
advisors bean definition. It offers the same merit of consistent configuration and
avoidance of duplication as BeanNameAutoProxyCreator .
Using this mechanism involves:
Specifying a DefaultAdvisorAutoProxyCreator bean definition.
Specifying any number of Advisors in the same or related contexts. Note that these
25/08/2016 12:10
400 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreato
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdv
<property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<bean id="customAdvisor" class="com.mycompany.MyAdvisor"/>
<bean id="businessObject1" class="com.mycompany.BusinessObject1">
<!-- Properties omitted -->
</bean>
<bean id="businessObject2" class="com.mycompany.BusinessObject2"/>
25/08/2016 12:10
401 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
AbstractAdvisorAutoProxyCreator
This is the superclass of DefaultAdvisorAutoProxyCreator. You can create your own
auto-proxy creators by subclassing this class, in the unlikely event that advisor definitions
offer insufficient customization to the behavior of the framework
DefaultAdvisorAutoProxyCreator .
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreato
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdv
<property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor"
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.interceptor.AttributesTransaction
<property name="attributes" ref="attributes"/>
</bean>
</property>
25/08/2016 12:10
402 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreato
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdv
<property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor"
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.annotation.AnnotationTransactionA
</property>
</bean>
25/08/2016 12:10
403 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
404 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you do not specify a TargetSource, a default implementation is used that wraps a local
object. The same target is returned for each invocation (as you would expect).
Lets look at the standard target sources provided with Spring, and how you can use
them.
When using a custom target source, your target will usually need to be a
prototype rather than a singleton bean definition. This allows Spring to
create a new target instance when required.
The above swap() call changes the target of the swappable bean. Clients who hold a
reference to that bean will be unaware of the change, but will immediately start hitting the
new target.
Although this example doesnt add any advice - and its not necessary to add advice to
25/08/2016 12:10
405 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
arbitrary advice.
Note that the target object - "businessObjectTarget" in the example - must be a prototype.
This allows the PoolingTargetSource implementation to create new instances of the
target to grow the pool as necessary. See the javadocs of
AbstractPoolingTargetSource and the concrete subclass you wish to use for
25/08/2016 12:10
406 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
information about its properties: "maxSize" is the most basic, and always guaranteed to
be present.
In this case, "myInterceptor" is the name of an interceptor that would need to be defined
in the same IoC context. However, it isnt necessary to specify interceptors to use pooling.
If you want only pooling, and no other advice, dont set the interceptorNames property at
all.
Its possible to configure Spring so as to be able to cast any pooled object to the
org.springframework.aop.target.PoolingConfig interface, which exposes
information about the configuration and current size of the pool through an introduction.
Youll need to define an advisor like this:
Simpler pooling is available using auto-proxying. Its possible to set the TargetSources
used by any auto-proxy creator.
25/08/2016 12:10
407 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Theres only one property: the name of the target bean. Inheritance is used in the
TargetSource implementations to ensure consistent naming. As with the pooling target
source, the target bean must be a prototype bean definition.
25/08/2016 12:10
408 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
409 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
14.1.2 JNDI
The org.springframework.mock.jndi package contains an implementation of the
JNDI SPI, which you can use to set up a simple JNDI environment for test suites or
stand-alone applications. If, for example, JDBC DataSource s get bound to the same
JNDI names in test code as within a Java EE container, you can reuse both application
25/08/2016 12:10
410 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
411 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
412 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
413 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
414 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
may affect future tests. Also, many operationssuch as inserting or modifying persistent
datacannot be performed (or verified) outside a transaction.
The TestContext framework addresses this issue. By default, the framework will create
and roll back a transaction for each test. You simply write code that can assume the
existence of a transaction. If you call transactionally proxied objects in your tests, they will
behave correctly, according to their configured transactional semantics. In addition, if a
test method deletes the contents of selected tables while running within the transaction
managed for the test, the transaction will roll back by default, and the database will return
to its state prior to execution of the test. Transactional support is provided to a test via a
PlatformTransactionManager bean defined in the tests application context.
If you want a transaction to commitunusual, but occasionally useful when you want a
particular test to populate or modify the databasethe TestContext framework can be
instructed to cause the transaction to commit instead of roll back via the @Commit
annotation.
See transaction management with the TestContext framework.
25/08/2016 12:10
415 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
15.4 Annotations
15.4.1 Spring Testing Annotations
The Spring Framework provides the following set of Spring-specific annotations that you
can use in your unit and integration tests in conjunction with the TestContext framework.
Refer to the corresponding javadocs for further information, including default attribute
values, attribute aliases, and so on.
@BootstrapWith
@BootstrapWith is a class-level annotation that is used to configure how the Spring
TestContext Framework is bootstrapped. Specifically, @BootstrapWith is used to
specify a custom TestContextBootstrapper . Consult the Bootstrapping the
TestContext framework section for further details.
@ContextConfiguration
@ContextConfiguration defines class-level metadata that is used to determine how to
25/08/2016 12:10
416 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
417 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@WebAppConfiguration
@WebAppConfiguration is a class-level annotation that is used to declare that the
ApplicationContext loaded for an integration test should be a
WebApplicationContext . The mere presence of @WebAppConfiguration on a test
class ensures that a WebApplicationContext will be loaded for the test, using the
default value of "file:src/main/webapp" for the path to the root of the web application
(i.e., the resource base path). The resource base path is used behind the scenes to
create a MockServletContext which serves as the ServletContext for the tests
WebApplicationContext .
@ContextConfiguration
@WebAppConfiguration
public class WebAppTests {
// class body...
}
To override the default, specify a different base resource path via the implicit value
attribute. Both classpath: and file: resource prefixes are supported. If no resource
prefix is supplied the path is assumed to be a file system resource.
@ContextConfiguration
@WebAppConfiguration("classpath:test-web-resources")
public class WebAppTests {
// class body...
}
@ContextHierarchy
@ContextHierarchy is a class-level annotation that is used to define a hierarchy of
ApplicationContext s for integration tests. @ContextHierarchy should be declared
with a list of one or more @ContextConfiguration instances, each of which defines a
level in the context hierarchy. The following examples demonstrate the use of
@ContextHierarchy within a single test class; however, @ContextHierarchy can also
be used within a test class hierarchy.
25/08/2016 12:10
418 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@ContextHierarchy({
@ContextConfiguration("/parent-config.xml"),
@ContextConfiguration("/child-config.xml")
})
public class ContextHierarchyTests {
// class body...
}
@WebAppConfiguration
@ContextHierarchy({
@ContextConfiguration(classes = AppConfig.class),
@ContextConfiguration(classes = WebConfig.class)
})
public class WebIntegrationTests {
// class body...
}
If you need to merge or override the configuration for a given level of the context
hierarchy within a test class hierarchy, you must explicitly name that level by supplying
the same value to the name attribute in @ContextConfiguration at each
corresponding level in the class hierarchy. See the section called Context hierarchies
and the @ContextHierarchy javadocs for further examples.
@ActiveProfiles
@ActiveProfiles is a class-level annotation that is used to declare which bean
definition profiles should be active when loading an ApplicationContext for an
integration test.
@ContextConfiguration
@ActiveProfiles("dev")
public class DeveloperTests {
// class body...
}
@ContextConfiguration
@ActiveProfiles({"dev", "integration"})
public class DeveloperIntegrationTests {
// class body...
}
25/08/2016 12:10
419 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
See the section called Context configuration with environment profiles and the
@ActiveProfiles javadocs for examples and further details.
@TestPropertySource
@TestPropertySource is a class-level annotation that is used to configure the locations
of properties files and inlined properties to be added to the set of PropertySources in
the Environment for an ApplicationContext loaded for an integration test.
Test property sources have higher precedence than those loaded from the operating
systems environment or Java system properties as well as property sources added by
the application declaratively via @PropertySource or programmatically. Thus, test
property sources can be used to selectively override properties defined in system and
application property sources. Furthermore, inlined properties have higher precedence
than properties loaded from resource locations.
The following example demonstrates how to declare a properties file from the classpath.
@ContextConfiguration
@TestPropertySource("/test.properties")
public class MyIntegrationTests {
// class body...
}
@DirtiesContext
@DirtiesContext indicates that the underlying Spring ApplicationContext has been
dirtied during the execution of a test (i.e., modified or corrupted in some mannerfor
example, by changing the state of a singleton bean) and should be closed. When an
application context is marked dirty, it is removed from the testing frameworks cache and
25/08/2016 12:10
420 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
closed. As a consequence, the underlying Spring container will be rebuilt for any
subsequent test that requires a context with the same configuration metadata.
@DirtiesContext can be used as both a class-level and method-level annotation within
the same class or class hierarchy. In such scenarios, the ApplicationContext is
marked as dirty before or after any such annotated method as well as before or after the
current test class, depending on the configured methodMode and classMode .
The following examples explain when the context would be dirtied for various
configuration scenarios:
Before the current test class, when declared on a class with class mode set to
BEFORE_CLASS .
@DirtiesContext(classMode = BEFORE_CLASS)
public class FreshContextTests {
// some tests that require a new Spring container
}
After the current test class, when declared on a class with class mode set to
AFTER_CLASS (i.e., the default class mode).
@DirtiesContext
public class ContextDirtyingTests {
// some tests that result in the Spring container being dirtied
}
Before each test method in the current test class, when declared on a class with
class mode set to BEFORE_EACH_TEST_METHOD.
@DirtiesContext(classMode = BEFORE_EACH_TEST_METHOD)
public class FreshContextTests {
// some tests that require a new Spring container
}
After each test method in the current test class, when declared on a class with class
mode set to AFTER_EACH_TEST_METHOD.
@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
public class ContextDirtyingTests {
// some tests that result in the Spring container being dirtied
}
Before the current test, when declared on a method with the method mode set to
BEFORE_METHOD
25/08/2016 12:10
421 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@DirtiesContext(methodMode = BEFORE_METHOD)
@Test
public void testProcessWhichRequiresFreshAppCtx() {
// some logic that requires a new Spring container
}
After the current test, when declared on a method with the method mode set to
AFTER_METHOD (i.e., the default method mode).
@DirtiesContext
@Test
public void testProcessWhichDirtiesAppCtx() {
// some logic that results in the Spring container being dirtied
}
For further details regarding the EXHAUSTIVE and CURRENT_LEVEL algorithms see the
DirtiesContext.HierarchyMode javadocs.
25/08/2016 12:10
422 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@TestExecutionListeners
@TestExecutionListeners defines class-level metadata for configuring the
TestExecutionListener implementations that should be registered with the
TestContextManager . Typically, @TestExecutionListeners is used in conjunction
with @ContextConfiguration .
@ContextConfiguration
@TestExecutionListeners({CustomTestExecutionListener.class, AnotherTestExecutionListen
public class CustomTestExecutionListenerTests {
// class body...
}
@Commit
@Commit indicates that the transaction for a transactional test method should be
committed after the test method has completed. @Commit can be used as a direct
replacement for @Rollback(false) in order to more explicitly convey the intent of the
code. Analogous to @Rollback , @Commit may also be declared as a class-level or
method-level annotation.
@Commit
@Test
public void testProcessWithoutRollback() {
// ...
}
@Rollback
@Rollback indicates whether the transaction for a transactional test method should be
rolled back after the test method has completed. If true , the transaction is rolled back;
otherwise, the transaction is committed (see also @Commit ). Rollback semantics for
integration tests in the Spring TestContext Framework default to true even if
@Rollback is not explicitly declared.
When declared as a class-level annotation, @Rollback defines the default rollback
semantics for all test methods within the test class hierarchy. When declared as a
method-level annotation, @Rollback defines rollback semantics for the specific test
method, potentially overriding class-level @Rollback or @Commit semantics.
25/08/2016 12:10
423 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Rollback(false)
@Test
public void testProcessWithoutRollback() {
// ...
}
@BeforeTransaction
@BeforeTransaction indicates that the annotated void method should be executed
before a transaction is started for test methods configured to run within a transaction via
Springs @Transactional annotation. As of Spring Framework 4.3,
@BeforeTransaction methods are not required to be public and may be declared on
Java 8 based interface default methods.
@BeforeTransaction
void beforeTransaction() {
// logic to be executed before a transaction is started
}
@AfterTransaction
@AfterTransaction indicates that the annotated void method should be executed
after a transaction is ended for test methods configured to run within a transaction via
Springs @Transactional annotation. As of Spring Framework 4.3,
@AfterTransaction methods are not required to be public and may be declared on
Java 8 based interface default methods.
@AfterTransaction
void afterTransaction() {
// logic to be executed after a transaction has ended
}
@Sql
@Sql is used to annotate a test class or test method to configure SQL scripts to be
executed against a given database during integration tests.
@Test
@Sql({"/test-schema.sql", "/test-user-data.sql"})
public void userTest {
// execute code that relies on the test schema and test data
}
25/08/2016 12:10
424 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
See the section called Executing SQL scripts declaratively with @Sql for further details.
@SqlConfig
@SqlConfig defines metadata that is used to determine how to parse and execute SQL
scripts configured via the @Sql annotation.
@Test
@Sql(
scripts = "/test-user-data.sql",
config = @SqlConfig(commentPrefix = "`", separator = "@@")
)
public void userTest {
// execute code that relies on the test data
}
@SqlGroup
@SqlGroup is a container annotation that aggregates several @Sql annotations.
@SqlGroup can be used natively, declaring several nested @Sql annotations, or it can
be used in conjunction with Java 8s support for repeatable annotations, where @Sql can
simply be declared several times on the same class or method, implicitly generating this
container annotation.
@Test
@SqlGroup({
@Sql(scripts = "/test-schema.sql", config = @SqlConfig(commentPrefix = "`")),
@Sql("/test-user-data.sql")
)}
public void userTest {
// execute code that uses the test schema and test data
}
25/08/2016 12:10
425 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@IfProfileValue
@IfProfileValue indicates that the annotated test is enabled for a specific testing
environment. If the configured ProfileValueSource returns a matching value for the
provided name , the test is enabled. Otherwise, the test will be disabled and effectively
ignored.
@IfProfileValue can be applied at the class level, the method level, or both.
Class-level usage of @IfProfileValue takes precedence over method-level usage for
any methods within that class or its subclasses. Specifically, a test is enabled if it is
enabled both at the class level and at the method level; the absence of
@IfProfileValue means the test is implicitly enabled. This is analogous to the
semantics of JUnit 4s @Ignore annotation, except that the presence of @Ignore
always disables a test.
25/08/2016 12:10
426 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@ProfileValueSourceConfiguration
@ProfileValueSourceConfiguration is a class-level annotation that specifies what
type of ProfileValueSource to use when retrieving profile values configured through
the @IfProfileValue annotation. If @ProfileValueSourceConfiguration is not
declared for a test, SystemProfileValueSource is used by default.
@ProfileValueSourceConfiguration(CustomProfileValueSource.class)
public class CustomProfileValueSourceTests {
// class body...
}
@Timed
@Timed indicates that the annotated test method must finish execution in a specified time
period (in milliseconds). If the text execution time exceeds the specified time period, the
test fails.
The time period includes execution of the test method itself, any repetitions of the test
(see @Repeat ), as well as any set up or tear down of the test fixture.
@Timed(millis=1000)
public void testProcessWithOneSecondTimeout() {
// some logic that should not take longer than 1 second to execute
}
25/08/2016 12:10
427 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Repeat
@Repeat indicates that the annotated test method must be executed repeatedly. The
number of times that the test method is to be executed is specified in the annotation.
The scope of execution to be repeated includes execution of the test method itself as well
as any set up or tear down of the test fixture.
@Repeat(10)
@Test
public void testProcessRepeatedly() {
// ...
}
25/08/2016 12:10
428 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Repeat
@Timed
@IfProfileValue
@ProfileValueSourceConfiguration
For example, if we discover that we are repeating the following configuration across our
JUnit 4 based test suite
@RunWith(SpringRunner.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public class OrderRepositoryTests { }
@RunWith(SpringRunner.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public class UserRepositoryTests { }
We can reduce the above duplication by introducing a custom composed annotation that
centralizes the common test configuration like this:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public @interface TransactionalDevTest { }
429 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
TestContext
TestContext encapsulates the context in which a test is executed, agnostic of the
actual testing framework in use, and provides context management and caching support
for the test instance for which it is responsible. The TestContext also delegates to a
SmartContextLoader to load an ApplicationContext if requested.
25/08/2016 12:10
430 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
TestContextManager
TestContextManager is the main entry point into the Spring TestContext Framework,
which manages a single TestContext and signals events to each registered
TestExecutionListener at well-defined test execution points:
prior to any before class or before all methods of a particular testing framework
test instance post-processing
prior to any before or before each methods of a particular testing framework
after any after or after each methods of a particular testing framework
after any after class or after all methods of a particular testing framework
TestExecutionListener
TestExecutionListener defines the API for reacting to test execution events published
by the TestContextManager with which the listener is registered. See Section 15.5.3,
TestExecutionListener configuration.
Context Loaders
ContextLoader is a strategy interface that was introduced in Spring 2.5 for loading an
ApplicationContext for an integration test managed by the Spring TestContext
Framework. Implement SmartContextLoader instead of this interface in order to
provide support for annotated classes, active bean definition profiles, test property
sources, context hierarchies, and WebApplicationContext support.
SmartContextLoader is an extension of the ContextLoader interface introduced in
Spring 3.1. The SmartContextLoader SPI supersedes the ContextLoader SPI that
was introduced in Spring 2.5. Specifically, a SmartContextLoader can choose to
process resource locations , annotated classes , or context initializers .
Furthermore, a SmartContextLoader can set active bean definition profiles and test
property sources in the context that it loads.
Spring provides the following implementations:
DelegatingSmartContextLoader : one of two default loaders which delegates
internally to an AnnotationConfigContextLoader , a
GenericXmlContextLoader , or a GenericGroovyXmlContextLoader depending
either on the configuration declared for the test class or on the presence of default
locations or default configuration classes. Groovy support is only enabled if Groovy is
on the classpath.
WebDelegatingSmartContextLoader : one of two default loaders which delegates
25/08/2016 12:10
431 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
internally to an AnnotationConfigWebContextLoader , a
GenericXmlWebContextLoader , or a GenericGroovyXmlWebContextLoader
depending either on the configuration declared for the test class or on the presence
of default locations or default configuration classes. A web ContextLoader will only
be used if @WebAppConfiguration is present on the test class. Groovy support is
only enabled if Groovy is on the classpath.
AnnotationConfigContextLoader : loads a standard ApplicationContext from
annotated classes.
AnnotationConfigWebContextLoader : loads a WebApplicationContext from
annotated classes.
GenericGroovyXmlContextLoader : loads a standard ApplicationContext from
resource locations that are either Groovy scripts or XML configuration files.
GenericGroovyXmlWebContextLoader : loads a WebApplicationContext from
resource locations that are either Groovy scripts or XML configuration files.
GenericXmlContextLoader : loads a standard ApplicationContext from XML
resource locations.
GenericXmlWebContextLoader : loads a WebApplicationContext from XML
resource locations.
GenericPropertiesContextLoader : loads a standard ApplicationContext from
Java Properties files.
25/08/2016 12:10
432 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
433 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Ordering TestExecutionListeners
When the TestContext framework discovers default TestExecutionListener s via the
aforementioned SpringFactoriesLoader mechanism, the instantiated listeners are
sorted using Springs AnnotationAwareOrderComparator which honors Springs
Ordered interface and @Order annotation for ordering.
AbstractTestExecutionListener and all default TestExecutionListener s
provided by Spring implement Ordered with appropriate values. Third-party frameworks
and developers should therefore make sure that their default TestExecutionListener s
are registered in the proper order by implementing Ordered or declaring @Order .
Consult the javadocs for the getOrder() methods of the core default
TestExecutionListener s for details on what values are assigned to each core listener.
Merging TestExecutionListeners
If a custom TestExecutionListener is registered via @TestExecutionListeners ,
the default listeners will not be registered. In most common testing scenarios, this
effectively forces the developer to manually declare all default listeners in addition to any
custom listeners. The following listing demonstrates this style of configuration.
@ContextConfiguration
@TestExecutionListeners({
MyCustomTestExecutionListener.class,
ServletTestExecutionListener.class,
DirtiesContextBeforeModesTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
SqlScriptsTestExecutionListener.class
})
public class MyTest {
// class body...
}
The challenge with this approach is that it requires that the developer know exactly which
listeners are registered by default. Moreover, the set of default listeners can change from
release to releasefor example, SqlScriptsTestExecutionListener was introduced
in Spring Framework 4.1, and DirtiesContextBeforeModesTestExecutionListener
25/08/2016 12:10
434 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
435 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Test classes that use the TestContext framework do not need to extend any particular
class or implement a specific interface to configure their application context. Instead,
configuration is achieved simply by declaring the @ContextConfiguration annotation
at the class level. If your test class does not explicitly declare application context resource
locations or annotated classes , the configured ContextLoader determines how to
load a context from a default location or default configuration classes. In addition to
context resource locations and annotated classes , an application context can also
be configured via application context initializers .
The following sections explain how to configure an ApplicationContext via XML
configuration files, Groovy scripts, annotated classes (typically @Configuration
classes), or context initializers using Springs @ContextConfiguration annotation.
Alternatively, you can implement and configure your own custom SmartContextLoader
25/08/2016 12:10
436 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you omit both the locations and value attributes from the
@ContextConfiguration annotation, the TestContext framework will attempt to detect a
default XML resource location. Specifically, GenericXmlContextLoader and
GenericXmlWebContextLoader detect a default location based on the name of the test
class. If your class is named com.example.MyTest , GenericXmlContextLoader loads
your application context from "classpath:com/example/MyTest-context.xml" .
package com.example;
@RunWith(SpringRunner.class)
25/08/2016 12:10
437 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from "/AppConfig.groovy" and
// "/TestConfig.groovy" in the root of the classpath
@ContextConfiguration({"/AppConfig.groovy", "/TestConfig.Groovy"})
public class MyTest {
// class body...
}
If you omit both the locations and value attributes from the
@ContextConfiguration annotation, the TestContext framework will attempt to detect a
default Groovy script. Specifically, GenericGroovyXmlContextLoader and
GenericGroovyXmlWebContextLoader detect a default location based on the name of
the test class. If your class is named com.example.MyTest , the Groovy context loader
will load your application context from
"classpath:com/example/MyTestContext.groovy" .
package com.example;
@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from
// "classpath:com/example/MyTestContext.groovy"
@ContextConfiguration
public class MyTest {
25/08/2016 12:10
438 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
// class body...
}
25/08/2016 12:10
439 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you omit the classes attribute from the @ContextConfiguration annotation, the
TestContext framework will attempt to detect the presence of default configuration
classes. Specifically, AnnotationConfigContextLoader and
AnnotationConfigWebContextLoader will detect all static nested classes of the test
class that meet the requirements for configuration class implementations as specified in
the @Configuration javadocs. In the following example, the OrderServiceTest class
declares a static nested configuration class named Config that will be automatically
used to load the ApplicationContext for the test class. Note that the name of the
configuration class is arbitrary. In addition, a test class can contain more than one
static nested configuration class if desired.
@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from the
// static nested Config class
@ContextConfiguration
public class OrderServiceTest {
@Configuration
static class Config {
// this bean will be injected into the OrderServiceTest class
@Bean
public OrderService orderService() {
OrderService orderService = new OrderServiceImpl();
// set properties, etc.
return orderService;
}
}
@Autowired
private OrderService orderService;
@Test
public void testOrderService() {
// test the orderService
}
}
25/08/2016 12:10
440 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
441 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
It is also possible to omit the declaration of XML configuration files, Groovy scripts, or
annotated classes in @ContextConfiguration entirely and instead declare only
ApplicationContextInitializer classes which are then responsible for registering
beans in the contextfor example, by programmatically loading bean definitions from
XML files or configuration classes.
@RunWith(SpringRunner.class)
// ApplicationContext will be initialized by EntireAppInitializer
// which presumably registers beans in the context
@ContextConfiguration(initializers = EntireAppInitializer.class)
public class MyTest {
// class body...
}
25/08/2016 12:10
442 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
In the following example that uses XML resource locations, the ApplicationContext
for ExtendedTest will be loaded from "base-config.xml" and "extended-config.xml", in
that order. Beans defined in "extended-config.xml" may therefore override (i.e., replace)
those defined in "base-config.xml".
@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from "/base-config.xml"
// in the root of the classpath
@ContextConfiguration("/base-config.xml")
public class BaseTest {
// class body...
}
// ApplicationContext will be loaded from "/base-config.xml" and
// "/extended-config.xml" in the root of the classpath
@ContextConfiguration("/extended-config.xml")
public class ExtendedTest extends BaseTest {
// class body...
}
In the following example that uses context initializers, the ApplicationContext for
ExtendedTest will be initialized using BaseInitializer and ExtendedInitializer .
Note, however, that the order in which the initializers are invoked depends on whether
they implement Springs Ordered interface or are annotated with Springs @Order
annotation or the standard @Priority annotation.
@RunWith(SpringRunner.class)
25/08/2016 12:10
443 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Lets take a look at some examples with XML configuration and @Configuration
classes.
<!-- app-config.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="...">
<bean id="transferService"
class="com.bank.service.internal.DefaultTransferService">
<constructor-arg ref="accountRepository"/>
<constructor-arg ref="feePolicy"/>
</bean>
<bean id="accountRepository"
class="com.bank.repository.internal.JdbcAccountRepository">
<constructor-arg ref="dataSource"/>
25/08/2016 12:10
444 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
</bean>
<bean id="feePolicy"
class="com.bank.service.internal.ZeroFeePolicy"/>
<beans profile="dev">
<jdbc:embedded-database id="dataSource">
<jdbc:script
location="classpath:com/bank/config/sql/schema.sql"/>
<jdbc:script
location="classpath:com/bank/config/sql/test-data.sql"/>
</jdbc:embedded-database>
</beans>
<beans profile="production">
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"
</beans>
<beans profile="default">
<jdbc:embedded-database id="dataSource">
<jdbc:script
location="classpath:com/bank/config/sql/schema.sql"/>
</jdbc:embedded-database>
</beans>
</beans>
package com.bank.service;
@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from "classpath:/app-config.xml"
@ContextConfiguration("/app-config.xml")
@ActiveProfiles("dev")
public class TransferServiceTest {
@Autowired
private TransferService transferService;
@Test
public void testTransferService() {
// test the transferService
}
}
25/08/2016 12:10
445 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
446 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Profile("default")
public class DefaultDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.build();
}
}
@Configuration
public class TransferServiceConfig {
@Autowired DataSource dataSource;
@Bean
public TransferService transferService() {
return new DefaultTransferService(accountRepository(), feePolicy());
}
@Bean
public AccountRepository accountRepository() {
return new JdbcAccountRepository(dataSource);
}
@Bean
public FeePolicy feePolicy() {
return new ZeroFeePolicy();
}
}
package com.bank.service;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {
TransferServiceConfig.class,
StandaloneDataConfig.class,
JndiDataConfig.class,
DefaultDataConfig.class})
@ActiveProfiles("dev")
public class TransferServiceTest {
@Autowired
private TransferService transferService;
25/08/2016 12:10
447 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Test
public void testTransferService() {
// test the transferService
}
}
In this variation, we have split the XML configuration into four independent
@Configuration classes:
TransferServiceConfig : acquires a dataSource via dependency injection using
@Autowired
StandaloneDataConfig : defines a dataSource for an embedded database
suitable for developer tests
JndiDataConfig : defines a dataSource that is retrieved from JNDI in a production
environment
DefaultDataConfig : defines a dataSource for a default embedded database in
case no profile is active
As with the XML-based configuration example, we still annotate TransferServiceTest
with @ActiveProfiles("dev") , but this time we specify all four configuration classes
via the @ContextConfiguration annotation. The body of the test class itself remains
completely unchanged.
It is often the case that a single set of profiles is used across multiple test classes within a
given project. Thus, to avoid duplicate declarations of the @ActiveProfiles annotation
it is possible to declare @ActiveProfiles once on a base class, and subclasses will
automatically inherit the @ActiveProfiles configuration from the base class. In the
following example, the declaration of @ActiveProfiles (as well as other annotations)
has been moved to an abstract superclass, AbstractIntegrationTest .
package com.bank.service;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {
TransferServiceConfig.class,
StandaloneDataConfig.class,
JndiDataConfig.class,
DefaultDataConfig.class})
@ActiveProfiles("dev")
public abstract class AbstractIntegrationTest {
}
package com.bank.service;
25/08/2016 12:10
448 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
449 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
450 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Inlined properties in the form of key-value pairs can be configured via the properties
attribute of @TestPropertySource as shown in the following example. All key-value
pairs will be added to the enclosing Environment as a single test PropertySource
with the highest precedence.
The supported syntax for key-value pairs is the same as the syntax defined for entries in
a Java properties file:
"key=value"
"key:value"
"key value"
@ContextConfiguration
@TestPropertySource(properties = {"timezone = GMT", "port: 4242"})
public class MyIntegrationTests {
// class body...
}
25/08/2016 12:10
451 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Test property sources have higher precedence than those loaded from the operating
systems environment or Java system properties as well as property sources added by
the application declaratively via @PropertySource or programmatically. Thus, test
property sources can be used to selectively override properties defined in system and
application property sources. Furthermore, inlined properties have higher precedence
than properties loaded from resource locations.
In the following example, the timezone and port properties as well as any properties
defined in "/test.properties" will override any properties of the same name that are
defined in system and application property sources. Furthermore, if the
"/test.properties" file defines entries for the timezone and port properties those
will be overridden by the inlined properties declared via the properties attribute.
@ContextConfiguration
@TestPropertySource(
locations = "/test.properties",
properties = {"timezone = GMT", "port: 4242"}
)
public class MyIntegrationTests {
// class body...
}
25/08/2016 12:10
452 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
locations.
@TestPropertySource("base.properties")
@ContextConfiguration
public class BaseTest {
// ...
}
@TestPropertySource("extended.properties")
@ContextConfiguration
public class ExtendedTest extends BaseTest {
// ...
}
In the following example, the ApplicationContext for BaseTest will be loaded using
only the inlined key1 property. In contrast, the ApplicationContext for
ExtendedTest will be loaded using the inlined key1 and key2 properties.
@TestPropertySource(properties = "key1 = value1")
@ContextConfiguration
public class BaseTest {
// ...
}
@TestPropertySource(properties = "key2 = value2")
@ContextConfiguration
public class ExtendedTest extends BaseTest {
// ...
}
Loading a WebApplicationContext
Spring 3.2 introduced support for loading a WebApplicationContext in integration
tests. To instruct the TestContext framework to load a WebApplicationContext instead
of a standard ApplicationContext , simply annotate the respective test class with
@WebAppConfiguration .
The presence of @WebAppConfiguration on your test class instructs the TestContext
framework (TCF) that a WebApplicationContext (WAC) should be loaded for your
integration tests. In the background the TCF makes sure that a MockServletContext is
created and supplied to your tests WAC. By default the base resource path for your
MockServletContext will be set to "src/main/webapp". This is interpreted as a path
relative to the root of your JVM (i.e., normally the path to your project). If youre familiar
with the directory structure of a web application in a Maven project, youll know that
25/08/2016 12:10
453 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
"src/main/webapp" is the default location for the root of your WAR. If you need to override
this default, simply provide an alternate path to the @WebAppConfiguration annotation
(e.g., @WebAppConfiguration("src/test/webapp") ). If you wish to reference a base
resource path from the classpath instead of the file system, just use Springs classpath:
prefix.
Please note that Springs testing support for WebApplicationContexts is on par with its
support for standard ApplicationContexts . When testing with a
WebApplicationContext you are free to declare XML configuration files, Groovy
scripts, or @Configuration classes via @ContextConfiguration . You are of course
also free to use any other test annotations such as @ActiveProfiles ,
@TestExecutionListeners , @Sql , @Rollback , etc.
The following examples demonstrate some of the various configuration options for
loading a WebApplicationContext .
Conventions.
@RunWith(SpringRunner.class)
// defaults to "file:src/main/webapp"
@WebAppConfiguration
// detects "WacTests-context.xml" in same package
// or static nested @Configuration class
@ContextConfiguration
public class WacTests {
//...
}
The above example demonstrates the TestContext frameworks support for convention
over configuration. If you annotate a test class with @WebAppConfiguration without
specifying a resource base path, the resource path will effectively default to "file:src/main
/webapp". Similarly, if you declare @ContextConfiguration without specifying resource
locations , annotated classes , or context initializers , Spring will attempt to
detect the presence of your configuration using conventions (i.e., "WacTests-context.xml"
in the same package as the WacTests class or static nested @Configuration classes).
Default resource semantics.
@RunWith(SpringRunner.class)
// file system resource
25/08/2016 12:10
454 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@WebAppConfiguration("webapp")
// classpath resource
@ContextConfiguration("/spring/test-servlet-config.xml")
public class WacTests {
//...
}
This example demonstrates how to explicitly declare a resource base path with
@WebAppConfiguration and an XML resource location with @ContextConfiguration .
The important thing to note here is the different semantics for paths with these two
annotations. By default, @WebAppConfiguration resource paths are file system based;
whereas, @ContextConfiguration resource locations are classpath based.
Explicit resource semantics.
@RunWith(SpringRunner.class)
// classpath resource
@WebAppConfiguration("classpath:test-web-resources")
// file system resource
@ContextConfiguration("file:src/main/webapp/WEB-INF/servlet-config.xml")
public class WacTests {
//...
}
In this third example, we see that we can override the default resource semantics for both
annotations by specifying a Spring resource prefix. Contrast the comments in this
example with the previous example.
To provide comprehensive web testing support, Spring 3.2 introduced a
ServletTestExecutionListener that is enabled by default. When testing against a
WebApplicationContext this TestExecutionListener sets up default thread-local state
via Spring Webs RequestContextHolder before each test method and creates a
MockHttpServletRequest , MockHttpServletResponse , and ServletWebRequest
based on the base resource path configured via @WebAppConfiguration .
ServletTestExecutionListener also ensures that the MockHttpServletResponse
and ServletWebRequest can be injected into the test instance, and once the test is
complete it cleans up thread-local state.
Once you have a WebApplicationContext loaded for your test you might find that you
25/08/2016 12:10
455 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
perform assertions after invoking your web component. The following example
demonstrates which mocks can be autowired into your test instance. Note that the
WebApplicationContext and MockServletContext are both cached across the test
suite; whereas, the other mocks are managed per test method by the
ServletTestExecutionListener .
Injecting mocks.
@WebAppConfiguration
@ContextConfiguration
public class WacTests {
@Autowired
WebApplicationContext wac; // cached
@Autowired
MockServletContext servletContext; // cached
@Autowired
MockHttpSession session;
@Autowired
MockHttpServletRequest request;
@Autowired
MockHttpServletResponse response;
@Autowired
ServletWebRequest webRequest;
//...
}
Context caching
Once the TestContext framework loads an ApplicationContext (or
WebApplicationContext ) for a test, that context will be cached and reused for all
subsequent tests that declare the same unique context configuration within the same test
suite. To understand how caching works, it is important to understand what is meant by
unique and test suite.
An ApplicationContext can be uniquely identified by the combination of configuration
parameters that are used to load it. Consequently, the unique combination of
configuration parameters are used to generate a key under which the context is cached.
The TestContext framework uses the following configuration parameters to build the
25/08/2016 12:10
456 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
457 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Since Spring Framework 4.3, the size of the context cache is bounded with a default
maximum size of 32. Whenever the maximum size is reached, a least recently used
(LRU) eviction policy is used to evict and close stale contexts. The maximum size can be
configured from the command line or a build script by setting a JVM system property
named spring.test.context.cache.maxSize . As an alternative, the same property
can be set programmatically via the SpringProperties API.
Since having a large number of application contexts loaded within a given test suite can
cause the suite to take an unnecessarily long time to execute, it is often beneficial to
know exactly how many contexts have been loaded and cached. To view the statistics for
the underlying context cache, simply set the log level for the
org.springframework.test.context.cache logging category to DEBUG .
In the unlikely case that a test corrupts the application context and requires reloading
for example, by modifying a bean definition or the state of an application objectyou can
annotate your test class or test method with @DirtiesContext (see the discussion of
@DirtiesContext in Section 15.4.1, Spring Testing Annotations). This instructs Spring
to remove the context from the cache and rebuild the application context before executing
the next test. Note that support for the @DirtiesContext annotation is provided by the
DirtiesContextBeforeModesTestExecutionListener and the
DirtiesContextTestExecutionListener which are enabled by default.
Context hierarchies
When writing integration tests that rely on a loaded Spring ApplicationContext , it is
often sufficient to test against a single context; however, there are times when it is
beneficial or even necessary to test against a hierarchy of ApplicationContext s. For
example, if you are developing a Spring MVC web application you will typically have a
root WebApplicationContext loaded via Springs ContextLoaderListener and a
child WebApplicationContext loaded via Springs DispatcherServlet . This results
in a parent-child context hierarchy where shared components and infrastructure
configuration are declared in the root context and consumed in the child context by
web-specific components. Another use case can be found in Spring Batch applications
where you often have a parent context that provides configuration for shared batch
infrastructure and a child context for the configuration of a specific batch job.
Since Spring Framework 3.2.2, it is possible to write integration tests that use context
hierarchies by declaring context configuration via the @ContextHierarchy annotation,
either on an individual test class or within a test class hierarchy. If a context hierarchy is
declared on multiple classes within a test class hierarchy it is also possible to merge or
override the context configuration for a specific, named level in the context hierarchy.
25/08/2016 12:10
458 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
When merging configuration for a given level in the hierarchy the configuration resource
type (i.e., XML configuration files or annotated classes) must be consistent; otherwise, it
is perfectly acceptable to have different levels in a context hierarchy configured using
different resource types.
The following JUnit 4 based examples demonstrate common configuration scenarios for
integration tests that require the use of context hierarchies.
ControllerIntegrationTests represents a typical integration testing scenario for a
Spring MVC web application by declaring a context hierarchy consisting of two levels, one
for the root WebApplicationContext (loaded using the TestAppConfig
@Configuration class) and one for the dispatcher servlet WebApplicationContext
(loaded using the WebConfig @Configuration class). The WebApplicationContext
that is autowired into the test instance is the one for the child context (i.e., the lowest
context in the hierarchy).
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextHierarchy({
@ContextConfiguration(classes = TestAppConfig.class),
@ContextConfiguration(classes = WebConfig.class)
})
public class ControllerIntegrationTests {
@Autowired
private WebApplicationContext wac;
// ...
}
The following test classes define a context hierarchy within a test class hierarchy.
AbstractWebTests declares the configuration for a root WebApplicationContext in a
Spring-powered web application. Note, however, that AbstractWebTests does not
declare @ContextHierarchy ; consequently, subclasses of AbstractWebTests can
optionally participate in a context hierarchy or simply follow the standard semantics for
@ContextConfiguration . SoapWebServiceTests and RestWebServiceTests both
extend AbstractWebTests and define a context hierarchy via @ContextHierarchy .
The result is that three application contexts will be loaded (one for each declaration of
@ContextConfiguration ), and the application context loaded based on the
configuration in AbstractWebTests will be set as the parent context for each of the
contexts loaded for the concrete subclasses.
@RunWith(SpringRunner.class)
25/08/2016 12:10
459 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@WebAppConfiguration
@ContextConfiguration("file:src/main/webapp/WEB-INF/applicationContext.xml")
public abstract class AbstractWebTests {}
@ContextHierarchy(@ContextConfiguration("/spring/soap-ws-config.xml")
public class SoapWebServiceTests extends AbstractWebTests {}
@ContextHierarchy(@ContextConfiguration("/spring/rest-ws-config.xml")
public class RestWebServiceTests extends AbstractWebTests {}
The following classes demonstrate the use of named hierarchy levels in order to merge
the configuration for specific levels in a context hierarchy. BaseTests defines two levels
in the hierarchy, parent and child . ExtendedTests extends BaseTests and
instructs the Spring TestContext Framework to merge the context configuration for the
child hierarchy level, simply by ensuring that the names declared via the name
attribute in @ContextConfiguration are both "child" . The result is that three
application contexts will be loaded: one for "/app-config.xml" , one for
"/user-config.xml" , and one for {"/user-config.xml", "/order-config.xml"} .
As with the previous example, the application context loaded from "/app-config.xml"
will be set as the parent context for the contexts loaded from "/user-config.xml" and
{"/user-config.xml", "/order-config.xml"} .
@RunWith(SpringRunner.class)
@ContextHierarchy({
@ContextConfiguration(name = "parent", locations = "/app-config.xml"),
@ContextConfiguration(name = "child", locations = "/user-config.xml")
})
public class BaseTests {}
@ContextHierarchy(
@ContextConfiguration(name = "child", locations = "/order-config.xml")
)
public class ExtendedTests extends BaseTests {}
In contrast to the previous example, this example demonstrates how to override the
configuration for a given named level in a context hierarchy by setting the
inheritLocations flag in @ContextConfiguration to false . Consequently, the
application context for ExtendedTests will be loaded only from
"/test-user-config.xml" and will have its parent set to the context loaded from
"/app-config.xml" .
@RunWith(SpringRunner.class)
@ContextHierarchy({
@ContextConfiguration(name = "parent", locations = "/app-config.xml"),
25/08/2016 12:10
460 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The TestContext framework does not instrument the manner in which a test
instance is instantiated. Thus the use of @Autowired or @Inject for
constructors has no effect for test classes.
Because @Autowired is used to perform autowiring by type, if you have multiple bean
definitions of the same type, you cannot rely on this approach for those particular beans.
In that case, you can use @Autowired in conjunction with @Qualifier . As of Spring 3.0
you may also choose to use @Inject in conjunction with @Named . Alternatively, if your
test class has access to its ApplicationContext , you can perform an explicit lookup by
using (for example) a call to applicationContext.getBean("titleRepository") .
25/08/2016 12:10
461 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
annotate fields or setter methods with @Autowired or @Inject . Alternatively, you can
disable dependency injection altogether by explicitly configuring your class with
@TestExecutionListeners and omitting
DependencyInjectionTestExecutionListener.class from the list of listeners.
Consider the scenario of testing a HibernateTitleRepository class, as outlined in the
Goals section. The next two code listings demonstrate the use of @Autowired on fields
and setter methods. The application context configuration is presented after all sample
code listings.
The first code listing shows a JUnit 4 based implementation of the test class that uses
@Autowired for field injection.
@RunWith(SpringRunner.class)
// specifies the Spring configuration to load for this test fixture
@ContextConfiguration("repository-config.xml")
public class HibernateTitleRepositoryTests {
// this instance will be dependency injected by type
@Autowired
private HibernateTitleRepository titleRepository;
@Test
public void findById() {
Title title = titleRepository.findById(new Long(10));
assertNotNull(title);
}
}
Alternatively, you can configure the class to use @Autowired for setter injection as seen
below.
@RunWith(SpringRunner.class)
// specifies the Spring configuration to load for this test fixture
25/08/2016 12:10
462 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The preceding code listings use the same XML context file referenced by the
@ContextConfiguration annotation (that is, repository-config.xml ), which looks
like this:
<?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.xsd">
<!-- this bean will be injected into the HibernateTitleRepositoryTests class -->
<bean id="titleRepository" class="com.foo.repository.hibernate.HibernateTitleRepos
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
If you are extending from a Spring-provided test base class that happens to use @Autowired
one of its setter methods, you might have multiple beans of the affected type defined in your
application context: for example, multiple DataSource beans. In such a case, you can overr
the setter method and use the @Qualifier annotation to indicate a specific target bean as
follows, but make sure to delegate to the overridden method in the superclass as well.
// ...
25/08/2016 12:10
463 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Autowired
@Override
public void setDataSource(@Qualifier("myDataSource") DataSource dataSource
super.setDataSource(dataSource);
}
// ...
The specified qualifier value indicates the specific DataSource bean to inject, narrowing the
of type matches to a specific bean. Its value is matched against <qualifier> declarations
within the corresponding <bean> definitions. The bean name is used as a fallback qualifier
value, so you may effectively also point to a specific bean by name there (as shown above,
assuming that "myDataSource" is the bean id).
25/08/2016 12:10
464 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The following code snippet is similar to the one we saw above for a request-scoped bean;
however, this time the userService bean has a dependency on a session-scoped
userPreferences bean. Note that the UserPreferences bean is instantiated using a
SpEL expression that retrieves the theme from the current HTTP session. In our test, we
will need to configure a theme in the mock session managed by the TestContext
25/08/2016 12:10
465 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
framework.
Session-scoped bean configuration.
<beans>
<bean id="userService"
class="com.example.SimpleUserService"
c:userPreferences-ref="userPreferences" />
<bean id="userPreferences"
class="com.example.UserPreferences"
c:theme="#{session.getAttribute('theme')}"
scope="session">
<aop:scoped-proxy />
</bean>
</beans>
25/08/2016 12:10
466 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Test-managed transactions
Test-managed transactions are transactions that are managed declaratively via the
TransactionalTestExecutionListener or programmatically via TestTransaction
(see below). Such transactions should not be confused with Spring-managed transactions
(i.e., those managed directly by Spring within the ApplicationContext loaded for tests)
or application-managed transactions (i.e., those managed programmatically within
application code that is invoked via tests). Spring-managed and application-managed
transactions will typically participate in test-managed transactions; however, caution
should be taken if Spring-managed or application-managed transactions are configured
with any propagation type other than REQUIRED or SUPPORTS (see the discussion on
transaction propagation for details).
25/08/2016 12:10
467 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
rollback and commit behavior, there is no need to clean up the database after the
createUser() method is executed since any changes made to the database will be
automatically rolled back by the TransactionalTestExecutionListener . See
Section 15.7, PetClinic Example for an additional example.
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = TestConfig.class)
@Transactional
public class HibernateUserRepositoryTests {
@Autowired
HibernateUserRepository repository;
@Autowired
SessionFactory sessionFactory;
JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Test
public void createUser() {
// track initial state in test database:
final int count = countRowsInTable("user");
User user = new User(...);
repository.save(user);
// Manual flush is required to avoid false positive in test
sessionFactory.getCurrentSession().flush();
assertNumUsers(count + 1);
}
protected int countRowsInTable(String tableName) {
return JdbcTestUtils.countRowsInTable(this.jdbcTemplate, tableName);
}
25/08/2016 12:10
468 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
By default, test transactions will be automatically rolled back after completion of the test;
however, transactional commit and rollback behavior can be configured declaratively via
the @Commit and @Rollback annotations. See the corresponding entries in the
annotation support section for further details.
25/08/2016 12:10
469 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
470 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@ContextConfiguration
@Transactional(transactionManager = "txMgr")
@Commit
public class FictitiousTransactionalTest {
@BeforeTransaction
void verifyInitialDatabaseState() {
// logic to verify the initial state before a transaction is started
}
@Before
public void setUpTestDataWithinTransaction() {
// set up test data within the transaction
}
@Test
// overrides the class-level @Commit setting
@Rollback
public void modifyDatabaseWithinTransaction() {
// logic which uses the test data and modifies database state
}
@After
public void tearDownWithinTransaction() {
// execute "tear down" logic within the transaction
}
@AfterTransaction
void verifyFinalDatabaseState() {
// logic to verify the final state after transaction has rolled back
}
}
When you test application code that manipulates the state of a Hibernate session
or JPA persistence context, make sure to flush the underlying unit of work within
test methods that execute that code. Failing to flush the underlying unit of work can
produce false positives: your test may pass, but the same code throws an
exception in a live, production environment. In the following Hibernate-based
example test case, one method demonstrates a false positive, and the other
method correctly exposes the results of flushing the session. Note that this applies
to any ORM frameworks that maintain an in-memory unit of work.
// ...
@Autowired
25/08/2016 12:10
471 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
SessionFactory sessionFactory;
@Transactional
@Test // no expected exception!
public void falsePositive() {
updateEntityInHibernateSession();
// False positive: an exception will be thrown once the Hibernate
// Session is finally flushed (i.e., in production code)
}
@Transactional
@Test(expected = ...)
public void updateWithSessionFlush() {
updateEntityInHibernateSession();
// Manual flush is required to avoid false positive in test
sessionFactory.getCurrentSession().flush();
}
// ...
Or for JPA:
// ...
@PersistenceContext
EntityManager entityManager;
@Transactional
@Test // no expected exception!
public void falsePositive() {
updateEntityInJpaPersistenceContext();
// False positive: an exception will be thrown once the JPA
// EntityManager is finally flushed (i.e., in production code)
}
@Transactional
@Test(expected = ...)
public void updateWithEntityManagerFlush() {
updateEntityInJpaPersistenceContext();
// Manual flush is required to avoid false positive in test
entityManager.flush();
}
// ...
25/08/2016 12:10
472 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringConte
org.springframework.test.context.testng.AbstractTransactionalTestNGSpringConte
ScriptUtils provides a collection of static utility methods for working with SQL scripts
and is mainly intended for internal use within the framework. However, if you require full
control over how SQL scripts are parsed and executed, ScriptUtils may suit your
needs better than some of the other alternatives described below. Consult the javadocs
for individual methods in ScriptUtils for further details.
ResourceDatabasePopulator provides a simple object-based API for programmatically
populating, initializing, or cleaning up a database using SQL scripts defined in external
resources. ResourceDatabasePopulator provides options for configuring the character
encoding, statement separator, comment delimiters, and error handling flags used when
parsing and executing the scripts, and each of the configuration options has a reasonable
default value. Consult the javadocs for details on default values. To execute the scripts
configured in a ResourceDatabasePopulator , you can invoke either the
populate(Connection) method to execute the populator against a
java.sql.Connection or the execute(DataSource) method to execute the populator
against a javax.sql.DataSource . The following example specifies SQL scripts for a
test schema and test data, sets the statement separator to "@@" , and then executes the
scripts against a DataSource .
25/08/2016 12:10
473 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
474 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Test
public void emptySchemaTest {
// execute code that uses the test schema without any test data
}
@Test
@Sql({"/test-schema.sql", "/test-user-data.sql"})
public void userTest {
// execute code that uses the test schema and test data
}
}
The following example is identical to the above except that the @Sql declarations are
grouped together within @SqlGroup for compatibility with Java 6 and Java 7.
25/08/2016 12:10
475 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Test
@SqlGroup({
@Sql(scripts = "/test-schema.sql", config = @SqlConfig(commentPrefix = "`")),
@Sql("/test-user-data.sql")
)}
public void userTest {
// execute code that uses the test schema and test data
}
25/08/2016 12:10
476 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
477 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
478 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@RunWith(SpringRunner.class)
@TestExecutionListeners({})
public class SimpleTest {
@Test
public void testMethod() {
// execute test logic...
}
}
25/08/2016 12:10
479 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
These classes are a convenience for extension. If you do not want your test
classes to be tied to a Spring-specific class hierarchy, you can configure
your own custom test classes by using @RunWith(SpringRunner.class)
or Springs JUnit rules.
25/08/2016 12:10
480 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
These classes are a convenience for extension. If you do not want your test
classes to be tied to a Spring-specific class hierarchy, you can configure
your own custom test classes by using @ContextConfiguration ,
@TestExecutionListeners , and so on, and by manually instrumenting
your test class with a TestContextManager . See the source code of
AbstractTestNGSpringContextTests for an example of how to
instrument your test class.
25/08/2016 12:10
481 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The Spring MVC Test framework provides first class support for testing Spring MVC code
using a fluent API that can be used with JUnit, TestNG, or any other testing framework.
Its built on the Servlet API mock objects from the spring-test module and hence does
not use a running Servlet container. It uses the DispatcherServlet to provide full
Spring MVC runtime behavior and provides support for loading actual Spring
configuration with the TestContext framework in addition to a standalone mode in which
controllers may be instantiated manually and tested one at a time.
Spring MVC Test also provides client-side support for testing code that uses the
RestTemplate . Client-side tests mock the server responses and also do not use a
running server.
Spring Boot provides an option to write full, end-to-end integration tests that
include a running server. If this is your goal please have a look at the Spring
Boot reference page. For more information on the differences between
out-of-container and end-to-end integration tests, see the section called
Differences between Out-of-Container and End-to-End Integration Tests.
25/08/2016 12:10
482 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration("test-servlet-context.xml")
public class ExampleTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void getAccount() throws Exception {
this.mockMvc.perform(get("/accounts/1").accept(MediaType.parseMediaType(
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.name").value("Lee"));
}
}
Static Imports
The fluent API in the example above requires a few static imports such as
MockMvcRequestBuilders.* , MockMvcResultMatchers.* , and
MockMvcBuilders.* . An easy way to find these classes is to search for types matching
"MockMvc*". If using Eclipse, be sure to add them as "favorite static members" in the
Eclipse preferences under Java Editor Content Assist Favorites. That will allow
use of content assist after typing the first character of the static method name. Other IDEs
25/08/2016 12:10
483 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
(e.g. IntelliJ) may not require any additional configuration. Just check the support for code
completion on static members.
Setup Options
There are two main options for creating an instance of MockMvc . The first is to load
Spring MVC configuration through the TestContext framework, which loads the Spring
configuration and injects a WebApplicationContext into the test to use to build a
MockMvc instance:
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration("my-servlet-context.xml")
public class MyWebTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
// ...
}
The second is to simply create a controller instance manually without loading Spring
configuration. Instead basic default configuration, roughly comparable to that of the MVC
JavaConfig or the MVC namespace, is automatically created and can be customized to a
degree:
public class MyWebTests {
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build(
}
// ...
25/08/2016 12:10
484 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
You can then inject the mock service into the test in order set up and verify expectations:
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration("test-servlet-context.xml")
public class AccountTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Autowired
private AccountService accountService;
// ...
}
The "standaloneSetup" on the other hand is a little closer to a unit test. It tests one
controller at a time: the controller can be injected with mock dependencies manually, and
it doesnt involve loading Spring configuration. Such tests are more focused on style and
make it easier to see which controller is being tested, whether any specific Spring MVC
configuration is required to work, and so on. The "standaloneSetup" is also a very
convenient way to write ad-hoc tests to verify specific behavior or to debug an issue.
Just like with any "integration vs. unit testing" debate, there is no right or wrong answer.
However, using the "standaloneSetup" does imply the need for additional
"webAppContextSetup" tests in order to verify your Spring MVC configuration.
25/08/2016 12:10
485 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Performing Requests
Its easy to perform requests using any HTTP method:
mockMvc.perform(post("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON));
You can also perform file upload requests that internally use
MockMultipartHttpServletRequest so that there is no actual parsing of a multipart
request but rather you have to set it up:
mockMvc.perform(fileUpload("/doc").file("a1", "ABC".getBytes("UTF-8")));
Or you can add Servlet request parameters representing either query of form parameters:
mockMvc.perform(get("/hotels").param("foo", "bar"));
If application code relies on Servlet request parameters and doesnt check the query
string explicitly (as is most often the case) then it doesnt matter which option you use.
Keep in mind however that query params provided with the URI template will be decoded
while request parameters provided through the param() method are expected to
already be decoded.
In most cases its preferable to leave out the context path and the Servlet path from the
request URI. If you must test with the full request URI, be sure to set the contextPath
and servletPath accordingly so that request mappings will work:
mockMvc.perform(get("/app/main/hotels/{id}").contextPath("/app").servletPath(
Looking at the above example, it would be cumbersome to set the contextPath and
servletPath with every performed request. Instead you can set up default request
properties:
public class MyWebTests {
private MockMvc mockMvc;
@Before
25/08/2016 12:10
486 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The above properties will affect every request performed through the MockMvc instance.
If the same property is also specified on a given request, it overrides the default value.
That is why the HTTP method and URI in the default request dont matter since they must
be specified on every request.
Defining Expectations
Expectations can be defined by appending one or more .andExpect(..) calls after
performing a request:
mockMvc.perform(get("/accounts/1")).andExpect(status().isOk());
Many times when writing tests, its useful to dump the results of the performed request.
This can be done as follows, where print() is a static import from
MockMvcResultHandlers :
mockMvc.perform(post("/persons"))
.andDo(print())
.andExpect(status().isOk())
25/08/2016 12:10
487 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
.andExpect(model().attributeHasErrors("person"));
As long as request processing does not cause an unhandled exception, the print()
method will print all the available result data to System.out . Spring Framework 4.2
introduced a log() method and two additional variants of the print() method, one
that accepts an OutputStream and one that accepts a Writer . For example, invoking
print(System.err) will print the result data to System.err ; while invoking
print(myWriter) will print the result data to a custom writer. If you would like to have
the result data logged instead of printed, simply invoke the log() method which will log
the result data as a single DEBUG message under the
org.springframework.test.web.servlet.result logging category.
In some cases, you may want to get direct access to the result and verify something that
cannot be verified otherwise. This can be achieved by appending .andReturn() after all
other expectations:
If all tests repeat the same expectations you can set up common expectations once when
building the MockMvc instance:
standaloneSetup(new SimpleController())
.alwaysExpect(status().isOk())
.alwaysExpect(content().contentType("application/json;charset=UTF-8"))
.build()
Note that common expectations are always applied and cannot be overridden without
creating a separate MockMvc instance.
When JSON response content contains hypermedia links created with Spring HATEOAS,
the resulting links can be verified using JsonPath expressions:
mockMvc.perform(get("/people").accept(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.links[?(@.rel == 'self')].href").value("http://localhost:80
When XML response content contains hypermedia links created with Spring HATEOAS,
the resulting links can be verified using XPath expressions:
25/08/2016 12:10
488 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Filter Registrations
When setting up a MockMvc instance, you can register one or more Servlet Filter
instances:
Registered filters will be invoked through via the MockFilterChain from spring-test ,
and the last filter will delegate to the DispatcherServlet .
25/08/2016 12:10
489 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
490 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
web application that supports CRUD operations on a Message object. The application
also supports paging through all messages. How would you go about testing it?
With Spring MVC Test, we can easily test if we are able to create a Message .
MockHttpServletRequestBuilder createMessage = post("/messages/")
.param("summary", "Spring Rocks")
.param("text", "In case you didn't know, Spring Rocks!");
mockMvc.perform(createMessage)
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/messages/123"));
What if we want to test our form view that allows us to create the message? For example,
assume our form looks like the following snippet:
<form id="messageForm" action="/messages/" method="post">
<div class="pull-right"><a href="/messages/">Messages</a></div>
<label for="summary">Summary</label>
<input type="text" class="required" id="summary" name="summary" value="" />
<label for="text">Message</label>
<textarea id="text" name="text"></textarea>
<div class="form-actions">
<input type="submit" value="Create" />
</div>
</form>
How do we ensure that our form will produce the correct request to create a new
message? A naive attempt would look like this:
mockMvc.perform(get("/messages/form"))
.andExpect(xpath("//input[@name='summary']").exists())
.andExpect(xpath("//textarea[@name='text']").exists());
This test has some obvious drawbacks. If we update our controller to use the parameter
message instead of text , our form test would continue to pass even though the HTML
form is out of synch with the controller. To resolve this we can combine our two tests.
String summaryParamName = "summary";
String textParamName = "text";
mockMvc.perform(get("/messages/form"))
.andExpect(xpath("//input[@name='" + summaryParamName + "']"
.andExpect(xpath("//textarea[@name='" + textParamName + "']"
25/08/2016 12:10
491 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
This would reduce the risk of our test incorrectly passing, but there are still some
problems.
What if we have multiple forms on our page? Admittedly we could update our xpath
expressions, but they get more complicated the more factors we take into account
(Are the fields the correct type? Are the fields enabled? etc.).
Another issue is that we are doing double the work we would expect. We must first
verify the view, and then we submit the view with the same parameters we just
verified. Ideally this could be done all at once.
Finally, there are some things that we still cannot account for. For example, what if
the form has JavaScript validation that we wish to test as well?
The overall problem is that testing a web page does not involve a single interaction.
Instead, it is a combination of how the user interacts with a web page and how that web
page interacts with other resources. For example, the result of a form view is used as the
input to a user for creating a message. In addition, our form view may potentially utilize
additional resources which impact the behavior of the page, such as JavaScript
validation.
25/08/2016 12:10
492 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
key constraints.
Testing can become slow since each test would need to ensure that the database is
in the correct state.
Since our database needs to be in a specific state, we cannot run tests in parallel.
Performing assertions on things like auto-generated ids, timestamps, etc. can be
difficult.
These challenges do not mean that we should abandon end-to-end integration testing
altogether. Instead, we can reduce the number of end-to-end integration tests by
refactoring our detailed tests to use mock services which will execute much faster, more
reliably, and without side effects. We can then implement a small number of true
end-to-end integration tests that validate simple workflows to ensure that everything
works together properly.
25/08/2016 12:10
493 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
MockMvcWebClientBuilder as follows.
@Autowired
WebApplicationContext context;
WebClient webClient;
@Before
public void setup() {
webClient = MockMvcWebClientBuilder
.webAppContextSetup(context)
.build();
}
This will ensure that any URL referencing localhost as the server will be directed to
our MockMvc instance without the need for a real HTTP connection. Any other URL will
be requested using a network connection as normal. This allows us to easily test the use
of CDNs.
The default context path is "" . Alternatively, we can specify the context
path as illustrated in the section called Advanced
MockMvcWebClientBuilder.
Once we have a reference to the HtmlPage , we can then fill out the form and submit it to
create a message.
HtmlForm form = createMsgFormPage.getHtmlElementById("messageForm");
HtmlTextInput summaryInput = createMsgFormPage.getHtmlElementById("summary");
25/08/2016 12:10
494 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Finally, we can verify that a new message was created successfully. The following
assertions use the AssertJ library.
assertThat(newMessagePage.getUrl().toString()).endsWith("/messages/123");
String id = newMessagePage.getHtmlElementById("id").getTextContent();
assertThat(id).isEqualTo("123");
String summary = newMessagePage.getHtmlElementById("summary").getTextContent();
assertThat(summary).isEqualTo("Spring Rocks");
String text = newMessagePage.getHtmlElementById("text").getTextContent();
assertThat(text).isEqualTo("In case you didn't know, Spring Rocks!");
This improves on our MockMvc test in a number of ways. First we no longer have to
explicitly verify our form and then create a request that looks like the form. Instead, we
request the form, fill it out, and submit it, thereby significantly reducing the overhead.
Another important factor is that HtmlUnit uses the Mozilla Rhino engine to evaluate
JavaScript. This means that we can test the behavior of JavaScript within our pages as
well!
Refer to the HtmlUnit documentation for additional information about using HtmlUnit.
Advanced MockMvcWebClientBuilder
In the examples so far, we have used MockMvcWebClientBuilder in the simplest way
possible, by building a WebClient based on the WebApplicationContext loaded for
us by the Spring TestContext Framework. This approach is repeated here.
@Autowired
WebApplicationContext context;
WebClient webClient;
@Before
public void setup() {
webClient = MockMvcWebClientBuilder
.webAppContextSetup(context)
.build();
}
25/08/2016 12:10
495 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
WebClient webClient;
@Before
public void setup() {
webClient = MockMvcWebClientBuilder
// demonstrates applying a MockMvcConfigurer (Spring Security)
.webAppContextSetup(context, springSecurity())
// for illustration only - defaults to ""
.contextPath("")
// By default MockMvc is used for localhost only;
// the following will use MockMvc for example.com and example.org as w
.useMockMvcForHosts("example.com","example.org")
.build();
}
As an alternative, we can perform the exact same setup by configuring the MockMvc
instance separately and supplying it to the MockMvcWebClientBuilder as follows.
MockMvc mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
webClient = MockMvcWebClientBuilder
.mockMvcSetup(mockMvc)
// for illustration only - defaults to ""
.contextPath("")
// By default MockMvc is used for localhost only;
// the following will use MockMvc for example.com and example.org as w
.useMockMvcForHosts("example.com","example.org")
.build();
This is more verbose, but by building the WebClient with a MockMvc instance we have
the full power of MockMvc at our fingertips.
25/08/2016 12:10
496 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Suppose we need to ensure that a message is created properly. The tests involve finding
the HTML form input elements, filling them out, and making various assertions.
This approach results in numerous, separate tests because we want to test error
conditions as well. For example, we want to ensure that we get an error if we fill out only
part of the form. If we fill out the entire form, the newly created message should be
displayed afterwards.
If one of the fields were named "summary", then we might have something like the
following repeated in multiple places within our tests.
HtmlTextInput summaryInput = currentPage.getHtmlElementById("summary");
summaryInput.setValueAttribute(summary);
So what happens if we change the id to "smmry"? Doing so would force us to update all
of our tests to incorporate this change! Of course, this violates the DRY Principle; so we
should ideally extract this code into its own method as follows.
public HtmlPage createMessage(HtmlPage currentPage, String summary, String text) {
setSummary(currentPage, summary);
// ...
}
public void setSummary(HtmlPage currentPage, String summary) {
HtmlTextInput summaryInput = currentPage.getHtmlElementById("summary"
summaryInput.setValueAttribute(summary);
}
This ensures that we do not have to update all of our tests if we change the UI.
We might even take this a step further and place this logic within an Object that
represents the HtmlPage we are currently on.
public class CreateMessagePage {
25/08/2016 12:10
497 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Formerly, this pattern is known as the Page Object Pattern. While we can certainly do this
with HtmlUnit, WebDriver provides some tools that we will explore in the following
sections to make this pattern much easier to implement.
25/08/2016 12:10
498 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
WebDriver driver;
@Before
public void setup() {
driver = MockMvcHtmlUnitDriverBuilder
.webAppContextSetup(context)
.build();
}
This will ensure that any URL referencing localhost as the server will be directed to
our MockMvc instance without the need for a real HTTP connection. Any other URL will
be requested using a network connection as normal. This allows us to easily test the use
of CDNs.
We can then fill out the form and submit it to create a message.
ViewMessagePage viewMessagePage =
page.createMessage(ViewMessagePage.class, expectedSummary, expectedText);
This improves on the design of our HtmlUnit test by leveraging the Page Object Pattern.
As we mentioned in the section called Why WebDriver and MockMvc?, we can use the
Page Object Pattern with HtmlUnit, but it is much easier with WebDriver. Lets take a look
at our new CreateMessagePage implementation.
public class CreateMessagePage
extends AbstractPage {
25/08/2016 12:10
499 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@FindBy(css = "input[type=submit]")
private WebElement submit;
public CreateMessagePage(WebDriver driver) {
super(driver);
}
The first thing you will notice is that CreateMessagePage extends the
AbstractPage . We wont go over the details of AbstractPage , but in summary it
contains common functionality for all of our pages. For example, if our application
has a navigational bar, global error messages, etc., this logic can be placed in a
shared location.
The next thing you will notice is that we have a member variable for each of the
parts of the HTML page that we are interested in. These are of type WebElement .
WebDriver 's PageFactory allows us to remove a lot of code from the HtmlUnit
version of CreateMessagePage by automatically resolving each WebElement . The
PageFactory#initElements(WebDriver,Class<T>) method will automatically resolve
each WebElement by using the field name and looking it up by the id or name of
the element within the HTML page.
We can use the @FindBy annotation to override the default lookup behavior. Our
example demonstrates how to use the @FindBy annotation to look up our submit
button using a css selector, input[type=submit].
Finally, we can verify that a new message was created successfully. The following
assertions use the FEST assertion library.
assertThat(viewMessagePage.getMessage()).isEqualTo(expectedMessage);
assertThat(viewMessagePage.getSuccess()).isEqualTo("Successfully created a new message
25/08/2016 12:10
500 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Advanced MockMvcHtmlUnitDriverBuilder
In the examples so far, we have used MockMvcHtmlUnitDriverBuilder in the simplest
way possible, by building a WebDriver based on the WebApplicationContext loaded
for us by the Spring TestContext Framework. This approach is repeated here.
@Autowired
WebApplicationContext context;
WebDriver driver;
@Before
public void setup() {
driver = MockMvcHtmlUnitDriverBuilder
.webAppContextSetup(context)
.build();
}
25/08/2016 12:10
501 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
@Before
public void setup() {
driver = MockMvcHtmlUnitDriverBuilder
// demonstrates applying a MockMvcConfigurer (Spring Security)
.webAppContextSetup(context, springSecurity())
// for illustration only - defaults to ""
.contextPath("")
// By default MockMvc is used for localhost only;
// the following will use MockMvc for example.com and example.org as w
.useMockMvcForHosts("example.com","example.org")
.build();
}
As an alternative, we can perform the exact same setup by configuring the MockMvc
instance separately and supplying it to the MockMvcHtmlUnitDriverBuilder as follows.
MockMvc mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
driver = MockMvcHtmlUnitDriverBuilder
.mockMvcSetup(mockMvc)
// for illustration only - defaults to ""
.contextPath("")
// By default MockMvc is used for localhost only;
// the following will use MockMvc for example.com and example.org as w
.useMockMvcForHosts("example.com","example.org")
.build();
This is more verbose, but by building the WebDriver with a MockMvc instance we have
the full power of MockMvc at our fingertips.
25/08/2016 12:10
502 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Geb is backed by WebDriver, so it offers many of the same benefits that we get from
WebDriver. However, Geb makes things even easier by taking care of some of the
boilerplate code for us.
This will ensure that any URL referencing localhost as the server will be directed to
our MockMvc instance without the need for a real HTTP connection. Any other URL will
be requested using a network connection as normal. This allows us to easily test the use
of CDNs.
We can then fill out the form and submit it to create a message.
when:
form.summary = expectedSummary
form.text = expectedMessage
submit.click(ViewMessagePage)
Any unrecognized method calls or property accesses/references that are not found will be
forwarded to the current page object. This removes a lot of the boilerplate code we
25/08/2016 12:10
503 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
As with direct WebDriver usage, this improves on the design of our HtmlUnit test by
leveraging the Page Object Pattern. As mentioned previously, we can use the Page
Object Pattern with HtmlUnit and WebDriver, but it is even easier with Geb. Lets take a
look at our new Groovy-based CreateMessagePage implementation.
class CreateMessagePage extends Page {
static url = 'messages/form'
static at = { assert title == 'Messages : Create'; true }
static content = {
submit { $('input[type=submit]') }
form { $('form') }
errors(required:false) { $('label.error, .alert-error')?.text() }
}
}
The first thing you will notice is that our CreateMessagePage extends Page . We wont
go over the details of Page , but in summary it contains common functionality for all of our
pages. The next thing you will notice is that we define a URL in which this page can be
found. This allows us to navigate to the page as follows.
to CreateMessagePage
We also have an at closure that determines if we are at the specified page. It should
return true if we are on the correct page. This is why we can assert that we are on the
correct page as follows.
then:
at CreateMessagePage
errors.contains('This field is required.')
Next we create a content closure that specifies all the areas of interest within the page.
We can use a jQuery-ish Navigator API to select the content we are interested in.
Finally, we can verify that a new message was created successfully.
then:
at ViewMessagePage
success == 'Successfully created a new message'
id
date
25/08/2016 12:10
504 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
summary == expectedSummary
message == expectedMessage
For further details on how to get the most out of Geb, consult The Book of Geb users
manual.
In the above example, MockRestServiceServer , the central class for client-side REST
tests, configures the RestTemplate with a custom ClientHttpRequestFactory that
asserts actual requests against expectations and returns "stub" responses. In this case
we expect a request to "/greeting" and want to return a 200 response with "text/plain"
content. We could define as additional expected requests and stub responses as needed.
When expected requests and stub responses are defined, the RestTemplate can be
used in client-side code as usual. At the end of testing mockServer.verify() can be
used to verify that all expectations have been satisfied.
By default requests are expected in the order in which expectations were declared. You
can set the ignoreExpectOrder option when building the server in which case all
expectations are checked (in order) to find a match for a given request. That means
requests are allowed to come in any order. Here is an example:
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
Even with unordered requests by default each request is allowed to execute once only.
The expect method provides an overloaded variant that accepts an ExpectedCount
argument that specifies a count range, e.g. once , manyTimes , max , min , between ,
and so on. Here is an example:
25/08/2016 12:10
505 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Note that when ignoreExpectOrder is not set (the default), and therefore requests are
expected in order of declaration, then that order only applies to the first of any expected
request. For example if "/foo" is expected 2 times followed by "/bar" 3 times, then there
should be a request to "/foo" before there is a request to "/bar" but aside from that
subsequent "/foo" and "/bar" requests can come at any time.
As an alternative to all of the above the client-side test support also provides a
ClientHttpRequestFactory implementation that can be configured into a
RestTemplate to bind it to a MockMvc instance. That allows processing requests using
actual server-side logic but without running a server. Here is an example:
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc));
// Test code that uses the above RestTemplate ...
mockServer.verify();
Static Imports
Just like with server-side tests, the fluent API for client-side tests requires a few static
imports. Those are easy to find by searching "MockRest*". Eclipse users should add
"MockRestRequestMatchers.*" and "MockRestResponseCreators.*" as "favorite
static members" in the Eclipse preferences under Java Editor Content Assist
Favorites. That allows using content assist after typing the first character of the static
method name. Other IDEs (e.g. IntelliJ) may not require any additional configuration. Just
check the support for code completion on static members.
506 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
The PetClinic application, available on GitHub, illustrates several features of the Spring
TestContext Framework in a JUnit 4 environment. Most test functionality is included in the
AbstractClinicTests , for which a partial listing is shown below:
import static org.junit.Assert.assertEquals;
// import ...
@ContextConfiguration
public abstract class AbstractClinicTests extends AbstractTransactionalJUnit4SpringCon
@Autowired
protected Clinic clinic;
@Test
public void getVets() {
Collection<Vet> vets = this.clinic.getVets();
assertEquals("JDBC query must show the same number of vets",
super.countRowsInTable("VETS"), vets.size());
Vet v1 = EntityUtils.getById(vets, Vet.class, 2);
assertEquals("Leary", v1.getLastName());
assertEquals(1, v1.getNrOfSpecialties());
assertEquals("radiology", (v1.getSpecialties().get(0)).getName());
// ...
}
// ...
}
Notes:
This test case extends the AbstractTransactionalJUnit4SpringContextTests
class, from which it inherits configuration for Dependency Injection (through the
DependencyInjectionTestExecutionListener ) and transactional behavior
(through the TransactionalTestExecutionListener ).
The clinic instance variablethe application object being testedis set by
Dependency Injection through @Autowired semantics.
The getVets() method illustrates how you can use the inherited
countRowsInTable() method to easily verify the number of rows in a given table,
thus verifying correct behavior of the application code being tested. This allows for
stronger tests and lessens dependency on the exact test data. For example, you can
add additional rows in the database without breaking tests.
Like many integration tests that use a database, most of the tests in
AbstractClinicTests depend on a minimum amount of data already in the
database before the test cases run. Alternatively, you might choose to populate the
25/08/2016 12:10
507 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
database within the test fixture set up of your test casesagain, within the same
transaction as the tests.
The PetClinic application supports three data access technologies: JDBC, Hibernate, and
JPA. By declaring @ContextConfiguration without any specific resource locations, the
AbstractClinicTests class will have its application context loaded from the default
location, AbstractClinicTests-context.xml , which declares a common
DataSource . Subclasses specify additional context locations that must declare a
PlatformTransactionManager and a concrete implementation of Clinic .
For example, the Hibernate implementation of the PetClinic tests contains the following
implementation. For this example, HibernateClinicTests does not contain a single
line of code: we only need to declare @ContextConfiguration , and the tests are
inherited from AbstractClinicTests . Because @ContextConfiguration is declared
without any specific resource locations, the Spring TestContext Framework loads an
application context from all the beans defined in AbstractClinicTests-context.xml
(i.e., the inherited locations) and HibernateClinicTests-context.xml , with
HibernateClinicTests-context.xml possibly overriding beans defined in
AbstractClinicTests-context.xml .
@ContextConfiguration
public class HibernateClinicTests extends AbstractClinicTests { }
In a large-scale application, the Spring configuration is often split across multiple files.
Consequently, configuration locations are typically specified in a common base class for
all application-specific integration tests. Such a base class may also add useful instance
variablespopulated by Dependency Injection, naturallysuch as a SessionFactory
in the case of an application using Hibernate.
As far as possible, you should have exactly the same Spring configuration files in your
integration tests as in the deployed environment. One likely point of difference concerns
database connection pooling and transaction infrastructure. If you are deploying to a
full-blown application server, you will probably use its connection pool (available through
JNDI) and JTA implementation. Thus in production you will use a
JndiObjectFactoryBean or <jee:jndi-lookup> for the DataSource and
JtaTransactionManager . JNDI and JTA will not be available in out-of-container
integration tests, so you should use a combination like the Commons DBCP
BasicDataSource and DataSourceTransactionManager or
HibernateTransactionManager for them. You can factor out this variant behavior into
a single XML file, having the choice between application server and a 'local' configuration
separated from all other configuration, which will not vary between the test and production
25/08/2016 12:10
508 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
509 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
510 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Transaction bound event describes how you could use application events within a
transaction.
25/08/2016 12:10
511 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
512 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
513 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
514 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
that discuss transaction isolation levels and other core transaction concepts.
Understanding these concepts is essential to using the Spring Framework or any
transaction management solution.
The TransactionStatus interface provides a simple way for transactional code to
control transaction execution and query transaction status. The concepts should be
familiar, as they are common to all transaction APIs:
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
void flush();
boolean isCompleted();
}
25/08/2016 12:10
515 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you use JTA in a Java EE container then you use a container DataSource , obtained
through JNDI, in conjunction with Springs JtaTransactionManager . This is what the
JTA and JNDI lookup version would look like:
<?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:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd">
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/>
The JtaTransactionManager does not need to know about the DataSource , or any
other specific resources, because it uses the containers global transaction management
infrastructure.
You can also use Hibernate local transactions easily, as shown in the following examples.
In this case, you need to define a Hibernate LocalSessionFactoryBean , which your
application code will use to obtain Hibernate Session instances.
The DataSource bean definition will be similar to the local JDBC example shown
previously and thus is not shown in the following example.
25/08/2016 12:10
516 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
If you are using Hibernate and Java EE container-managed JTA transactions, then you
should simply use the same JtaTransactionManager as in the previous JTA example
for JDBC.
If you use JTA , then your transaction manager definition will look the same
regardless of what data access technology you use, be it JDBC, Hibernate
JPA or any other supported technology. This is due to the fact that JTA
transactions are global transactions, which can enlist any transactional
resource.
In all these cases, application code does not need to change. You can change how
25/08/2016 12:10
517 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
transactions are managed merely by changing configuration, even if that change means
moving from local to global transactions or vice versa.
25/08/2016 12:10
518 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
17.4.3 TransactionAwareDataSourceProxy
At the very lowest level exists the TransactionAwareDataSourceProxy class. This is a
proxy for a target DataSource , which wraps the target DataSource to add awareness
of Spring-managed transactions. In this respect, it is similar to a transactional JNDI
DataSource as provided by a Java EE server.
It should almost never be necessary or desirable to use this class, except when existing
code must be called and passed a standard JDBC DataSource interface
implementation. In that case, it is possible that this code is usable, but participating in
Spring managed transactions. It is preferable to write your new code by using the higher
level abstractions mentioned above.
25/08/2016 12:10
519 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
Where is TransactionProxyFactoryBean?
Declarative transaction configuration in versions of Spring 2.0 and above differs
considerably from previous versions of Spring. The main difference is that there is
no longer any need to configure TransactionProxyFactoryBean beans.
The pre-Spring 2.0 configuration style is still 100% valid configuration; think of the
new <tx:tags/> as simply defining TransactionProxyFactoryBean beans on
your behalf.
The concept of rollback rules is important: they enable you to specify which exceptions
25/08/2016 12:10
520 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
(and throwables) should cause automatic rollback. You specify this declaratively, in
configuration, not in Java code. So, although you can still call setRollbackOnly() on
the TransactionStatus object to roll back the current transaction back, most often you
can specify a rule that MyApplicationException must always result in rollback. The
significant advantage to this option is that business objects do not depend on the
transaction infrastructure. For example, they typically do not need to import Spring
transaction APIs or other Spring APIs.
Although EJB container default behavior automatically rolls back the transaction on a
system exception (usually a runtime exception), EJB CMT does not roll back the
transaction automatically on anapplication exception (that is, a checked exception other
than java.rmi.RemoteException ). While the Spring default behavior for declarative
transaction management follows EJB convention (roll back is automatic only on
unchecked exceptions), it is often useful to customize this behavior.
25/08/2016 12:10
521 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
25/08/2016 12:10
522 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...
package x.y.service;
public class DefaultFooService implements FooService {
public Foo getFoo(String fooName) {
throw new UnsupportedOperationException();
}
public Foo getFoo(String fooName, String barName) {
throw new UnsupportedOperationException();
}
public void insertFoo(Foo foo) {
throw new UnsupportedOperationException();
}
public void updateFoo(Foo foo) {
throw new UnsupportedOperationException();
}
}
Assume that the first two methods of the FooService interface, getFoo(String) and
getFoo(String, String) , must execute in the context of a transaction with read-only
semantics, and that the other methods, insertFoo(Foo) and updateFoo(Foo) , must
execute in the context of a transaction with read-write semantics. The following
configuration is explained in detail in the next few paragraphs.
<!-- from the file 'context.xml' -->
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- this is the service object that we want to make transactional -->
<bean id="fooService" class="x.y.service.DefaultFooService"/>
<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below)
25/08/2016 12:10
523 de 1194
http://docs.spring.io/spring/docs/current/spring-framework-reference/h...