metagear.de
A Comprehensive Introduction into the Spring Framework (with Sample Application)
July 9, 2009 · Robert Söding

Preface

Primarily, this article has been written in order to qualify for the SpringSource Certified Spring Professional exam. It might cover a decent number of themes being on the curriculum, however, certainly not all.
This article comes with a sample application that should be easy to set up for other developers. This application is not meant to illustrate any aspects introduced in the article, but covers what the author thought to be common use cases in a - not so - real-world application.
As this is the author's first Java Enterprise application, and his first IT-related article, too, likely there are major flaws, i.e., regarding best practices or technical understandings. Furthermore, the author's mother tongue is not English.
Reading the article and studying the sample application is recommend for software developers that don't want to read the - even more comprehensive - Spring Reference (although the latter certainly provides much more accuracy), want to refresh their knowledge on Spring, look at it from an additional perspective, or have working working samples that partially extend what's covered by Spring's own sample applications.
Readers are supposed to have a basic knowledge of the Java language, Database access, and Servlet / JSP technologies.
This article deals with version 2.5 of the Spring framework. The upcoming 3.0 version will add new features, but, basically, not revoke existing ones. Thus, the article will remain valid to a large degree.
Feedback is welcome and can be directed to .

The Spring Framework

The Spring Framework is an open source framework for the Java platform (there is a port for Microsoft .NET, too, as well as some other platforms). It facilitates software development for Java, and Java EE, and advocates best practices in software development. It has been introduced in October 2002 and, since then, evolved constantly.
Basic principles of the Spring framework include:
Based on the Spring Framework, a number of subprojects exist, including Spring Security, Spring RichClient, and Spring WebFlow (as well as quite a few others).
To run Spring applications, an application server is not necessary. Java applications of any type can host a Spring container.
Spring modules can be used independently from another, i.e., Spring's JDBC-related APIs can be used without programming the AOP way.
The Spring framework is comprehensively and sensibly documented. While there is qualified community support, commercial support is available, too. Spring's architecture appears to be thoroughly planned, recent versions of the Spring framework have been backwards compatible to a very large degree.
Finally, not meant a subjective attitude: It is a framework developers will want to work with.

The Sample Application

Requirements

Project Nature, IDE, and Maven

The project has been developped using the Springsource Tool Suite (STS) 2.1 (which is based on Eclipse 3.5). As the project is managed by Apache Maven, it can be imported into various IDEs (Integrated Development Environment), including Eclipse and Netbeans.
STS contains tools to manage Spring beans, as well as the m2eclipse Maven plugin, which is highly recommended.
In Eclipse for instance, - the m2eclipse plugin being installed - the project can be imported via File —> Import —> Maven Projects.
Maven-related tasks like testing and packaging can be conducted using the aforementioned Eclipse Maven plugin or, alternatively, by using Maven from the command line.
On Debian-based Linux distributions, Maven can be installed by running ...
apt-get install maven2
... as root.
For other operating systems, please consult the installation instructions at the Maven web site.
The project has been set up for Java 1.6 compatibility. Likely, that could be changed to Java 1.5.

Application Server

The sample application has been successfully tested on the following application servers (which could also be referred to as web containers in this case):
On other application servers, including Apache Geronimo, IBM WebSphere Community Edition, JBoss AS GA, and Sun Glassfish, deployment fails - mostly due to errors related to ActiveMQ's and OpenEJB default configuration.
In order to use OpenEJB on Tomcat (as well as the Tomcat-based Springsource tc Server), $M2_REPO/repository/org/apache/openejb/javaee-api/5.0-2/javaee-api-5.0-2.jar needs to be copied to $TOMCAT_HOME/lib. Theoretically, this should not be necessary, however, it was in the author's testing.

Database

The sample application has been successfully tested with the following DBMs':
Edit jdbc.properties to choose your database implementation, and edit user name and password.
Additional, non-Hibernate-based, DDL indexes, checks and constraints (see chapter Additional DDL Commands) have been implemented for PostgreSQL, only.
It is therefor recommended to use PostgreSQL as database backend.
The Oracle JDBC driver (ojdbc14.jar) is not included in the Maven pom.xml file (as, at the time of writing, it was incomplete in the Maven repository). Please download it from Oracle if planning to use the sample application with an Oracle database.
Hibernate's property hibernate.hbm2ddl.auto by default is set up to create-drop the database tables on application startup and shutdown. On other DBMSs than HSQLDB, this does not affect the creation of the database itself.
In this case, create a database named "article" before running the application.

Running the Sample Application

When running in an application server, the web application is accessible under the context URL "/springarticle" (i.e., http://localhost:8080/springarticle. The first page is a login form. Any user name / password combination from the src/main/resources/logins.properties file can be used.

User Roles and Use Cases

In general, the application consists of a number of layers:

User Roles

The following user roles exist (BTW, these are Java types in the com.acme.sample.domain package):
User Types
A User has a name and a password, by which she can login to the application. Additionally, she has been assigned one or more authorities (which could be also named roles) that are used by the application to determine which parts of the web GUI she may view, and which Java classes and methods she is allowed to call. See chapter Spring Security for further information.
To each User that does not have the authority Administrator, a BusinessUser should be assigned (- really). BusinessUsers may have associated Orders, Vendors associated Products, additionally. See chapter Domain Model for a complete diagram.

Use Cases

Use cases are based on a User's role, which can be ROLE_ADMINISTRATOR, ROLE_CUSTOMER or ROLE_VENDOR.

All Users

Administrators

Customers

The following diagram illustrates the "Place Order" use case:
'Place Order' Use Case
See chapter Notify Vendor on Order Placement for more information on this use case.

Vendors

The Spring Container

Generally spoken, the Spring container manages beans.
Beans, in the Spring context, are POJOs (Plain Old Java Objects), classes of virtually any type and shape, that are managed by the Spring container. I.e., they do not have to implement special interfaces, or throw special exceptions.
Managing beans to the container means, controlling beans' lifecycles and configuring them, particularly, by assigning (plain old, in a way) dependencies and (Spring AOP) intercepting functionality.
Beans can be configured via XML schema-based configuration files or inline Java 5 annotations (any other format would be possible, however, these are commonly used).

BeanFactory and ApplicationContext

The root interface for accessing a Spring container is a BeanFactory, which contains the (overloaded) Object getBean(..) method.
The ApplicationContext interface (indirectly) extends BeanFactory, plus other interfaces, which functionality it thus provides, including:
There may be several ApplicationContexts per classloader, i.e., in a web application, one for the complete application, and others for single servlets. Application contexts may inherit from parent contexts, servlets' contexts do inherit from the 'global' context.

Container Instantiation

Other than, i.e., Java EE, a Spring container is not tied to a parent container. It can be run in a web or JEE application, Java applet, Swing application, or testing application. ApplicationContext implementations can be instantiated directly, or indirectly (i.e., in a web application or JUnit test).
Spring provides a number of ApplicationContext implementations (in the org.apache.xbean.spring.context package), including the commonly used ClassPathXmlApplicationContext.

Manual Instantiation

Instantiating a ClassPathXmlApplicationContext manually is straightforward:
ApplicationContext context = new ClassPathXmlApplicationContext(
        new String[] {"services.xml", "daos.xml"});
MyBean myBean = (MyBean) context.getBean("myBean");
To the constructor, one or more XML beans configuration files are passed. In the code snippet above, the files are relative to the current directory. Alternatively, the prefix classpath: causes them to be searched on the classpath, and classpath*: also considers linked JARs.

Implicit Instantiation within the Spring TestContext Framework

Test classes within the Spring TestContext framework may specify XML configuration files by setting the @ContextConfiguration annotation:
@ContextConfiguration(locations = {
        "classpath:applicationContext-remoting.xml",
        "classpath:applicationContext-web.xml"})
public abstract class AbstractTests extends AbstractJUnit4SpringContextTests {}
For further information see chapter Testing.

Implicit Instantiation within a Web Application

This section refers to Servlet 2.4 containers or newer. In legacy containers, a slightly modified configuration is needed.
In Spring MVC, an ApplicationContext - by default, an ClassPathXmlApplicationContext - is implicitly set up by configuring a ContextLoaderListener and/or one or more DispatcherServlets.
ContextLoaderListener
The ContextLoaderListener is meant to manage Spring beans that belong to the middle tier and data access layers. It is configured as follows (in web.xml):
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
                classpath:applicationContext-middleTier.xml
                classpath:applicationContext-dataAccess.xml
        </param-value>
</context-param>
DispatcherServlet
Next, one or more DispatcherServlets can be set up. Typically, they will have their own ApplicationContext, each, however, that context inherits from the ContextLoaderListener's context (where inherited bean definitions can be overridden), so the 'global' bean definitions can be used there.
A DispatcherServlet is configured as follows (in web.xml):
<servlet>
        <servlet-name>springDispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>
                        classpath:applicationContext-client-frontend.xml
                </param-value>
        </init-param>

        <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
        <servlet-name>springDispatcher</servlet-name>
        <url-pattern>/app/*</url-pattern>
</servlet-mapping>
The contextConfigLocation property is optional. By default, the servlet would load a bean configuration file named <servlet-name>-servlet.xml (in this sample, springDispatcher-servlet.xml) in the web application's WEB-INF folder.
This configuration file may contain bean definitions of Controllers, ViewResolvers, LocaleResolvers, handler mappings, etc. (many of which discussed in chapter Spring MVC), but should not - in terms of separation of concerns - contain definitions of beans from the middle tier or data access layer (as mentioned, the latter ones will be accessible, though).
WebApplicationContext
The default application context is a XmlWebApplicationContext, which supports theming (Theme getTheme(String) method) and is aware of the ServletContext it is running in (ServletContext getServletContext() method).

Dependency Injection

Objects in the Java programming world are instances of types (classes). Objects may be dependant on other objects to be functional, i.e., a car should have four tires (has-a relationship). The most straightforward way to construct these dependencies is to use the new statement:
class Car {
        Tire[] tires = new Tire[4];

        Car() {
                tires[0] = new SnowTire();
                tires[1] = new SnowTire();
                tires[2] = new SnowTire();
                tires[3] = new SnowTire();
        }
}
However, this leads to tight coupling: Whenever the type of the Tire is to be changed (i.e., spring comes, normal tires are to be tested, snow tires are sold out), the Car's code needs to be changed, and recompiled. This is impractical.
There are a number of design patterns to work around tight coupling, including the Factory Pattern, the Service Locator Pattern, and, to some extend, the Decorator Pattern, loosening the coupling. One can, however, argue that wherever there is still a new statement in code, coupling is still too tight.
Dependency Injection (DI), a form of Inversion of Control (IoC), comes to the rescue: The container - that runs the application - injects the dependencies (from outside), based on the application's (declarative) configuration.
In Spring, basically, two forms of dependency injection declaration exist, using Java 5 annotations or external XML configuration markup (see chapter Bean Configuration).

Injection Types

The configuration code samples in this chapter are built on XML schema-based configuration. As for annotation-based configuration, see chapter Configuration Related to Dependency Injection.

Constructor Arguments Injection

In the following code snippet there is a constructor requiring two arguments to be passed:
class Car {
        Tire[] tires;
        CigaretteLighter lighter;

        Car(Tire[] tires, CigaretteLighter lighter) {
                this.tires = tires;
                this.lighter = lighter;
        }
}
In XML schema-based configuration, injection could be set up as follows:
<bean id="tire" class="example.SnowTire" />

<util:set id="tires">
        <idref local="tire" />
        <idref local="tire" />
        <idref local="tire" />
        <idref local="tire" />
</util:set>

<bean id="lighter" class="example.CigaretteLighter" />

<bean id="car" class="example.Car">
        <constructor-arg ref="tires" />
        <constructor-arg ref="lighter" />
</bean>
Most details in the above code snippet are not relevant for this subsection. There is more information in the chapters XML Schema-Based Configuration and The util Schema. The util:set declaration will cause Spring to create a java.util.HashSet instance, which will be auto-converted to the Tire[] array.
The object instances passed via the constructor-arg XML elements will be assigned by their Java type, automatically. Alternatively, the type can be explicitly set:
<constructor-arg type="int" value="42" />
<constructor-arg type="java.lang.String" value="777" />
Additionally, a (0-based) argument index can be set:
<constructor-arg index="0" value="42" />
<constructor-arg index="1" value="777" />

Instance Field Injection

Instance field injection cannot be declared using XML schema-based configuration. In contrast, specific annotations do work for that purpose (see chapter Configuration Related to Dependency Injection).

Setter Injection

Considering the following Java class, ...
public class Car {
        CigaretteLighter lighter;

        public void setCigaretteLighter(CigaretteLighter lighter) {
                this.lighter = lighter;
        }
}
... a corresponding XML bean configuration could be:
<bean class="example.Car">
        <property name="cigaretteLighter">
                <bean class="example.CigaretteLighter" />
        </property>
</bean>
In the above sample, an anonymous inner bean is created. Alternatively, there could be a reference to a bean declared elsewhere.

Method Arguments Injection

Specific annotations can be used to declare dependencies to be injected on methods not being setter methods, but having an arbitrary method name as well as possibly multiple arguments (see chapter Configuration Related to Dependency Injection). Method arguments injection cannot be declared using XML schema-based configuration.

Autowiring

Autowiring means that the Spring container will try to locate exactly one matching bean to dependency-inject into applicable properties (setter methods), each, or a constructor.
In XML schema-based configuration, there is the autowire attribute, i.e.:
<bean class="example.Car" autowire="byType" />
It can take the following values: In the byName and byType modes, no exception will be thrown if no matching bean is found. This can be changed by setting dependency-check="objects".
There is a corresponding default-autowire attribute on the bean's beans parent element.
The bean's attribute autowire-candidate (with its possible values default|true|false) specifies whether or not a bean may be considered when looking for matches. By default, it may. This setting only applies to autowiring by type, and not by name.
At the beans parent level, the default-autowire-candidates attribute can be used to set one or more bean name patterns for identifying autowire candidates. The patterns may contain wildcards (*), multiple patterns are delimited by commas (,).
For information on declaring autowiring behavior through annotations see chapter Configuration Related to Dependency Injection.

Bean Scopes

Spring beans are singleton scoped by default. Singleton beans' lifecycles start when being initialized (by default, at container startup time) and end when the container prepares to shutdown. Each call to BeanFactory.getBean(..) and each dependency-injected bean refers to the same instance of a singleton scoped bean.
Singleton beans are not meant to hold application state beyond their initial configuration (particularly, dependencies).
Alternatively, a bean's scope can be set to prototype. In this case a new instance will be created with every BeanFactory.getBean(..) call or dependency injection.
In WebApplication contexts the request and session scopes exist, such a bean instance will be created for each HTTP request or session.
There is also the globalSession scope. A globalSession scoped bean instance is shared amongst each portlet within a HTTP session. If the web application is not a portlet application, the scope will implicitly fallback to the session scope.
It is possible to create a custom scope by implementing the Scope interface and registering the bean with
ConfigurableBeanFactory.registerScope(String, Scope).
In XML schema-based configuration, scope is an attribute of the bean element. As an annotation, @Scope can be used.

Bean Configuration

Spring Beans typically are either configured by Java 5 annotations, or by XML schema-based configuration (typically, configuration files).

XML Schema-Based Configuration

The XML schemas, on which configuration is based, are documented inline, and can be read while editing a configuration file in commonly used IDEs, including Eclipse and Spring Tools Suite.

The beans Schema

An empty configuration file starts with the beans element and typically includes bean elements:
<?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: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 class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"
                p:order="0" 
                p:interceptors-ref="localeChangeInterceptor">

                <property name="mappings">
                        <value>
                                /adminAddCustomer.htm=adminAddCustomerController
                        </value>
                </property>
        </bean>

        <bean id="localeChangeInterceptor" class="..." ... />
</beans>
Bean Properties
As with the property attribute in the above snippet, a bean may have properties set. The property "mappings" would refer to the bean class' setMappings(..) setter method.
An analogous shortcut to <bean><property name="mappings"> ... would be <bean p:mappings="...". This requires the p namespace to be specified (see xmlns:p in the above snippet).
p:interceptors-ref in the above snippet refers to another Spring bean.
The "mappings" property in this case is of the Java type java.util.Properties. Spring will convert the value by using a matching PropertyEditor, based on the type of the target property.
In case of the Java type Properties, the XML element value ist used (which takes a list of values, separated by whitespace). XML elements that map to other Java types include list, map, props (similar to map), and set.
In the following snippet, not a property, but a constructor argument, is set to a map:
<bean id="supportedLocales" class="java.util.HashMap">
        <constructor-arg>
                <map>
                        <entry key="en" value="general.languages.english" />
                        <entry key="de" value="general.languages.german" />
        </constructor-arg>
</bean>
Other possible property XML child elements include bean (for creating an anonymous inner bean, like an anonymous inner class in Java), ref (referencing a bean defined elsewhere) and idref (similar to ref, but an XML parser will validate the existence of the referenced bean within the same file).
bean Attributes
This subsection refers to the XML attributes an XML bean element can take.
None of the possible bean attributes is mandantory.
Firstly, there is the class attribute, which takes the fully qualified class name. With the parent attribute, a "superclass" bean can be specified, from which the bean then will inherit most settings. The parent bean could be abstract="true" in order to not be instantiated, directly.
By a bean's id, other beans can reference it. The name attribute can be used to add one or more aliases.
As Spring manages the lifecycle of the bean, it can call an init-method or destroy-method. Optionally, the bean can be instantiated by using the given factory-method of a given factory-class (see chapter Factory Pattern).
Autowiring can be configured by the autowired, autowire-candidate, and primary attributes.
The depends-on attribute is used when the currently configured bean needs another bean to be fully configured before it will be configured itself.
By default, Spring loads all beans on startup. This can be changed by setting the lazy-init attribute.
By setting the scope attribute, another scope than the default scope singleton can be set (see chapter Bean Scopes).

The aop Schema

To use the aop namespace, its declaration needs to be associated with the corresponding XML schema:
<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/aop 
                http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
The aop:config, aop:pointcut, aop:aspect, and aop:advisor can be used to create and advise AOP aspects.
See chapter Declarative Transaction Management for an example. For further information on AOP, see chapter Spring AOP.

The context Schema

To use the context namespace, its declaration needs to be associated with the corresponding XML schema:
<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">
</beans>
The context:property-placeholder element configures a Spring PropertyPlaceholderConfigurer, which replaces properties in the shape ${...} by their actual values. See chapter DataSource Setup for an example.
Multiple PropertyPlaceholderConfigurers (allowing for using multiple .properties files) within an ApplicationContext will conflict by default. This can be resolved by setting a different placeholderPrefix property for each instance. The default placeholderPrefix is "${", and could, for instance, be changed to "$jdbcStuff{".
The context:annotation-config element causes Spring detect various annotations, including Spring's @Required and @Autowired, JSR 250's @PostConstruct, @PreDestroy and @Resource (if available), and JPA's @PersistenceContext and @PersistenceUnit (if available).
Detection of Spring's @Transactional annotation, in contrast, is activated by the tx:annotation-config element.
The context:component-scan element makes Spring scan the classpath for annotated components that will be auto-registered as Spring beans. By default, the Spring-provided @Component, @Repository, @Service, and @Controller stereotypes will be detected. By default, context:component-scan implicitly activates tx:annotation-config.
The context:component-scan element's base-package attribute allows for limiting the scan to the given package contents. The sub-elements context:exclude-filter and context:include-filter allow for further filtering.
Additional possible elements are omitted in this subsection.

The util Schema

To use the util namespace, its declaration needs to be associated with the corresponding XML schema:
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd">
</beans>
The util schema contains convenience utility shortcuts for defining collection beans, setting constant values, etc.
In example, the following code snippet ...
<bean id="supportedLocales" class="java.util.HashMap">
        <constructor-arg>
                <map>
                        <entry key="en" value="general.languages.english"></entry>
                        <entry key="de" value="general.languages.german"></entry>
                </map>
        </constructor-arg>
</bean>
... can also be expressed as:
<util:map id="supportedLocales">
        <entry key="en" value="general.languages.english"></entry>
        <entry key="de" value="general.languages.german"></entry>
</util:map>
There are corresponding util:list, util:set and util:properties elements.

The tx Schema

To use the tx namespace, its declaration needs to be associated with the corresponding XML schema:
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        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">
</beans>
The existence of an tx:annotation-driven element instructs Spring to create transactional proxies for beans annoted with Spring's @Transactional and EJB3's @TransactionAttribute. By default, this requires a TransactionManager with an id "txManager" to be set up, this can be changed by setting the transaction-manager attribute.
Using the tx:advice element, classes containing matching methods can be advised by transactional advices (similar to annotating them).
<tx:advice id="readOnlyTransactionsAdvice"
        transaction-manager="transactionManager">
        <tx:attributes>
                <tx:method name="get*" read-only="true" />
                <tx:method name="*" />
        </tx:attributes>
</tx:advice>

<aop:config>
        <aop:pointcut id="serviceLayerGettersPointcut"
                expression="execution(* com.acme.sample.businessfacade.impl.*.*(..))" />
        <aop:advisor id="readOnlyTransactionsInServiceLayerAdvisor"
                advice-ref="readOnlyTransactionsAdvice" pointcut-ref="serviceLayerGettersPointcut" />
</aop:config>
Also see chapter Declarative Transaction Management.

Annotation-based Configuration

Configuration Related to Dependency Injection

In order to cause Spring detect the annotations mentioned below, one or more BeanPostProcessors need to be activated by using the context:component-scan element in XML schema-based configuration (see chapter The context Schema).
The @Required annotation can be set on methods - reasonably, on setter methods. If the annotated property has not been populated initially, an exception will be thrown.
The @Autowired annotation may be placed on constructors, fields, and methods (not only setter methods, but also methods of other signatures and more than one argument). It has an optional property required, which defaults to true. It also works on typed collections, like List<Jacket>, which then are populated with all matching beans.
Autowiring means that matching beans (by default, determined by type) are automatically injected. If there is more or less than exactly one autowiring candidate at initialization time, an exception will be thrown.
Autowiring by qualifier can be accomplished by adding a @Qualifier annotation, for example:
@Autowired
public void prepareForRide(Saddle saddle, @Qualifier("rainJacket") Jacket jacket) { 
        ... 
}
There should be a correspondig XML configuration (see chapter The beans Schema), i.e.:
<bean class="example.jackets.RainJacket">
        <qualifier value="rainJacket">
</bean>
Custom qualifier annotation interfaces can be easily written. Additionally, a CustomAutoWireConfigurer may be set up.
The JSR-250 @Resource annotation, which Spring detects on fields and setter methods, causes Spring to look up a named bean if the name attribute is given, otherwise, to look up a matching bean by type.
The ApplicationContext and its sub-interfaces are globally accessible within a Spring application. There is not need to create explicit bean definitions for them.

Configuration Related to Lifecycle Events

In order to cause Spring detect the annotations mentioned below, one or more BeanPostProcessors need to be activated by using the context:component-scan element in XML schema-based configuration (see chapter The context Schema).
No-arg methods (other restrictions do apply) annotated with @PostConstruct or @PreDestroy will be executed after the bean has been initially configured (i.e., dependencies have been injected) or just before the bean will get out of the container's scope.

Configuration Related to Bean Management

In order to cause Spring detect the annotations mentioned below, one or more BeanPostProcessors need to be activated by using the context:component-scan element in XML schema-based configuration (see chapter The context Schema).
As an alternative to XML Schema-Based Configuration, where beans to manage are detected after they are defined using an XML bean element, Spring can also detect beans to manage by annotations on them.
Beans being annotated by @Component at the type level will be auto-detected. Specializations of @Component include @Service (i.e., a business facade), @Repository (a Data Access Object, DAO), and @Controller (a controller - this annotation is usually used in combination with a @RequestMapping annotation, see chapter Mapping Controllers to URLs).
These specializations currently have a limited meaning, however, this may change in future Spring versions (i.e., to be used with exception translation). These annotations may also serve as pointcut targets.
The annotations mentioned above also have an optional name attribute.
By using the @Scope annotation at the type level, i.e., @Scope("prototype"), another scope than the default singleton scope can be specified (see chapter Bean Scopes).

Configuration Related to Spring AOP

Annotations related to aspect-orientated programming include @Aspect, @Pointcut, @Before, and others. See chapter Spring AOP for further information.

Configuration Related to Transactional Behavior

For the @Transactional annotation see chapter @Transactional annotation.

Configuration Related to the Spring TestContext Framework

See chapter Spring TestContext Framework for a discussion.

Spring Security

This article and its sample application focus on the Spring Core Framework rather than Spring Security, and the author has not dealed too much with the latter yet, so essential information may be missing in this chapter. Nonetheless, the sample application basically needs any form of authentication and authorization to represent workflows in which users of different roles participate.
When starting the sample application's web GUI, the user needs to login. The database has been pre-populated with three user logins. See login.properties for user name / password combinations.

Authentication (and Some Bits of Authorization)

Authentication and authorization can declaratively be applied as simple as that: First, specify a AuthenticationProvider implementation and assign a UserDetailsManager implementation to it.
The following code snippet shows a sample for an DaoAuthenticationProvider with a InMemoryDaoImpl:
<authentication-provider>
        <user-service>
                <user 
                        name="admin1" 
                        password="l33nuxRules"
                        authorities="ROLE_ADMINISTRATOR" />
                <user 
                        name="vendor1" 
                        password="l33nuxRules"
                        authorities="ROLE_VENDOR" />
        </user-service>
</authentication-provider>
Alternatively, a JdbcDaoImpl instance can be assigned to a DaoAuthenticationProvider:
<authentication-provider>
        <jdbc-user-service 
                data-source-ref="dataSource"
                authorities-by-username-query="SELECT username,authority 
                        FROM authorities WHERE username = ?"
                users-by-username-query="SELECT username,password,enabled 
                        FROM users WHERE username = ?" />
        </authentication-provider>
The database schema in this article's sample application slightly differs from Spring Security's database schema.
It could be configured as follows:
<http auto-config="true">
        <intercept-url 
                pattern="/**"
                access="ROLE_CUSTOMER,ROLE_VENDOR,ROLE_ADMINISTRATOR" />
        <intercept-url 
                pattern="/admin/**"
                access="ROLE_ADMINISTRATOR" />
        </http>
In the above code snippet, auto-config="true" "automatically registers a login form, BASIC authentication, anonymous authentication, logout services, remember-me and servlet-api-integration" (quoted from the tag attribute's inline documentation). This means, you don't even have to write a login form!
In this article's sample application a custom login form is used, though (/login.jsp). - A minimal JSP login form could be of the shape:
<c:if test="${not empty param.login_error}">
        <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
        <br />
</c:if>

<form action="j_spring_security_check">
        User name: <input type='text' name='j_username'
        value='<c:if test="${not empty param.login_error}"><c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>' />
        <br />
        
        Password: <input type='password' name='j_password' />
        
        <%-- 
                <br />
                "Remember me" is optional
                <input type="checkbox" name="_spring_security_remember_me" />
                Remember password
        --%>
        
        <input value="Login" type="submit">
</form>
The form POSTs to the "URL" j_spring_security_check, and the user name and password fields are named j_username and j_password, respectively.

Authorization

In the sample application, authorization is applied both at the JSP and Java source level.
In /WEB-INF/views/includes/navi.jsp, the Spring Security tag library is used:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<sec:authorize ifAllGranted="ROLE_ADMINISTRATOR">
        <a href="<c:url value='/app/adminListProducts.htm'/>">Products</a>
</sec:authorize>
In the Java source, the controllers as well as the business facade interfaces are secured by annotating types or methods by either @javax.annotation.security.RolesAllowed(String[]) or @org.springframework.security.annotation.Secured(String[]) (where the role names or authorities are passed as arguments) can be used.
For this to work, Spring needs to be configured to interprete these annotations:
<global-method-security jsr250-annotations="enabled"
        secured-annotations="enabled" />

Spring AOP

Aspect Orientated Programming (AOP) addresses cross-cutting concerns, which are pieces of code (or logic) that typically are not directly part of the business logic and may occur over and over again, at several places within the business logic code.
Such cross-cutting concerns can be logging, performance monitoring, tracing, transaction management, custom security checks, exception handling, caching, and others.
Similar to applying the Decorator Pattern, with AOP, additional behavior can be added to an existing class, where a proxy wraps that class and delegates calls to it. On the other hand, cross-cutting code is isolated from the application code.

AOP Terminology

An aspect is a concern that typically cross-cuts over multiple objects, like logging or transaction management.
A join point is a point of code execution in the target object. In Spring AOP, this is always the execution of a method.
An advice is a chunk of code that gets executed at a specific join point - before, before and after (around), or after execution of the target object's code.
A pointcut is a combination of a class filter and method matcher, matching one or more join points.
Target objects, or advised, are those objects to which one or more aspects are applied. These objects will be proxied in Spring AOP.
An AOP proxy wraps a target object, delegates to it, and executes applicable advices.
An introduction adds code - an interface and its implementation - to a target object; the object will implement additional methods.

Advices

An aspect is a concern that typically cross-cuts over multiple objects, like logging or transaction management.

Declaring or Implementing an Advice

There are three ways to implement an advice in a Spring application:

Declaring an Advice in XML configuration

In a configuration file that is passed to Spring's ApplicationContext, i.e., an around advice might be declared as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:aop="http://www.springframework.org/schema/aop" 
        xsi:schemaLocation="
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
        ...
        <aop:config>
                <aop:aspect ref="someBean">
                        <aop:around method="doProfiling" pointcut="execution(* *(..))" />
                </aop:aspect>
        </aop:config>
        ...
</beans>
Pointcut expressions (like execution(* *(..))) are discussed in chapter Pointcut Expressions.

Declaring an Advice Using AspectJ Annotations

In Java code, in an aspect, AspectJ annotations - in package org.aspectj.lang.annotation - can be used to declare an advice:
@Aspect
public class ProfilingAdvice {

        @Around("execution(* *(..))")
        public void doProfiling() {
                ...
        }
}
Pointcut expressions (like execution(* *(..))) are discussed in chapter Pointcut Expressions.
For AspectJ annotations to be picked up by Spring, an application configuration file must contain:
<aop:aspectj-autoproxy />

Implementing an Advice by Implementing a Specific Interface

In package org.springframework.aop, Spring provides several interfaces, i.e., MethodBeforeAdvice, which all extend org.aopalliance.aop.Advice. Somewhat surprisingly, no interface for around advices exists in the org.springframework.aop namespace. For around advices the interface org.aopalliance.intercept.MethodInterceptor would be implemented, i.e.:
public class ProfilingAdvice implements MethodInterceptor {
 
        public Object invoke(MethodInvocation method) throws Throwable {
                ...
        }
}
While this approach is valid, implementing any of both alternatives is simpler. Thus, like the Spring Reference Documentation, this article will focus on the latter ones. Anyways, there is more information available in the article Spring: A Quick Journey Through Spring AOP.

Types of Advices

Before Advice

A before advice gets executed before a join point. It may interrupt the execution flow by throwing a Throwable. It can access the target object itself, the target object's method currently being called, and the method arguments:
public interface MethodBeforeAdvice extends BeforeAdvice {
        void before(Method method, Object[] args, Object target) throws Throwable;
}
The equivalent AspectJ annotation is @Before, the equivalent XML tag aop:before.

After Returning Advice

An after returning advice gets executed after a method successfully returned.
public interface AfterReturningAdvice extends AfterAdvice {
        void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;
}
The equivalent AspectJ annotation is @AfterReturning, the equivalent XML tag aop:after-returning.

After Throwing Advice

An after throwing advice gets executed after a method has thrown an exception.
public interface ThrowsAdvice extends AfterAdvice {
}
Implementing classes must implements methods of the shape:
void afterThrowing([Method, args, target], ThrowableSubclass);
If the advice throws an exception itself, that will override the target object's original exception. If the advice's exception is not a RuntimeException but a checked Exception, it mandantorily needs to be compatible with the exception the target method declares in its throws clause.
The equivalent AspectJ annotation is @AfterThrowing, the equivalent XML tag aop:after-throwing.

After Advice

An after advice gets executed after a method returned, whether an exception had been thrown or not.
public interface AfterAdvice extends Advice {
}
From the reference documentation, it's not quite clear how to implement valid methods here.
The equivalent AspectJ annotation is @After, the equivalent XML tag aop:after.

Around Advice

An around advice gets executed before and / or after the target method is executed.
public interface org.aopalliance.intercept.MethodInterceptor extends org.aopalliance.intercept.Interceptor {
        Object invoke(org.aopalliance.intercept.MethodInvocation arg0) throws Throwable;
}
The equivalent AspectJ annotation is @Around, the equivalent XML tag aop:around.
When annotating with @Around or using the aop:around XML tag, the depicted method can take a ProceedingJoinPoint as a method argument, which can be used to invoke the target method. Its Object proceed(..) method may take custom arguments to be passed to the target method. That way further execution can be manipulated. Also, the target method's return value - if any - can be modified or replaced.
In this article's sample application's I18nAdvice, an around advice is used to add commonly used data to each ModelAndView:
@Aspect
public class I18nAdvice {
        ...

        @Around("execution(org.springframework.web.servlet.ModelAndView *.*(..))")
        public ModelAndView addSupportedLocales(ProceedingJoinPoint joinPoint)
                        throws Throwable {
                ModelAndView mav = (ModelAndView) joinPoint.proceed();

                mav.addObject("supportedLocales", supportedLocales);

                return mav;
        }
}

Pointcuts

A pointcut is a combination of a class filter and method matcher, matching one or more join points.

Pointcut Expressions

Pointcut expressions consist of a designator and arguments passed to the former.
The designator most often used is execution, which matches method execution join points.
Other designators do filter for types, arguments, and annotations.
Pointcut expressions can be combined by using the &&, || and ! operators.
The format of an execution expression is:
execution(
        modifiers-pattern? 
        ret-type-pattern 
        declaring-type-pattern? 
        name-pattern(param-pattern)
        throws-pattern?
)
In example, the pattern ...
execution(* *(..))
... matches any method.
execution(org.springframework.web.servlet.ModelAndView *.*(..))
... matches any method that returns a ModelAndView instance.

Declaring or Implementing a Pointcut

There are three ways to implement a pointcut in a Spring application:

Declaring a Pointcut in XML Configuration

In a configuration file that is passed to Spring's ApplicationContext, i.e., a pointcut might be declared as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:aop="http://www.springframework.org/schema/aop" 
        xsi:schemaLocation="
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
        ...
        <aop:config>
                <aop:aspect ref="someBean">
                        <aop:around method="doProfiling" pointcut="execution(* *(..))" />
                </aop:aspect>
        </aop:config>
        ...
</beans>
Alternatively, the pointcut can be defined in its own XML element:
<aop:config>
        <aop:aspect ref="someBean">
                <aop:pointcut expression="execution(* *(..))" id="myPointcut"/>
                <aop:around method="doProfiling" pointcut-ref="myPointcut" />
        </aop:aspect>
</aop:config>
Pointcut expressions - like execution(* *(..)) - are discussed in chapter Pointcut Expressions.

Declaring a Pointcut Using AspectJ Annotations

AspectJ pointcut annotations (see chapter Types of Advices) typically take a pointcut expression as an argument, so there is an implicit pointcut declaration.
Additionally, there is the @Pointcut annotation, which is - obviously - not an advice, but can be referred by one, i.e.,
@Pointcut("execution(* *(..))")
public void foo() {}

@Before("foo()")
public void bar() {
        ...
}

Pointcut Implementations

In subpackages of org.springframework.aop, Spring provides a number of Pointcut implementations:
The AspectJExpressionPointcut evaluates AspectJ expressions - mainly execution expressions, which, however, can be combined with others.
There are two contrasting, abstract, *MethodMatcherPointcuts: StaticMethodMatcherPointcut (with a JdkRegexpMethodPointcut implementation, that makes use of regular expressions) and DynamicMethodMatcherPointcut. Implementations of the latter will finally execute a method of the following signature (from the MethodMatcher interface inherited):
boolean matches(Method method, Class targetClass, Object[] args);
This allows for evaluating method argument values at runtime.
An AnnotationMatchingPointcut inspects Java 5 annotations on the type or method level.
A ComposablePointcut allows for combining Pointcuts, or their ClassFilters or MethodMatchers, respectively. Applying the union(..) method means, both pointcuts need to match, applying the intersection(..) method, one of both must match. In practice, it might be easier to use AspectJ expressions.
A Pointcut, basically, is made up of a ClassFilter and a MethodMatcher.
Finally, there is a TruePointcut that is always matching (it is used to control "temporary" - like abstract - program flow in other Pointcut implementations).

Advisors

An advisor (Advisor) is an aspect that refers to a single advice. A pointcut advisor (PointcutAdvisor) - with its implementation DefaultPointcutAdvisor - extends the advisor by additionally referring to a pointcut, linking advice and pointcut. There are some other types of advisors, not discussed at this place.
In XML configuration, an advisor can be set up as follows:
<!--
        Add read-only transactions to all get* methods in the service layer.
—>
<tx:advice id="readOnlyTransactionsAdvice"
        transaction-manager="transactionManager">
        <tx:attributes>
                <tx:method name="get*" read-only="true" />
                <tx:method name="*" />
        </tx:attributes>
</tx:advice>

<aop:config>
        <aop:pointcut id="serviceLayerGettersPointcut"
                expression="execution(* com.acme.sample.businessfacade.impl.*.*(..))" />
        <aop:advisor id="readOnlyTransactionsInServiceLayerAdvisor"
                advice-ref="readOnlyTransactionsAdvice" pointcut-ref="serviceLayerGettersPointcut" />
</aop:config>
As with Advice and Pointcut implementations, Advisors, too, can be implemented using the Java APIs. A working example is discussed in chapter Add Transactional Behavior to Certain Methods.

AOP and Dependency Injection

In chapter Providing a List of Selectable Locales, an AOP advice is added to each method that returns a ModelAndView:
@Aspect
public class I18nAdvice {
        ...

        @Around("execution(org.springframework.web.servlet.ModelAndView *.*(..))")
        public ModelAndView addSupportedLocales(ProceedingJoinPoint joinPoint)
                        throws Throwable {
                ...
        }
}
As a result, actually, an AOP proxy (a JdkDynamicAopProxy) is used whenever the advised class is needed. This AOP proxy cannot be cast to the advised class, AdminAddCustomerController. (A ClassCastException will be thrown.)
The reason is, the proxy does not extend the advised class, but delegates to it.
In contrast, if an interface (AdminAddCustomer) can be extracted from the advised class (AdminAddCustomerController), the JdkDynamicProxy can be cast to that interface (down-cast from Controller which the proxy implements):
public class AdminAddCustomerControllerTests extends AbstractTests {
        @Autowired
        @Resource(name="adminAddCustomerController")
        private AdminAddCustomer controller;
...
In web applications, alternatively to using an AOP advice, a Spring servlet HandlerInterceptor could be used to postHandle(..) a ModelAndView.

AOP Use Cases in the Sample Application

Add Transactional Behavior to Certain Methods

Chapter tx:advice XML Configuration describes how to combine an advice, a pointcut, and an advisor, in order to add transactional behavior to certain method executions.
Under the hood, Spring uses AOP with all of its transaction management, i.e., when methods are marked @Transactional.

Add a List of Available Languages To Each MVC View

For customized GUI internationalization, the end user needs to choose a language from a list. This list will be displayed in any MVC view, and thus, passed to each ModelAndView instance.
The advice I18nAdvice is defined as:
@Aspect
public class I18nAdvice {
        private Map<String, String> supportedLocales;

        @Resource(name="supportedLocales")
        public void setSupportedLocales(Map<String, String> locales) {
                this.supportedLocales = locales;
        }

        @Around("execution(org.springframework.web.servlet.ModelAndView *.*(..))")
        public ModelAndView addSupportedLocales(ProceedingJoinPoint joinPoint)
                        throws Throwable {
                ModelAndView mav = (ModelAndView) joinPoint.proceed();

                mav.addObject("supportedLocales", supportedLocales);

                return mav;
        }
}
Alternatively to using an AOP advice, a Spring servlet HandlerInterceptor could be used to postHandle(..) a ModelAndView.
For more information on the implementation of this use case, see chapter Providing a List of Selectable Locales.

Notify Vendor on Order Placement

Several vendors in the sample application wish to be notified whenever a customer places an order that concerns them. Other vendors would wish, too, however, they don't have any notification gateway (but snail mail). ;-) Thus, notifications are only transmitted to a - configurable - list of vendors.
This use case is implemented by using Spring's AOP API, particularly, DefaultPointcutAdvisor, Pointcut and MethodMatcher, and AfterReturningAdvice.
The following image shows the related bean configuration in appContext-businessFacadeInterceptors.xml:
Bean Configuration
Starting at the image's right bottom, the configuration defines a list of vendors (by their names) that need to be notified:
<util:list id="vendorsToNotifyList">
        <value>vendor1</value>
        <value>John Doe</value>
        <value>Big Bill Broonzey</value>
</util:list>
Based on that list that is passsed to the pointcut ...
<bean id="vendorNotifierPointcut"
        class="com.acme.sample.businessfacade.aop.VendorNotifierPointcutImpl"
        p:vendorsToNotifyNames-ref="vendorsToNotifyList"></bean>
... the sample application's self-implemented DynamicMethodMatcherPointcut, VendorNotifierPointcutImpl, decides, based on runtime arguments, whether boolean matches(.., Object[] args) returns true:
public boolean matches(Method method, Class targetClass, Object[] args) {
        boolean matches = matches(method, targetClass);
        
        if (matches) {
                matches = false;
                
                Order order = (Order) args[0];
                String vendorName = order.getVendor().getName();
                
                for (String vendorToNotifyName : vendorsToNotifyNames) {
                        if (vendorName.equals(vendorToNotifyName)) {
                                matches = true;
                                break;
                        }
                }
        }
        
        return matches;
}
If true gets returned, an AfterReturning advice, VendorNotifierAdviceImpl will be called, that notifies the vendor via several remoting services, including RMI:
@Override
public void afterReturning(Object returnValue, Method method,
                Object[] args, Object target) throws Throwable {
        Order order = (Order) args[0];
        vendorRmiConnector.notifyAboutNewOrder(order);
}
This use case is tested by InsertOrderTest's insertOrder() method.
For more information on this use case see chapter Use Cases: Customers

Data Persistence

Spring supports a number of data access technologies, including JDBC (Java Database Connectitiy) and several object-relational mapping (ORM) tools: Hibernate, JDO (Java Data Objects), Oracle TopLink, iBATIS SQL Maps and JPA (Java Persistence API).
In the sample application, JDBC and (mostly) Hibernate is used, and only these are covered by this article.

DataSource Setup

A javax.sql.DataSource implementation can be set up in the application context's XML configuration files. Here, a BasicDataSource, provided by the Apache Commons project, is used:
<?xml version="1.0" encoding="UTF-8"?>
<beans 
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
         xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="
                        http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-2.5.xsd">
        <context:property-placeholder location="classpath:jdbc.properties" />

        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
                destroy-method="close"
                p:driverClassName="${jdbc.driverClassName}"
                p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" />
</beans>
At the end of the data source's lifecycle, Spring will call its method specified by destroy-method to close the database connection properly.
It is good practice to externalize the database connection properties into a separate file to support an administrator or deployer focus on the settings she actually needs to edit: There are placeholders like ${jdbc.username}, which are to be found in a file classpath:jdbc.properties. This file might have the following content:
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:file:testdb
jdbc.username=sa
jdbc.password=
For the placeholder replacement to work, a PropertyPlaceholderBeanDefinitionParser needs to be set up to find the placeholder definitions file: <context:property-placeholder location="classpath:jdbc.properties" />.
Alternatively to using a BasicDataSource, one could obtain a data source from JNDI as follows:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/DefaultDS"/>
</bean>

The Sample Application's Data Access Layer

Domain Model

Domain Model
The sample application's domain objects - entities - can be located in the com.acme.sample.domain package.
Users need to login into the application. Upon successful authentication they are associated with one or more Authority, which has a role ROLE_ADMINISTRATOR, ROLE_CUSTOMER or ROLE_VENDOR.
While Users that have the Role ROLE_ADMINISTRATOR are able to edit the shop's meta data (add, edit, delete Users, Customers, Vendors and Products), the application's business use cases are tailored to the BusinessUsers, which are specified as Customers and Vendors. See chapter User Roles for more information.
Both Customers and Vendors - as they are BusinessUsers - may have Orders associated. Furthermore, a Vendor may have an assortment of Products.
An Order has a Vendor and a Customer, and it has one or more LineItems, which consists of a number (count) of a Product.
The following table shows the entities's relations:
Entity Relation Target Entity Relation Type
User Authority one-to-many
BusinessUser one-to-one (target may be null)
BusinessUser (Customer or Vendor) Order one-to-many
Vendor Product one-to-many
Order Customer one-to-one
Vendor one-to-one
LineItem one-to-many
LineItem Product one-to-one
These are has-a relations, refering to bean properties.
There are also a number of is-a relations, refering to inheritance: All entities have an id, so they inherit from the AbstractIdentifiable class, which defines a public getter and setter method for that field. Most entities also have a name, so they extend the class AbstractNameable. Both Customers and Vendors can have associated Orders, so they inherit from the BusinessUser class.
The following image shows the corresponding database diagram:
Database Diagram

Data Access Layer

The sample application's data access objects (DAOs) are defined via Java interfaces (in the com.acme.sample.dao package). The business objects that are using them are unaware of the actual data access implementations, which may be replaced without affecting the business objects' functioning at all.
For each domain object (entity), one data access object exists. All of them extend the interface GenericDAO<T extends AbstractIdentifyable> that defines common data access operations:
public interface GenericDAO<T extends AbstractIdentifyable> {
        T get(int id);

        List<T> get(String filterCriteria);

        List get(String query, Object[] params);

        List<T> get();

        void insert(T object);

        void update(T object);

        void remove(T object);
}
Data access operations that cannot be shared with other entities, are defined separately:
public interface OrderDAO extends GenericDAO<Order> {
        /**
         * Return a list of orders for the given customer.
         */
        List<Order> get(Customer customer);

        /**
         * Return a list of orders for the given vendor.
         */
        List<Order> get(Vendor vendor);
}

ORM with Hibernate

Object-Relational Mapping (ORM, O/RM or O/R mapping) means converting database entities to objects that can be accessed programmatically.

SessionFactory Setup

The Hibernate SessionFactory is set up as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans 
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
         xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="
                http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                http://www.springframework.org/schema/context 
                http://www.springframework.org/schema/context/spring-context-2.5.xsd">
        
        <context:property-placeholder location="classpath:jdbc.properties" />

        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
                destroy-method="close" 
                p:driverClassName="${jdbc.driverClassName}"
                p:url="${jdbc.url}" 
                p:username="${jdbc.username}"
                p:password="${jdbc.password}" />

        <bean id="sessionFactory"
                class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
                p:dataSource-ref="dataSource" 
                p:mappingResources="article.hbm.xml">
                <property name="hibernateProperties">
                        <props>
                                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}
                                </prop>
                                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}
                                </prop>
                        </props>
                </property>
                <property name="eventListeners">
                        <map>
                                <entry key="merge">
                                        <bean
                class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener" />
                                </entry>
                        </map>
                </property>
        </bean>
</beans>
The LocalSessionFactoryBean that creates an org.hibernate.SessionFactory basically is configured by setting a reference to a DataSource and specifying one or more Hibernate mappingResources. There are numerous other settings which could be configured, however, the aforementioned ones might be most common.
It is also mandantory to specify the hibernate.dialect (i.e., to a org.hibernate.dialect.PostgreSQLDialect) to enable Hibernate build matching SQL statements for the database used.
In this case, the placeholders - already discussed in chapter DataSource Setup - again are read from the jdbc.properties file.
The IdTransferringMergeEventListener is needed in order to transfer the ID of entities newly saved by Hibernate - typically, the ID will be auto-generated by the database on INSERT - back to the entity object. This is not standard behavior with Hibernate Session's Object merge(Object) .. method.

Hibernate Mappings

ORM mappings - as with Hibernate - associate object data (persistent entities) to relational data (a relational database).
In general, the mappings can be expressed in an XML format or, alternatively, as Java 5-style annotations.
This article covers XML mappings only, and only those needed to construct the sample application. For more information please consult the Hibernate Reference Documentation.
Basically, a mapping file consists of the classes to be mapped:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
                "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
        <class name="com.acme.sample.domain.LineItem" table="line_items" />
        <class name="com.acme.sample.domain.Order" table="orders" />
        ...
</hibernate-mapping>
The table attribute is optional, and defaults to the class name.

id Element

Every mapped class needs to have an ID - to be mapped to a table's primary key. When a record gets inserted, the database will usually generate the primary key value, automatically. Different strategies exist for primary key generation, however, generator class="native" should work with any database. id's name attribute refers to the Java entity's property name (the column refers to the table column name, is optional, and defaults to the Java property name):
<hibernate-mapping>
        <class name="com.acme.sample.domain.LineItem" table="line_items">
                <id name="id" column="id">
                        <generator class="native" />
                </id>
                ...
        </class>
        ...
</hibernate-mapping>

property Element

Plain properties are mapped by using the property element:
<hibernate-mapping> 
        <class name="com.acme.sample.domain.User" table="users">
                ...
                <property name="name" column="user_name" length="50"
                        not-null="true" unique="true" />
        </class>
        ...
</hibernate-mapping>
The field's data type will be determined by Java reflection, so the attribute type is optional. Field restrictions can be specified (i.e., length and not-null). unique="true" will add a unique constraint, and index="index_name" will build an index.

Relations

Often, entity properties refer to other entities (Java classes, respectively). These has-a properties can be one-to-one, one-to-many, many-to-one, and many-to-many relations. Collections can be mapped, Lists, Sets, and Maps.
Relations can be unidirectional or bidirectional.
One-to-one Relation
The sample application does not have a use case for a one-to-one relation. However, expressed in Java, an example could be:
class Person {
        Address address;

        Address getAddress { return address; }
        setAddress(Address address) { this.address = address; }
}
Matching Hibernate mappings would be:
<class name="com.acme.sample.domain.Address">
        <id name="id">
                <generator class="native" />
        </id>
        <property name="street" />
        <property name="city" />
</class>

<class name="com.acme.sample.domain.Person">
        <id name="id">
                <generator class="foreign">
                        <param name="property">address</param>
                </generator>
        </id>
        <property name="name" />
        <one-to-one name="address" constrained="true" />
</class>
The address mapping is straight. The person mapping specifies an id generator that will synchronize the ids of both classes on SQL INSERTs. There is a one-to-one relation to the address entity which is constrained (expressing a foreign key). By default, the id fields will be used for the relation.
To make this relation bidirectional, one would add an additional one-to-one relation to the address mapping.
Alternatively to a one-to-one mapping, a unique many-to-one mapping could be used:
<class name="com.acme.sample.domain.Person">
        <id name="id">
                <generator class="native" />
        </id>
        <property name="name" />
        <many-to-one name="address" column="person_id" unique="true" />
</class>
This would add a field person_id to the person table, pointing via a foreign key to the address table's id field, plus create a unique constraint on the person_id field.
Optional, Bidirectional, One-to-one Relation
In the sample application there is an optional, bidirectional, one-to-one relation between a (Spring Security) User and a BusinessUser (Customer or Vendor):
To a User (having a login name and password - authentication - as well as a set of privileges to access parts of the application - authorization), a Customer or Vendor can be assigned (for example, they can see their own orders). On the other hand, a User with the role Administrator (ROLE_ADMINISTRATOR) does not need to be a BusinessUser.
Such a constraint can be expressed by a many-to-one (on table business_users), plus a one-to-one (on table users) relation in Hibernate.
However, as stated in a Bug Report, the many-to-one relation still allows more than BusinessUser be assigned to one User.
A unique constraint would eliminate duplicates in table business_users's column user_id, nevertheless, many-to-one name="user" class="...User" unique="true" in the Hibernate configuration does not create one. Even if it would, Hibernate would probably not remove duplicates on updates and inserts, but throw some constraint violation exception.
As another issue, in practice, the relation is not bidirectional: Updating the User by setting setBusinessUser(BusinessUser) does not reflect its changes on the database.
After all, this article's author might be strongly mistaken. Further investigation would fall out of this article's scope, anyways.
Collection Mappings
In Java code, one-to-many, many-to-one and many-to-many relations are expressed as arrays, Lists, Sets and Maps. Returned from a Hibernate Session, they behave like HashMap, HashSet, TreeMap, TreeSet or ArrayList, depending upon the interface type. Corresponding mapping elements are array, primitive-array (both for arrays), list, bag (both for Lists), set and map.
This article only covers set mappings (as they are exclusively used in the sample application), for further information see the Hibernate Reference Documentation, Chapter 6. Collection Mapping ff..
One-to-many Relations
A property of type Set, i.e., ...
class User {
        private Set<Authority> authorities;

        public Set<Authority> getAuthorities() { return authorities }
        public void setAuthorities(Set<Authority> authorities {
                this.authorities = authorities;
        }
}
... is mapped as follows:
<class name="com.acme.sample.domain.User" table="users">
        ...
        <set name="authorities" table="authorities">
                <key column="user_id" />
                <one-to-many class="com.acme.sample.domain.Authority" />
        </set>
        ...
</class>
The Java property is mapped to the table authorities that gets an additional column user_id and a foreign key that points from authorities.user_id back to the primary key users.id.
Many-to-one Relations
A many-to-one relation looks up one or multiple persistent entities of a given type, i.e.:
<class name="com.acme.sample.domain.LineItem" table="line_items">
        ...
        <many-to-one name="product" column="product_id"
                class="com.acme.sample.domain.Product" />
        ...
</class>
The many-to-one element on the LineItem's product property makes Hibernate create a foreign key (from line_items.product_id to products.id).
Many-to-many Relations
A many-to-many relation associates one or more entities of one type with one ore more entities of another type. An example follows:
<class name="com.acme.sample.domain.Product" table="products">
        ...
        <set name="vendors" table="vendors_products">
                <key column="product_id" />
                <many-to-many class="com.acme.sample.domain.Vendor"
                        column="vendor_id" />
        </set>
        ...
</class>
In this case, vendor entities are assigned to the current product entity.
An additional database look up table, vendors_products (not being backed by a Java class at all), is used to hold the various possible vendor_id/product_id combinations. On that table, a composite primary key (vendor_id/product_id) and a foreign key (vendors_products.product_id, referencing products.id) are automatically generated by Hibernate.
The Vendor class mapping defines a similar many-to-many relation, vendors "having" products.
Cascading Operations
Data access operations, including insert, update, and delete, may be cascaded to associated entities.
For example, there is an Order entity that is associated with a Set<LineItem>. When this order object gets inserted (persisted for the first time), its associated lineitems should be inserted, automatically. (Alternatively, the lineitems would need to be inserted by code, after the order had been inserted.)
When the order gets deleted, this operation should cascade on the lineitems, automatically. (Alternatively, the lineitems would need to be removed manually before the order can be removed.)
The cascade attribute can be specified on the association mappings (i.e., on set, list, and map). Its default value is none.
Possible values (cascade types) of the cascade attribute are:
Unfortunately, Hibernate's documentation (particularly, Hibernate Reference Documentation, Chapter 6. Collection Mapping ff.) does not provide comprehensive information on the cascade types. For example, the org.hibernate.annotations.CascadeType enumeration declares additional possible values.
Furthermore, in practice, behaviour will differ (or even fail) amongst different databases. In the sample application, in file article.hbm.xml, the customer mapping's association with the customer's orders is set to cascade="all-delete-orphan". However, deletion of a persisted Customer - for example, in CustomerDaoTest.testRemove(), on the call customerDAO.remove(customer) - will fail with MySQL and HSQLDB, but work with PostgreSQL and Oracle Express:

MySQL and HSQLDB:
Hibernate: update orders set customer_id=null where customer_id=?
PostgreSQL and Oracle Express:
Hibernate: update line_items set order_id=null where order_id=?
Hibernate: delete from line_items where id=?
Hibernate: delete from orders where id=?
Hibernate: delete from business_users where id=?
Nevertheless, investigating in this issue is beyond the article's scope. Probably, the author is mistaken after all.

Additional DDL Commands

For entity relations - one-to-one, one-to-many and many-to-one relations - Hibernate will generate foreign keys, automatically. On single fields, indexes and unique constraints can be added manually by setting the index and unique attribute, respectively, of a property mapping.
To ensure data integrity, however, additional rules are needed by the sample application, i.e.: Additional DDL (Data Definition Language) statements can be specified through the database-object element in Hibernate mappings files, i.e.:
<hibernate-mapping>
        ...

        <database-object>
                <create>
                        ALTER TABLE products
                        ADD CONSTRAINT products_check_price_gt_0 
                        CHECK (price > 0::double precision);
                </create>
                <drop>
                        ALTER TABLE products 
                        DROP CONSTRAINT products_check_price_gt_0;
                </drop>
                <dialect-scope name="org.hibernate.dialect.PostgreSQLDialect" />
        </database-object>
</hibernate-mapping>
The dialect-scope element is optional.
In the sample application, these additional DDL definitions are implemented for the PostgreSQL database only.

Hibernate ORM and Inheritance Mapping

Customers and Vendors share most of their properties. With a User login, either a Customer or Vendor can be associated. - For these reasons, both classes inherit from the BusinessUser class.
Object-relational mapping tools can use different strategies to map an inheritance hierarchy to a relational database:
The article How inheritance works in Hibernate comes with well-explained examples for the aforementioned strategies.
The present article's sample application however makes use of the "single table per class hierarchy" mapping:
<class name="com.acme.sample.domain.BusinessUser" table="BusinessUsers">
        <id name="id">
                <generator class="native" />
        </id>

        <property name="name" column="name" 
                length="255" not-null="true"
                index="businessUserName" />
        <property name="springSecurityUserID" 
                column="springSecurityUserID" not-null="true" 
                index="businessUserSpringSecurityUserID" />
        
        <discriminator column="userType" type="string" length="10" />
        
        <subclass name="com.acme.sample.domain.Vendor"
                discriminator-value="VENDOR">
                <set name="orders" table="Orders">
                        <key column="vendorID" />
                        <one-to-many class="com.acme.sample.domain.Order" />
                </set>
                <set name="products" table="VendorsProducts">
                        <key column="vendorID" />
                        <many-to-many class="com.acme.sample.domain.Product"
                                column="productID" />
                </set>
        </subclass>
        <subclass name="com.acme.sample.domain.Customer"
                discriminator-value="CUSTOMER">
                <set name="orders" table="Orders">
                        <key column="customerID" />
                        <one-to-many class="com.acme.sample.domain.Order" />
                </set>
        </subclass>
</class>
Emphasized elements and attributes are discussed below:
id, name, springSecurityUserID: There is not much to add on the identity field and the other properties. On the fields name and springSecurityUserID, however, Hibernate will create an index.
discriminator: This column indicates the type of the subclass on a per-row basis. There are corresponding discriminator-value attributes on the subclass elements.
subclass Vendor: orders: There is a one-to-many relation between a Vendor and her Orders, defined by the Orders table's vendorID field and - implicitly the primary key is used - the Vendor table's id field. Hibernate will create an appropriate foreign key on the Orders table.
products: As many vendors can have the same product in their assortments, and a vendor's assortment can consist of many products, this is a many-to-many relation. The VendorsProducts table acts as a look up table for vendors' assortments. It is not mapped to a Java class but defined inline in the Vendor and Product (sub)class mappings. Hibernate will generate appropriate foreign keys as well as a composite primary key to that table, automatically.
subclass Customer: Customers have one-to-many relations to their Orders similar to Vendors.

Hibernate DAO Implementations

The sample application's DAO interfaces' - discussed in chapter Data Access Layer - Hibernate implementations are located in the com.acme.sample.dao.impl.hibernate package.
Basically, they use Spring's HibernateTemplate convenience class, that takes care of retrieving and closing Hibernate sessions, handles session lifecycle exceptions, and converts HibernateExceptions to subclasses of Springs DataAccessExceptions (which are the same for all data access technologies Spring integrates).
To a HibernateTemplate instance a - dependency-injected - SessionFactory is passed:
private HibernateTemplate hibernateTemplate;

@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}
This SessionFactory is an instance of a Spring LocalSessionFactoryBean, configured as described in chapter SessionFactory Setup.
The HibernateTemplate instance then is used to implement the DAOs' data access methods:
@Override
public List get(String query, Object[] params) {
        return this.hibernateTemplate.find(query, params);
}

@Override
public T get(int id) {
        return (T) this.hibernateTemplate.get(this.tClass, id);
}

@Override
public List<T> get(String filterCriteria) {
        String queryString = "from " + this.getEntityName()
                        + " where name like ?" + orderBy;

        return (List<T>) this.hibernateTemplate.find(queryString,
                        filterCriteria);
}

@Override
public List<T> get() {
        String queryString = "from " + this.getEntityName() + orderBy;

        return (List<T>) this.hibernateTemplate.find(queryString);
}

@Override
public void insert(T T) {
        this.hibernateTemplate.persist(T);
}

@Override
public void remove(T T) {
        this.hibernateTemplate.delete(T);
}

@Override
public void update(T T) {
        this.hibernateTemplate.merge(T);
}
The HibernateTemplate class also provides a method saveOrUpdate(Object) ...

Generic Data Access Objects

As most of the DAOs' data access methods (any of those quoted above) would contain redundant code, these have been externalized into an abstract, generic, DAO superclass, from which all other DAOs inherit. GenericDaoImpl.java is defined as:
public abstract class GenericDaoImpl
        <T extends AbstractIdentifyable>
        implements GenericDAO<T> {
        // implementation code ...
}
Subclasses extend GenericDaoImpl:
public class CustomerDaoImpl 
        extends GenericDaoImpl<Customer> 
        implements CustomerDAO {
        // inherited methods, which don't need to be overridden ...
}
HibernateTemplate defines a number of methods that take a Class as method argument, i.e., method .. Object get(Class, Serializable) .. (to retrieve an object by its type and primary key).
Normally, one would call that method like, get(Customer.class, 42), however, that does not work with the generic type: get(T.class, 42) (or just T.class) will not compile due to Java type erasure!
A workaround is to use Java reflection to retrieve the class:
this.tClass = (Class<T>) ((ParameterizedType) getClass()
        .getGenericSuperclass()).getActualTypeArguments()[0];

JDBC

Spring provides an abstraction layer over the JDBC API, taking care of opening and closing database connections, offering several convenience classes and methods, and - last not least - eliminating the need of verbose error handling by converting JDBC's checked SQLException to appropriate, unchecked, subclasses of Spring's DataAccessException.

Spring Data Access Exception Hierarchy

So, in Spring, there is a data access exception hierarchy. Since version 1.6, Java natively provides a somewhat comparable hierarchy (before, there was the - relatively uninformative - SQLException only), however, there are still two basic differences:
Spring's DataAccessExceptions extend RuntimeException, which means, they are not checked - and don't need to be handled. That's because Spring presumes most data access exceptions to be non-recoverable (cannot be successfully repeated without modification, anyways).
Also, Spring's DataAccessExceptions are not specific to JDBC: Spring also converts specific exceptions of the various O/R Mappers (ORMs) it supports, to its own, unified, exception hierarchy.
For a more general discussion see Exception Translator Pattern.

Central JDBC Worker Classes

Central JDBC worker classes include:
In this article's sample application, there is an example implementation for each of the aforementioned classes, in the com.acme.sample.dao.impl.jdbc package.
To change which class is used, edit appContext-dataAccessObjects.xml. - I.e., change ...
<bean id="businessUserDAO" class="com.acme.sample.dao.impl.jdbc.JdbcTemplateBusinessUserDaoImpl" />
to ...
<bean id="businessUserDAO" class="com.acme.sample.dao.impl.jdbc.StoredProcedureBusinessUserDaoImpl" />
... and run it by using the BusinessUserDaoTests JUnit test.

JdbcTemplate

JdbcTemplateBusinessUserDaoImpl in the sample application is a wrapper around Spring's JdbcTemplate:
public class JdbcTemplateBusinessUserDaoImpl implements BusinessUserDAO {
        private JdbcTemplate jdbcTemplate;

        @Autowired
        public void setDataSource(DataSource dataSource) {
                this.jdbcTemplate = new JdbcTemplate(dataSource);
        }
        
        ...
}
To the JdbcTemplate's List query(..) method, an SQL string, an array of SQL parameters and a RowMapper instance are passed:
@Override
@SuppressWarnings("unchecked")
public List<BusinessUserWrapper> getCandidatesForLogin(int loginID) {
        String query = "select id, name, security_user_id"
                        + " from business_users where security_user_id <> ?"
                        + " or security_user_id is null";

        return (List<BusinessUserWrapper>) this.jdbcTemplate.query(
                        query,
                        new Object[] { loginID }, 
                        new RowMapper() {

                                @Override
                                public BusinessUserWrapper mapRow(ResultSet rs, int rowNum)
                                                throws SQLException {
                                        BusinessUserWrapper user = new BusinessUserWrapper();
                                        user.setId(rs.getInt("id"));
                                        user.setName(rs.getString("name"));
                                        user.setSpringSecurityID(rs.getInt("security_user_id"));

                                        return user;
                                }
                        });
}
The anonymous RowMapper instance is used to convert each row of the JDBC ResultSet to an arbitrary data access object (DAO). The JdbcTemplate instance will handle, and convert, the SQLException that might be thrown.

SimpleJdbcTemplate

SimpleJdbcTemplate, wrapped by SimpleJdbcTemplateBusinessUserDaoImpl in the sample application, behaves like JdbcTemplate, except from the fact it considers Java 5 semantics:
public class SimpleJdbcTemplateBusinessUserDaoImpl implements BusinessUserDAO {
        private SimpleJdbcTemplate simpleJdbcTemplate;

        @Autowired
        public void setDataSource(DataSource dataSource) {
                this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
        }

        @Override
        public List<BusinessUserWrapper> getCandidatesForLogin(int loginID) {
                String query = "select id, name, security_user_id"
                                + " from business_users" + " where security_user_id <> ?"
                                + " or security_user_id is null";

                return this.simpleJdbcTemplate.query(
                        query,
                        new BusinessUserRowMapper(), 
                        loginID);
        }
}
As Java 5 generics are used, no type cast is needed when returning the result of SimpleJdbcTemplate's List<T> query(..) method. The last method argument is of type Object ..., a Java 5, variable-length, array (vararg). The int parameter gets autoboxed to an Integer instance.
The BusinessUserRowMapper used here converts each JDBC ResultSet row to a DAO (exactly like demonstrated above in the JdbcTemplate demonstration). It implements Spring's ParameterizedRowMapper, which extends RowMapper and adds Java 5 generic type parametrization:
public class BusinessUserRowMapper implements
                ParameterizedRowMapper<BusinessUserWrapper> {

        @Override
        public BusinessUserWrapper mapRow(ResultSet rs, int rowNum)
                        throws SQLException {
                ...

NamedParameterJdbcTemplate

NamedParameterJdbcTemplate (wrapped by NamedParameterJdbcTemplateBusinessUserDaoImpl in the sample application), supports the use of named SQL parameters:
      public List<BusinessUserWrapper> getCandidatesForLogin(int loginID) {
                String query = "select id, name, security_user_id"
                                + " from business_users" + " where security_user_id <> :id"
                                + " or security_user_id is null";
                
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("id", loginID);

                return (List<BusinessUserWrapper>) this.jdbcTemplate.query(query,
                                params, new BusinessUserRowMapper());
        }
Instead of the Map, a SqlParameterSource could be used, which allows for adding finer-grain information on the parameters passed, including their data types (otherwise determined by reflection).

StoredProcedure

The abstract StoredProcedure class is a convenience wrapper around (finally) JdbcTemplate, faciliating stored procedure calls. In the sample application, it is implemented by StoredProcedureBusinessUserDaoImpl.
Obviously, for this demo class to work, a stored procedure with a matching signature must exist in the database. In the sample application, this is implemented for the PostgreSQL database, only. Compare chapter Additional DDL Commands, where that procedure - for PostgreSQL, a type and a function - gets automatically created by Hibernate:
<database-object>
        <create>CREATE TYPE business_user_wrapper as (
        id integer, name character varying(255), security_user_id integer)</create>
        <drop>DROP TYPE business_user_wrapper</drop>
        <dialect-scope name="org.hibernate.dialect.PostgreSQLDialect" />
</database-object>
<database-object>
        <create>CREATE FUNCTION get_candidates_for_login(login_id integer) 
                RETURNS SETOF business_user_wrapper 
                AS
                        'select id, name, security_user_id 
                        from business_users 
                        where security_user_id &lt;&gt; $1 
                        or security_user_id is null'
                LANGUAGE 'sql' VOLATILE;</create>
        <drop>DROP FUNCTION get_candidates_for_login(integer)</drop>
        <dialect-scope name="org.hibernate.dialect.PostgreSQLDialect" />
</database-object>
As usual, a DataSource reference needs to be passed (typically, injected). After setting the SQL statement (simply the name of the stored procedure to call) and in and out parameters, the StoredProcedure's central method Map execute(Map) is executed, passing a Map of function parameters. One of the possible return values (there may be multiple ones) is, in case of the bespoken demonstration class, a List<BusinessUserWrapper>:
public class StoredProcedureBusinessUserDaoImpl extends StoredProcedure
                implements BusinessUserDAO {
        private static final String STORED_PROCEDURE_NAME = "get_candidates_for_login";

        private static final String STORED_PROCEDURE_PARAM1 = "login_id";

        private static final String RESULT_SET_NAME = "businessUsers";

        @Autowired
        public void setDataSource(DataSource dataSource) {
                super.setDataSource(dataSource);
        }

        public StoredProcedureBusinessUserDaoImpl() {
                this.setSql(STORED_PROCEDURE_NAME);
                // input parameter
                this.declareParameter(new SqlParameter(STORED_PROCEDURE_PARAM1,
                                Types.INTEGER));
                // output (parameter)
                this.declareParameter(new SqlReturnResultSet(RESULT_SET_NAME,
                                new BusinessUserRowMapper()));
                // this call does have a return value
                this.setFunction(true);
        }

        @SuppressWarnings("unchecked")
        @Override
        public List<BusinessUserWrapper> getCandidatesForLogin(int loginID) {
                Map<String, Object> params = new HashMap<String, Object>();
                params.put(STORED_PROCEDURE_PARAM1, loginID);

                Map result = this.execute(params);

                return (List<BusinessUserWrapper>) result.get(RESULT_SET_NAME);
        }
}

Transaction Management

Transaction Definitions

Transactions in Spring are defined by the TransactionDefinition interface.

Propagation

Propagation means the scope of one or more transactions.
In Spring, transaction propagation (see TransactionDefinition and Propagation) behaves analogous to the Transaction Attributes of Java EE Container-Managed Transactions.
Possible values are (the descriptions are copied from the JavaDocs):

Isolation

An isolation level denotes the extend to which a transaction can read uncommitted data changes of other transactions.
Spring's TransactionDefinition defines the same isolation levels as those defined in java.sql.Connection. See these types' JavaDocs for further information.

Other Transaction Settings

Transactions can have an execution timeout.
Transactions can be read-only. This does not necessarily prevent from executing writing operations but may be a hint to the underlying transaction manager to allow optimizations.
Using the @Transactional annotation, conditions for rollback and no-rollback can be set.

Transaction Managers

PlatformTransactionManager is the central interface in Spring's transaction infrastructure, and defines the methods commit(TransactionStatus), rollback(TransactionStatus), and getTransaction(TransactionDefinition). All Spring transaction managers extend AbstractPlatformManager, which implements PlatformTransactionManager.
Spring provides the following transaction managers:
Transaction Manager Manages Transactions of
CciLocalTransactionManager javax.resource.cci.ConnectionFactory
DataSourceTransactionManager java.sql.DataSource
HibernateTransactionManager org.hibernate.SessionFactory (and java.sql.DataSource)
JdoTransactionManager javax.jdo.PersistenceManagerFactory (and java.sql.DataSource)
JmsTransactionManager (plus, JmsTransactionManager102 for legacy JMS 1.0) javax.jms.ConnectionFactory
JpaTransactionManager javax.persistence.EntityManagerFactory (and java.sql.DataSource)
JtaTransactionManager an underlying javax.transaction.TransactionManager
TopLinkTransactionManager org.springframework.orm.toplink.SessionFactory (and java.sql.DataSource)
JtaTransactionManager delegates operations to an underlying TransactionManager. By default (the corresponding property is autodetectTransactionManager), it will try to resolve a TransactionManager the application server, resp., container, provides. Java EE containers' JTA providers may support distributed transactions (across multiple data sources) and the PROPAGATION_REQUIRES_NEW transaction scope.
For specific Java EE containers, special subclasses of JtaTransactionManager exist: OC4JJtaTransactionManager, WebLogicJtaTransactionManager and WebSphereUowTransactionManager.

Setting Up a Transaction Manager

In the sample application, a HibernateTransactionManager is used to manage transactions (in applicationContext-dataSource.xml):
<bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager"
        p:sessionFactory-ref="sessionFactory" />
It depends on a LocalSessionFactoryBean (that creates a org.hibernate.SessionFactory). The configuration of a LocalSessionFactoryBean is described in chapter SessionFactory Setup.
A JtaTransactionManager (or one of its subclasses mentioned in chapter Transaction Managers) may also be configured by using the tx:jta-transaction-manager tag (its bean name will be "transactionManager", automatically):
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

        <tx:jta-transaction-manager />
        ...

Declarative Transaction Management

tx:advice XML Configuration

As a trivial example, the sample application adds read-only transactions to any methods in the service layer whose names start with "get".
As mentioned in chapter Other Transaction Settings, setting the read-only property of a transaction may be a hint to the underlying transaction manager for optimizations.
In appContext-businessFacadeInterceptors.xml, a transactional advice is configured, an AOP pointcut, and an AOP advisor:
<tx:advice id="readOnlyTransactionsAdvice"
        transaction-manager="transactionManager">
        <tx:attributes>
                <tx:method name="get*" read-only="true" />
                <tx:method name="*" />
        </tx:attributes>
</tx:advice>

<aop:config>
        <aop:pointcut id="serviceLayerGettersPointcut"
                expression="execution(* com.acme.sample.businessfacade.impl.*.*(..))" />
        <aop:advisor id="readOnlyTransactionsInServiceLayerAdvisor" advice-ref="readOnlyTransactionsAdvice"
                pointcut-ref="serviceLayerGettersPointcut" />
</aop:config>
There is a JUnit test, TransactionsTests, that uses Spring's AopUtils to ensure that the service layer is actually proxied, and that the configured pointcut and advisor are applicable:
@Test
public void testReadOnlyGetMethods() {
        assertTrue("AdminFacade is not proxied by AOP.", 
                AopUtils.isAopProxy(adminFacade));
        assertTrue("AdminFacade is not a JDK Dynamic Proxy.", 
                AopUtils.isJdkDynamicProxy(adminFacade));

        Pointcut pointcut = (Pointcut) applicationContext
                .getBean("serviceLayerGettersPointcut");
        assertTrue(
                "Pointcut serviceLayerGettersPointcut cannot be applied to AdminFacade.",
                AopUtils.canApply(pointcut, AopUtils.getTargetClass(adminFacade)));

        Advisor advisor = (Advisor) applicationContext
                .getBean("readOnlyTransactionsInServiceLayerAdvisor");
        assertTrue(
                "Advisor readOnlyTransactionsInServiceLayerAdvisor cannot be applied to AdminFacade.",
                AopUtils.canApply(advisor, AopUtils.getTargetClass(adminFacade)));
}
See chapter Spring AOP for further information on aspect-orientated programming in Spring.
By default, Spring transactions will automatically rollback when RuntimeExceptions - or Errors are thrown. This behavior can be configured by adding the attributes rollback-for and no-rollback-for (which take a comma-separated list of type names as arguments) to the tx:method element. Other possible attributes are isolation, propagation, and timeout (see chapter Transaction Definitions).

@Transactional Annotation

The Transactional interface defines the same properties as discussed above:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
        Propagation propagation() default Propagation.REQUIRED;
        Isolation isolation() default Isolation.DEFAULT;
        int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
        boolean readOnly() default false;
        Class<? extends Throwable>[] rollbackFor() default {};
        String[] rollbackForClassName() default {};
        Class<? extends Throwable>[] noRollbackFor() default {};
        String[] noRollbackForClassName() default {};
}
This annotation can be applied at the class and method level, requiring Java 5, the bean it is used with being managed by Spring, and a tx:annotation-driven element in an XML configuration file. By default, this element's attribute transaction-manager points to a bean named "transactionManager".
It is recommended not to set annotations on interfaces, but on concrete classes instead: Annotations are not inherited from interfaces and thus don't work with AspectJ proxies. On the other hand, annotations will not work with methods which visibility is anything but public, and JDK proxies. See chapter Spring AOP for more information.
In the sample application, AdminFacade.addOrEditUser(..) and CustomerFacade.addOrder(..) are annotated by @Transactional, however, there is nothing special about that.

Spring MVC

See the Model-View-Controller (MVC) Pattern chapter for more abstract information on MVC goals and architecture.

Controllers

In the sample application, all controllers reside in the com.acme.sample.web.controllers Java package. They are named by the scheme <user role><use case>Controller.java, i.e., VendorListProductsController.java.

AbstractController

Simple controllers that - besides populating a model to supply the view with - just forward to a single view in this case all extend Spring's abstract AbstractController class. A sample goes as follows:
public class CustomerListOrdersController extends AbstractController {
        // ...

        @Override
        protected ModelAndView handleRequestInternal(HttpServletRequest request,
                        HttpServletResponse response) throws Exception {
                Map<String, Object> model = new HashMap<String, Object>();
                model.put("orders", 
                                facade.getCustomer(
                                request.getUserPrincipal().getName()
                                ).getOrders());

                return new ModelAndView("customerListOrders", model);
        }
}
The .. handleRequestInternal(..) .. method returns a ModelAndView instance, which may (in most cases, it will) reference a view to forward to (in most cases, a JSP page) and - in the shape of a Spring ModelMap (implementing a java.util.Map) - arbitrary object instances that the view uses to populate its dynamic portions.
The view then can access the model's List<Order> object (BTW, a list of entitity beans) by the EL (Expression Language) variable $orders.

SimpleFormController

Often, a controller displays a form (which is a view as well), which contents are then filled in by the user, and get posted back to the controller. On success the controller will display another view, on failure (i.e., a mandantory form field has not been filled in by the user), the form will get re-displayed, any validation errors marked and depicted.
Such types of controllers that display a form that gets posted back suite well to extend Spring's SimpleFormController class. - An example:
public class AdminAddVendorController extends SimpleFormController {
        // ...

        public AdminAddVendorController() {
                // views can then access the "form backing object" 
                // by the EL variable $vendor
                setCommandName("vendor");
                
                // location of the form view to display
                setFormView("adminAddVendor");
                
                // what to display after the form data
                // has been saved
                setSuccessView("redirect:adminListVendors.htm");
        }

        // the model, accessible  
        // by the variable $vendor (in this case)
        @Override
        protected Object formBackingObject(HttpServletRequest request)
                        throws Exception {
                return new Vendor(); // a simple entity bean
        }

        // called after a form submit
        @Override
        protected void onBindAndValidate(HttpServletRequest request,
                        Object command, BindException errors) throws Exception {
                // this form has only one editable field,
                // so validation is simple
                ValidationUtils.rejectIfEmpty(errors, "name", "validation.general.nameMustNotBeEmpty",
                                "Name must not be empty.");
        }

        // called after a form submit,
        // if no BindExceptions were raised 
        @Override
        protected void doSubmitAction(Object command) throws Exception {
                // the command object
                // (or form backing object)
                // that the user has edited.
                Vendor vendor = (Vendor) command;
                
                // do some business action
                facade.addVendor(vendor);
                
                // the underlying SimpleFormController instance
                // will now forward to our defined successView
        }
}
So, using Spring's SimpleFormController class, there are two views involved now - a form view and a success view. In this case, these have been defined in in the controller's constructor.
The MVC model is now considered a command, which transfers state (the form data) bi-directionally to the form and back to the controller. In the sample above, a simple entity bean is returned by the Object formBackingObject(HttpServletRequest) method. After the user has edited and posted back the form, the - thereby edited - command object can be evaluated and validated by the controller (in this case, in the overriden methods .. onBindAndValidate(..) .. and .. doSubmitAction() ..).
For to provide data that is used by the view - but not to be edited therein - one can use the Map referenceData(HttpServletRequest) .. method. Similar to the model portion in a ModelAndView instance, a java.util.Map implementation is used to hold arbitrary objects, accessible by their respective keys.
Validation is discussed in the subsection called Validation.
Finally, in the .. doSubmitAction(..) .. method, some business method is used to persist the edited command data, and the SimpleFormController forwards to the successView we had set initially.

AbstractWizardFormController

More complex controllers can display an arbitrary number of views - or pages. In this article's sample application, a customer, who prepares to place an order, first selects a vendor (in one form view), and next products from that vendor's products assortment (in another form view).
Amongst other related methods, Spring's abstract AbstractWizardFormController class provides the method int getTargetPage(HttpServletRequest, Object, Errors, int), where the view to be displayed next can be specified after evaluating request parameters, the command object (discussed in chapter SimpleFormController), validation errors and - of course - the current page (by its page ID).
Accordingly, there is a method setPages(String[]) to set the view names (the first one set there will get the page ID 0, the next one 1, consecutively).
To methods intended for form validation - including .. onBindAndValidate(HttpServletRequest, Object, BindException, int), the page ID is passed as a method argument, to enable developers validate only those fields of the command object that had been edited in the current view.
In the CustomerAddOrderController class, the aforementioned methods are applied:
public class CustomerAddOrderController extends AbstractWizardFormController {
        @Autowired
        private CustomerFacade facade;

        public CustomerAddOrderController() {
                setCommandName("orderForm");

                // specify a number of pages
                setPages(new String[] { "customerAddOrderSelectVendor",
                                "customerAddOrderSelectProducts" });
        }

        @Override
        protected int getTargetPage(HttpServletRequest request, Object command,
                        Errors errors, int currentPage) {
                AddOrderForm form = (AddOrderForm) command;
                if (currentPage == 0 && form.getVendor().getId() > 0) {
                        // a vendor has been selected;
                        // proceed with the "vendor's products" page
                        return 1;
                }
                else if (currentPage == 1) {
                        return 1;
                }

                return 0;
        }

        @Override
        protected void onBindAndValidate(HttpServletRequest request,
                        Object command, BindException errors, int page) throws Exception {
                // synchronize form properties
                AddOrderForm form = (AddOrderForm) command;

                switch (page) {
                case 0: // "select vendor" page
                        // retrieve the vendor that has been selected in form 0
                        Vendor vendor = facade.getVendor(
                                form.getVendor().getId());
                        form.setVendor(vendor);

                        // provide the form with this vendor's products
                        form.setVendorProducts(
                                vendor.getProductsAsList());
                        break;
                case 1: // "select products" page
                        // apply the customer's product selection
                        // ... (edit the form backing bean)
                }
        }

        @Override
        protected Object formBackingObject(HttpServletRequest request)
                        throws Exception {
                AddOrderForm form = new AddOrderForm();
                form.setVendors(facade.getVendors());

                return form;
        }

        @Override
        protected ModelAndView processFinish(HttpServletRequest request,
                        HttpServletResponse response, Object command, BindException errors)
                        throws Exception {

                AddOrderForm form = (AddOrderForm) command;
                form.setCustomer(getCurrentCustomer(request));
                facade.addOrder(form);

                return new ModelAndView("customerAddOrderFinish");
        }
}

Other Controllers

Other controllers (not used in the sample application) include:

Mapping Controllers to URLs

Controllers are handlers for incoming HTTP requests (that point to a certain URL).
Spring's default (it doesn't need to be explicitly specified in the application's configuration) HandlerMapping implementation is BeanNameUrlHandlerMapping. It maps the bean's name to the handling controller:
<bean name="/index.htm" class="com.acme.sample.web.controllers.MainController" />
Bean names may contain ANT-style wildcards. They need to start with a slash.
DefaultAnnotationHandlerMapping is another HandlerMapping that is pre-configured by Spring. It evaluates Java 5 annotations:
@RequestMapping("/index.htm")
public class MainController extends AbstractController { ...
Using SimpleUrlHandlerMapping, one can explicitly map URLs to handlers (wildcards are allowed):
      <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" p:order="0">
                <property name="mappings">
                        <value>
                                /adminAddCustomer.htm=adminAddCustomerController
                        </value>
                </property>
        </bean>
When defining a HandlerMapping that is not a default one, this will override the default settings. Then otherwise implicit handlers need to be explicitly declared:
      <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"
                p:order="0">
                ...
        </bean>

        <!--
                The following two handler mappings only need to be explicitly declared
                when a non-default handler mapping (like SimpleUrlHandlerMapping
                above) is declared.
        —>
        <bean
                class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"
                p:order="1" />
        <bean
                class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"
                p:order="2" />
Other existing HandlerMapping implementations include:

Views

Views - which are based on interfaces and classes in package org.springframework.web.servlet - are not necessarily part of Spring's MVC framework (where the controllers reside in package org.springframework.web.servlet.mvc). Theoretically, Spring views (or MVC views in general) could be used independently of controllers and models, or in other scopes.
This article's view on Spring views, however, is a more practical one. The article needs to flatten information depth.
Additionally, Spring MVC concepts might be used in other environments than with Servlets, i.e., with Spring RichClient (a framework tailored for Java Swing). This article can only consider the - Servlet-based - technologies described in the Spring Framework Reference Documentation.

Passing Model Data to Views

All Controller implementations (indirectly) implement a method ModelAndView handleRequest(..). The returned ModelAndView instance itself provides a central getter Map getModel(), which returns a Map of key/value pairs. From within the views, the values are accessible by their keys.
Additionally, Controllers that implement BaseCommandController (including all Spring controllers that have a "Form" in their class name) manage a command object (of an arbitrary type) that is accessible by the BaseCommandController's String getCommandName() getter method.
In JSP views, a ModelAndView Map's values, i.e., ...
Map model = new HashMap();
model.put("key1", "hello world");

MyHelloWorld myHelloWorld = new MyHelloWorld();
myHelloWorld.setMessage("hello world");
model.put("key2", "hello back");
... would be accessible by using standard JSP expression language (EL):
$key1
$key2.message
Similarly, a BaseCommandController implementation's command object is accessible by the key that had been set by using the class' setCommandName(String) property.
In case of other AbstractView implementations, that don't use EL, but access the model programmatically instead (like an AbstractExcelView implementation), there is always a method that takes the ModelAndView's Map as a method parameter, which can, for instance, be accessed as follows:
public class OrderExcelView extends AbstractExcelView {

        @Override
        protected void buildExcelDocument(Map model, HSSFWorkbook workbook,
                        HttpServletRequest request, HttpServletResponse response)
                        throws Exception {
                Order order = (Order) model.get("order");
                // ...

View Technologies

Out-of-the-box, Spring provides support for the following view technologies:
This article, and its sample application, cover views built upon plain old JSPs (using standard EL (Expression Language)), the JSPs partly enriched by Spring's Form and Security tag libraries, and an Excel producer.

JSP and JSTL Views; Spring's Form Tag Library

Spring does not change the way JSPs work at all. However, it provides a form tag library to bind the form-backing command bean to HTML form fields, i.e., input type="text", input type="checkbox", etc.. These include "multiple HTML element" tags, like a series of connected radiobuttons. There are also fields to display form validation errors. - An example (adminAddOrEditProduct.jsp), demonstrating the usage of Spring's form tag library, follows:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<form:form commandName="product">
        Name:
        <form:input path="name" />
        <form:errors path="name" cssClass="errors" />
        <br />

        Price:
        <form:input path="price" />
        <form:errors path="price" cssClass="errors" />

        &nbsp;
        <input type="submit" value="Save" />
        <br />
</form:form>
The form tag's commandName property matches the BaseCommandController's (and subclasses', like AbstractFormController's and SimpleFormController's) property of the same name. If not set there, it defaults to "command".
The form does not need an action but, by default, POSTs back to the controller that had set the view.
Next in the above code snippet, there are form:input and form:errors tags, bound to a path attribute - that matches a property of the form-backing command bean. Naturally, error messages are only displayed when errors do exist for that form field.
form:checkboxes and form:radiobuttons are checked under the following conditions:
The form:select, form:checkboxes and form:radiobuttons tags allow for selecting one or multiple values (the tag's items attribute) from a list of possible values (the tag's path attribute). Additionally, they may have an itemLabel displayed for the underlying itemValue. An example (from vendorListProducts.jsp) follows:
<form:checkboxes items="${products.allProducts}" path="vendorProductIDs"
        itemLabel="name" itemValue="id"
        element="div" />
The path attribute can hold an array or Collection value, and, in the above code snippet, refers to the property vendorProductIDs of the form's backing bean. It defines the values currently being selected.
The items attribute can hold an array, Collection or Map value. If it is a Map, and the itemLabel and itemValue attributes are not set, the Map's keys and values will be used. This list of all possible values might refer to a property of the form backing bean (the command object), however, it should be separated into the AbstractFormController's (its subclasses') Map referenceData(..).
The element attribute defines which HTML element should surround each input type="checkbox". The default element is span.

Excel Views

In the sample application, an order can be exported to a Microsoft Excel document, which is written to the browser. The view that creates the Excel document extends Spring's abstract class AbstractExcelView and simply overrides one method (from OrderExcelView.java):
protected void buildExcelDocument(Map model, HSSFWorkbook workbook,
                HttpServletRequest request, HttpServletResponse response)
                throws Exception {
        Order order = (Order) model.get("order");

        HSSFSheet sheet = workbook.createSheet("Order");
        
        int row = 0;
        for (LineItem item : order.getLineItems()) {
                HSSFCell cell = getCell(sheet, row, 0);
                setText(cell, String.valueOf(item.getCount()));
                
                cell = getCell(sheet, row, 1);
                setText(cell, String.valueOf(item.getProduct().getName()));
                
                cell = getCell(sheet, row, 2);
                setText(cell, String.valueOf(item.getProduct().getPrice()));
                
                row++;
        }
}
This view is used by a controller like any other view type, including JSPs - once it is registered to the BeanFactory (or ApplicationContext). In the sample application, that is done by adding a normal <bean ... /> definition.
The AbstractExcelView class extends the abstract class AbstractView (like AbstractPdfView and AbstractXsltView do).
By default, the web browser will prompt the user to download the Excel document, not to display it inline. This behavior can be changed by overwriting AbstractView's abstract method boolean generatesDownloadContent() (which returns true with AbstractExcelView).

Resolving Views

In the sample application, mostly an InternalResourceViewResolver is used to resolve JSP views:
<bean p:order="1"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:viewClass="org.springframework.web.servlet.view.JstlView" 
        p:prefix="/WEB-INF/views/"
        p:suffix=".jsp" />
When a controller returns a ModelAndView("listProducts"), the JSP /WEB-INF/views/listProducts.jsp will be rendered.
It is good practice to place JSP views under /WEB-INF to prevent direct access to them, as, per definition, files within /WEB-INF are not accessible by URL.
Just like AbstractExcelView and other classes, the JstlView class extends the AbstractView class which implements the View interface's central method void render(Map, HttpServletRequest, HttpServletResponse) throws Exception.
The ResourceBundleViewResolver is more flexible than the InternalResourceViewResolver and lets one specify the view's class and location per single view:
<bean p:order="0" 
        class="org.springframework.web.servlet.view.ResourceBundleViewResolver"
        p:basename="views" />
The baseName attribute "views" refers to a file named views.properties in the root of the classpath (or, i.e., views_de_DE.properties, when internationalization applies). This attribute may be omitted, the default is "views".
views.properties, in the sample application, contains the following text (for a view named "index"):
index.class=org.springframework.web.servlet.view.JstlView
index.url=/WEB-INF/jsp/index.jsp
Both aforementioned ViewResolvers implement the Ordered interface: By specifying the beans' order attribute, their precedence can be set (a lower int - starting by Integer.MIN_VALUE meaning a higher precedence).
Both InternalResourceViewResolver and ResourceBundleViewResolver refer to a physical location of the targeted view. Plus, they let JstlView handle JSP documents. However, our Excel view (OrderExcelView.java) is a Java class, and can't be addressed that way.

Internationalization

Spring's central ApplicationContext interface extends the MessageSource interface, which - by a number of String getMessage(..) overloaded methods - provides access to - optionally, parametrized or localized - messages.

MessageSource Implementation

Basically, there are two MessageSource implementations: ResourceBundleMessageSource and ReloadableResourceBundleMessageSource. Like the standard java.util.Properties class, both use either *.properties files as message repositories, i.e., ...
validation.general.nameMustNotBeEmpty='Name' must not be empty.
views.includes.navi.youAreLoggedInAs=You are logged in as
... or *.xml files, i.e.,
<entries>
        <entry key="validation.general.nameMustNotBeEmpty">'Name' must not be empty.</entry>
        <entry key="views.includes.navi.youAreLoggedInAs">You are logged in as</entry>
</entries>
The location of one or more of these properties files can be set via the setBaseName(String) and setBaseNames(String[]) methods.
Just like with the standard java.util.ResourceBundle class, such a base name, for instance, could be "messages". Following the rules described in java.util.ResourceBundle.getBundle(..), depending on the given (or default) Locale and the physical existance of these files, a file named "messages_en_US.properties", "messages_de_DE.properties", "messages_en.properties", or "messages.properties" (the default) might be used for input.
While the ResourceBundleMessageSource caches the messages, the ReloadableResourceBundleMessageSource does not if its property cacheSeconds is set.
An application server might cache files, itself. Read ReloadableResourceBundleMessageSource's JavaDoc for tips.
Another difference to ResourceBundleMessageSource and java.util.ResourceBundle is that file encodings can be specified.

Retrieving Messages

In this article's sample application (in file appContext-internationalization.xml), a ReloadableResourceBundleMessageSource is configured as follows:
<bean id="messageSource" 
        p:cacheSeconds="3" p:defaultEncoding="UTF-8"
        p:basenames="/WEB-INF/classes/messages"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
</bean>
In JSPs, messages can now be retrieved by, i.e. (in navi.jsp):
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<div><spring:message code="views.includes.navi.youAreLoggedInAs" /></div> ...
In the sample application's MVC controllers, validation errors are localized:
ValidationUtils.rejectIfEmpty(errors, "name",
        "validation.general.nameMustNotBeEmpty");
Only navi.jsp and the MVC controllers are localized in the sample application.
It has been already mentioned that Spring's ApplicationContext extends the MessageSource interface, so the latter's String getMessage(..) methods are available anywhere where an ApplicationContext is accessible.

Resolving and Changing Locales

LocaleResolver implementations Spring provides include AcceptHeaderLocaleResolver, which looks at the client's (browser's) accept-language HTTP header field, SessionLocaleResolver, which tries to resolve a Locale from the HttpSession, and CookieLocaleResolver, which adds and retrieves HTTP Cookies in order to persist and resolve selected Locales.
In the sample application (in appContext-internationalization.xml), a CookieLocaleResolver is configured:
<bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
LocaleResolver beans must have the id "localeResolver", else they are not recognized by Spring.
In order to enable the user change the locale, a LocaleChangeInterceptor is configured:
<bean id="localeChangeInterceptor"
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
This interceptor needs to be advised to any applicable handler mappings, i.e. (in appContext-modelViewController.xml):
<bean
        class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"
        p:interceptors-ref="localeChangeInterceptor" />
The LocaleChangeInterceptor looks at a HTTP request parameter (with a default name of "locale"), and uses a LocaleResolver to map the parameter's value to a (newly,) selected, Locale. For instance, a HTTP request pointing to the URL "index.htm?locale=de" would set a German locale.

Providing a List of Selectable Locales

This section is rather integrational than conceptual.
In order to let an application's user select a locale from a list, the latter needs to be displayed in at least one view, in this case, in any view.
To add the list (Map in this case) to all ModelAndViews, each method call that returns a ModelAndView is intercepted by an Around advice:
@Aspect
public class I18nAdvice {
        private Map<String, String> supportedLocales;

        /**
         * Specify which locales are supported by the application.
         * @param locales Key: Locale code (i.e., "en", or "en_US").<br>
         * Value: Message code for the display language (i.e., "languages.english",
         * or "languages.german").
         */
        @Required
        public void setSupportedLocales(Map<String, String> locales) {
                this.supportedLocales = locales;
        }

        /**
         * Add a Map of supported locales to each ModelAndView.
         */
        @Around("execution(org.springframework.web.servlet.ModelAndView *.*(..))")
        public ModelAndView addSupportedLocales(ProceedingJoinPoint joinPoint)
                        throws Throwable {
                ModelAndView mav = (ModelAndView) joinPoint.proceed();

                mav.addObject("supportedLocales", supportedLocales);

                return mav;
        }
}
Implications of using AOP on Dependency Injection are discussed in chapter AOP and Dependency Injection.
As with localized messages, an application deployer can specify which locales are supported in a configuration file (appContext-internationalization.xml):
<bean id="i18nAdvice" class="com.acme.sample.web.controllers.advices.I18nAdvice">
        <property name="supportedLocales">
                <map>
                        <entry key="en" value="general.languages.english"></entry>
                        <entry key="de" value="general.languages.german"></entry>
                </map>
        </property>
</bean>
The map's keys represent the locale's country (and, optionally, country and variant) code (see the Locale JavaDocs). The map's values contain the key for the locale's (or language's) display name, as in the localized resource bundles (properties files) the application provides.
Finally, the selectable list can be displayed in the views, here, in navi.jsp:
<%@ taglib prefix='c' uri='http://java.sun.com/jstl/core_rt'%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
...
<c:forEach
        items="${supportedLocales}" 
        var="locale">
        <a href="?locale=${locale.key}">
                <spring:message code="${locale.value}" />
        </a>&nbsp;
</c:forEach>

Request Character Encoding

The CharacterEncodingFilter allows for specifying the character encoding of requests (i.e., posted forms). It is configured in web.xml:
<filter>
        <filter-name>encoding-filter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
        </init-param>
</filter>
<filter-mapping>
        <filter-name>encoding-filter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>
Additionally to setting the encoding property - that only applies if the request does not specify an encoding itself -, the forceEncoding property can be set. This will cause the HttpServletRequest to even override an encoding specified with the request, and also use the encoding as default HttpResponse encoding.

Integration

As an architectural simplification, the article's sample application contains an imaginary second application: a gateway to a vendor's ERP (Enterprise Resource Planning) system, which is located in package com.vendor1, and sub-packages.
A customer, saving a new order, triggers interactions with this, vendor's, application.
For contextual information regarding the sample application, see the chapters Use Cases: Customers and Notify Vendor on Order Placement.
There is also the Spring Web Services framework, which implements the contract-first approach of developing the WSDL file first and derive the Java code from that. This article, however, does not cover that.

Remoting

Spring supports a number of remoting technologies out-of-the-box.
Remoting technologies can be differentiated by their transport protocol (i.e., HTTP, TCP), contents (i.e., binary, XML), and serialization mechanisms (i.e., Java serialization).
In general, binary remoting is faster than, i.e., web services (see Java Remoting: Protocol Benchmarks). On the other hand, interoperatibility - amongst different programming languages - is normally better with web services, although Hessian provides APIs for a wider range of programming languages.

Remote Method Invocation (RMI)

Remote Method Invocation (RMI) is a binary, Java-to-Java only, remoting API.

Server-side Configuration

The remote interface is defined as follows:
public interface RmiConnector {
        /**
         * Notify the vendor that the given order had been placed in the shop application.
         * @throws RemoteException
         */
        void notifyAboutNewOrder(Order order);
        
        /**
         * Acknowledge that the order with the given ID has been received.
         */
        boolean isOrderNotificationReceived(long orderID);
}
The interface neither needs to extend the java.rmi.Remote interface, nor do methods need to declare RemoteExceptions. Any objects passed - like Order and its properties - need to implement Serializable.
The remote interface's implementation, RmiConnectorImpl, is trivial in this case.
The XML configuration, appContext-remotingServicesNonHTTP.xml, contains the following settings:
<bean class="org.springframework.remoting.rmi.RmiServiceExporter"
        p:serviceName="VendorRmiConnector" 
        p:serviceInterface="com.vendor1.erp1.RmiConnector"
        p:registryPort="1199">
        <property name="service">
                <bean class="com.vendor1.erp.rmi.RmiConnectorImpl"></bean>
        </property>
</bean>
Spring's RmiServiceExporter exposes the service based on the Remote interface serviceInterface, implemented by a service class, under the name of serviceName and the port of servicePort.

Client-side Configuration

At the client side, a Spring RmiProxyFactoryBean is used to create a proxy for the remote RMI service.
<bean id="vendorRmiConnector" 
        class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
        p:serviceUrl="rmi://localhost:1199/VendorRmiConnector"
        p:serviceInterface="com.vendor1.erp.rmi.RmiConnector" />

Standalone JAX-WS Web Service

The standalone JAX-WS web service in the sample appliction does not work with the Jetty appliction (used for testing) (while it does work with Tomcat). Due to related bugs it was extraordinary hard to debug this issue. Thus, an example for this type of web services is commented out in the sample application.
JAX-WS web services are successors to JAX-RPC web services.
Standalone JAX-WS web services run on the lightweight Java HTTP Server that comes with Java SE 1.6.
There are a number of alternatives, including JAX-RPC (i.e., using Apache Axis), JAX-WS RI, and XFire (now Apache CXF).

Server-side Configuration

Comparable to the RMI Remote interface, the remote interface is defined as follows:
@WebService(serviceName = "VendorJaxWsService")
@SOAPBinding(parameterStyle = ParameterStyle.BARE)
public interface JaxWsConnector {
        @WebMethod
        void notifyAboutNewOrder(Order order);

        @WebMethod
        boolean isOrderNotificationReceived(long orderID);
}
Spring's SimpleJaxWsServiceExporter will detect all beans annotated with @WebService, and all methods therein annotated with @WebService.
This article's author found it quite hard not to get a com.sun.xml.internal.ws.model.RuntimeModelerException ("runtime modeler error: Wrapper class com.vendor1.erp.jaxws.jaxws.IsOrderNotificationReceived is not found. Have you run APT to generate them?").
This error may occur if a) the web methods declare to throw any Throwable, or b) @SOAPBinding(parameterStyle = ParameterStyle.BARE) is missing (in contrast to ParameterStyle.WRAPPED, which is the default setting).
Theoretically, there might be a Maven APT plugin to generate the wrapper classes at compile time, however, the author didn't figure out how to apply it.
The interface's implementation class, like in the RMI sample, is trivial in this case.
The XML configuration, appContext-remotingServicesHTTP.xml, contains the following settings:
<bean id="jaxWsServiceExporter"
        class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"
        p:baseAddress="http://localhost:9999/" />

Client-side Configuration

At the client side, a Spring JaxWsPortProxyFactoryBean is used to create a proxy for the remote web service.
<bean id="vendorJaxWsConnector" 
        class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"
        depends-on="jaxWsServiceExporter"
        p:serviceInterface="com.vendor1.erp.jaxws.JaxWsConnector"
        p:wsdlDocumentUrl="http://localhost:9999/VendorJaxWsService?WSDL"
        p:namespaceUri="http://jaxws.erp.vendor1.com/"
        p:serviceName="VendorJaxWsService" 
        p:portName="JaxWebServiceEndpointPort" />
First-off, the depends-on (on the server bean) is needed as the server is not already started in the sample application (which contains, and starts, both client and server).
The wsdlDocumentUrl property composes from the server's / exporter's baseAdsress and the service name (set up in
@WebService(serviceName = "VendorJaxWsService")).
The namespaceUri property corresponds to the service interface's Java namespace, plus "javaws".
The serviceName property has already been mentioned. To the author it is not clear by which rules the portName property is generated into the WSDL file.
At development time it may be unclear which values are applicable for some of these properties. In succession, temporary exceptions will be thrown. Developers, using an IDE, can set a breakpoint at code points that are mentioned at the top of these exceptions' stack trace, and then point a web browser to the wsdlDocumentUrl property value. This should open the WSDL file, containing these values.

JAX-WS Web Service via Apache CXF

The Apache CXF framework supports a variety of services, including - used in the sample application - JAX-WS web services.

Server-side Configuration

In web.xml, Apache's CXFServlet is configured to listen under a given address:
<servlet>
        <servlet-name>jaxws</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
        <servlet-name>jaxws</servlet-name>
        <url-pattern>/jaxws/*</url-pattern>
</servlet-mapping>
In web.xml as well, a Spring XML configuration file is associated with Spring's central ContextLoaderListener:
<web-app>
        <context-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>
                        classpath:applicationContexts/vendor/appContext-remotingServicesHTTP.xml
                        ...
                </param-value>
        </context-param>
        ...

        <listener>
                <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        ...
</web-app>
In this Spring XML configuration file, our POJO (Plain Old Java Object) gets exposed as a JAX-WS endpoint:
<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" 
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        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-2.5.xsd
                http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

        <bean id="vendorJaxWsService" class="com.vendor1.erp.remoting.jaxws.JaxWsServiceImpl" />
        <jaxws:endpoint implementor="#vendorJaxWsService" address="/VendorService" />
</beans>

Client-side Configuration

At the client-side, a proxy is made available by the following XML configuration:
<jaxws:client id="vendorJaxWsConnector"
        serviceClass="com.vendor1.erp.remoting.jaxws.JaxWsService" 
        address="http://localhost:${ports.http}/springarticle/jaxws/VendorService" />
This Spring bean can now be dependency-injected into other beans:
@Resource(name = "vendorJaxWsConnector")
JaxWsService jaxWsConnector;

Hessian

Hessian is a binary protocol with transports via HTTP. APIs are provided for a wider range of languages.
There is an alternate, XML-based, remoting protocol named Burlap, which works for Java servers and clients, only. From a Spring point of view, configuration equals to a large degree.

Server-side configuration

First-off, the interface is quite similar to those used with the RMI and JAX-WS samples:
public interface HessianConnector {
        void notifyAboutNewOrder(long orderID);
        boolean isOrderNotificationReceived(long orderID);
}
Other than with RMI (and, like with JAX-WS), the interface does not have to extend another interface (Remote for RMI) and does not have to throw RemoteExceptions.
While in the other samples an Order had been serialized and remotely transported, in the sample application, a long primitive is passed, merely.
Serialization of more complex types won't work with Hessian out-of-the-box. As a workaround, one might want to write custom serializers. For an example see the blog entry, BigInteger and hessian. Using custom hessian Serializers with Spring.
When serialization fails with Hessian, a low-level (thus, hard to debug) Hessian HessianProtocol exception will be thrown (as always, wrapped into a Spring RemoteAccessException).
As with the other sample application's remoting samples, the interface's implementation is trivial, in this case.
In appContext-remotingServicesHTTP.xml, Spring's HessianServiceExporter creates a proxy of the service class, implementing its interface:
<bean id="hessianConnectorImpl" class="com.vendor1.erp.hessian.HessianConnectorImpl"></bean>

<bean name="hessianExporter"
        class="org.springframework.remoting.caucho.HessianServiceExporter"
        p:service-ref="hessianConnectorImpl" p:serviceInterface="com.vendor1.erp.hessian.HessianConnector" />
Finally, the servlet that makes up the front facade is being made available through the web.xml configuration, setting up a Spring HttpRequestHandlerServlet:
<servlet>
        <servlet-name>hessianExporter</servlet-name>
        <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>

<servlet-mapping>
        <servlet-name>hessianExporter</servlet-name>
        <url-pattern>/hessianExporter/HessianConnector</url-pattern>
</servlet-mapping>
The servlet name corresponds to the exporter's bean name.

Client-side configuration

At the client side, the proxied service is made available by a HessianProxyFactoryBean, using its interface (in appContext-remotingServicesHTTP.xml):
<bean id="vendorHessianConnector"
        class="org.springframework.remoting.caucho.HessianProxyFactoryBean"
        p:serviceUrl="http://localhost:8080/springarticle/hessianExporter/HessianConnector"
        p:serviceInterface="com.vendor1.erp.hessian.HessianConnector" />
The serviceUrl property corresponds to the server-side url-pattern property in web.xml.

Spring HTTP Invokers

Like Hessian, Spring HTTP invokers expose services through HTTP. Unlike Hessian however, HTTP invokers use the standard Java serialization mechanism, which allows for serialization of more complex objects than with Hessian.
In general, configuration settings equal those of Hessian.
The following sections will therefor outline the differences to the Hessian setup, only.

Server-side configuration

As Spring HTTP invokers use standard Java serialization, an Order object can be serialized. In contrast, in the Hessian sample, a long primitive had been passed:
public interface HttpInvokerService  {
        void notifyAboutNewOrder(Order order);
        boolean isOrderNotificationReceived(long orderID);
}
In appContext-remotingServicesHTTP.xml, Spring's HttpInvokerServiceExporter is used instead of the HessianServiceExporter.
Like in the Hessian sample, the bean is mapped to a servlet, and URL pattern in web.xml.

Client-side configuration

At the client side (in appContext-remotingClientsNonHTTP.xml), the proxied service is made available by a HttpInvokerProxyFactoryBean instead of a HessianProxyFactoryBean.

Java Message Service (JMS)

Java Message Service (JMS) is a form of loosely coupled distributed communication, where messages are not directly transferred from a message producer to a consumer, but to an intermediate Destination instead, which can be a Queue or a Topic. Messages usually are sent asynchronously, and it is possible to send replies to a repy-to Destination.
A (point-to-point) queue is a message reservoir where messages are consumed in the order sent (FIFO, first-in-first-out), and thereby removed from the queue.
A (publish-and-subscribe) topic, in contrast, is a message reservoir to which different consumers can subscribe.
Java EE application servers usually bring their own JMS provider. In this article's sample application, the Apache ActiveMQ framework is embedded.
There is much to say on JMS, and implementations may become fairly complex. This article only covers sending to and consuming from a Queue, as well as a sample reply to the original producer.

Consuming Messages

At the (ficticious) vendor's ERP system, a message consumer, or listener, is configured and implemented.
Involved are an ActiveMQ BrokerService (managing the transport layer's operations), an ActiveMQ ConnectionFactory implementation (connecting to configured queues or topics), and an ActiveMQ Queue implementation (containing the messages sent):
<amq:broker useJmx="false" persistent="false">
        <amq:transportConnectors>
                <amq:transportConnector uri="tcp://localhost:0" />
        </amq:transportConnectors>
</amq:broker>

<amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost" />

<amq:queue id="destinationQueue" physicalName="com.vendor1.erp.jms.Queue1" />
The ActiveMQ ConnectionFactory is wrapped by a Spring SingleConnectionFactory adapter that always returns the same connection. (There are alternatives.)
A Spring DefaultMessageListenerContainer references the aforementioned SingleConnectionFactory and Queue, as well as, finally, the sample application's MessageListener implementation:
<bean id="connectionFactory"
        class="org.springframework.jms.connection.SingleConnectionFactory"
        p:targetConnectionFactory-ref="jmsFactory" />

<bean id="vendor1JmsConsumer" class="com.vendor1.erp.jms.JmsConsumer" />

<bean id="jmsListenerContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="destinationQueue" />
        <property name="messageListener" ref="vendor1JmsConsumer" />
</bean>
The JmsConsumer is defined as follows:
public class JmsConsumer implements SessionAwareMessageListener {

        @Override
        public void onMessage(Message message, Session session) throws JMSException {
                Order order = (Order) ((ObjectMessage) message).getObject();

                if (message.getJMSReplyTo() != null) {
                        TextMessage replyToMessage = new ActiveMQTextMessage();
                        replyToMessage.setJMSCorrelationID(message.getJMSCorrelationID());
                        replyToMessage.setText("there needs to be some text");
                        
                        session.createProducer(message.getJMSReplyTo())
                                        .send(replyToMessage);
                }
        }
}
Implementing the SessionAwareMessageListener, defining the onMessage(Message, Session) method, allows for (consuming and) producing messages through the Session implementation passed.
At first in the onMessage(..) method, the Message object is cast to an ObjectMessage. Various Message implementations exist, including TextMessage, ByteMessage, and MapMessage.
The Message.getJMSReplyTo() method returns a Destination - if any - to send a reply to. A jMSCorrelationID is an application or provider specific string that, in the sample, is used to reference the original message. Finally, the Session is used to create a MessageProducer which sends a new TextMessage as a reply to the Destination that was passed with the original message.

Producing Messages

At the client side, a message producer is configured and implemented.
For the sake of simplicity, the sample refers to the ConnectionFactory set up in the server-side configuration.
The application's JmsVendorNotifier refers to a Spring JmsTemplate (which provides several convenience methods regarding producing and consuming messages, inspecting and converting messages, and accessing connections and sessions), as well as to the consumer's destination queue:
<import resource="../vendor/appContext-jms.xml"/>

<bean id="producerJmsTemplate" class="org.springframework.jms.core.JmsTemplate"
        p:connectionFactory-ref="connectionFactory" />

<bean id="vendorJmsProducer"
        class="com.acme.sample.businessfacade.interceptors.orderinserted.JmsVendorNotifier"
        p:destinationName="com.vendor1.erp.jms.Queue1" p:jmsTemplate-ref="producerJmsTemplate" />
A number of steps are involved to create a temporary Destination for the message's jMSReplyTo property:
Connection replyToConnection = jmsTemplate.getConnectionFactory().createConnection();
replyToConnection.start();
Session replyToSession = replyToConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
final Destination replyToDestination = replyToSession.createTemporaryQueue();
MessageConsumer replyToConsumer = replyToSession.createConsumer(replyToDestination);
replyToConsumer.setMessageListener(this);
Finally, a new ObjectMessage is created and sent within a callback object supplied to the JmsTemplate:
jmsTemplate.send(destinationName, new MessageCreator() {

        @Override
        public Message createMessage(Session session)
                        throws JMSException {
                ObjectMessage message = session.createObjectMessage(order);

                // prepare reply-to
                message.setJMSReplyTo(replyToDestination);
                message.setJMSCorrelationID("ID:" + String.valueOf(order.getId()));

                return message;
        }
});
Alternatively, a convenience method of the JmsTemplate can be used:
jmsTemplate.convertAndSend(order);
In the sample, the first message that has been sent has been provided with a reply-to Destination, a corresponding Connection has been started.
The message producer now itself implements the MessageListener interface, receiving reply-to messages in the onMessage(Message) method.

Exposing and Accessing EJBs

Spring supports accessing stateless session beans (SLSB) as well as resource injection into them.
Stateful session beans are not supported by Spring, probably because they have a lifecycle more difficult to implement.

Exposing EJBs

The sample application uses the OpenEJB framework which automatically scans the classpath for EJB and JPA annotations, including @Stateless on the Ejb3StatelessBeanService class in the sample application, and @Remote on its remote interface, which OpenEJB will expose.
The Ejb3StatelessBeanService SLSB in the sample application is also annotated by Spring's
@Interceptors(SpringBeanAutowiringInterceptor.class)
allowing for autowired resource injection into the SLSB.
Unfortunately, the Spring reference documentation does not mention a mandantory prerequisite for this to work: A ClassPathXmlApplicationContext needs to be defined in an XML configuration file used:
<bean class="org.springframework.context.support.ClassPathXmlApplicationContext" />
The default location of this file is classpath*:beanRefContext.xml.
The file's location could be changed by overwriting ...
public class MySpringBeanAutowiringInterceptor extends
                SpringBeanAutowiringInterceptor {

        @Override
        protected BeanFactoryLocator getBeanFactoryLocator(Object target) {
                return ContextSingletonBeanFactoryLocator
                                .getInstance("classpath:some/xmlConfigFile.xml");
        }
}
To the ClassPathXmlApplicationContext bean mentioned above, XML configuration file locations can be passed via an XML constructor-args element.

Accessing EJBs

In the sample application, a SimpleRemoteStatelessSessionProxyFactoryBean is used to look up the remote EJB via JNDI, retrieve it, and expose a proxy using its remote interface. The Spring jee namespace is used:
<jee:remote-slsb id="vendorEjb3SlsbConnector"
        cache-home="false" jndi-name="Ejb3StatelessBeanServiceRemote"
        business-interface="com.vendor1.erp.ejb3.Ejb3StatelessBeanServiceRemote">
        <jee:environment>
                java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory
        </jee:environment>
</jee:remote-slsb>
To access local SLSBs, a LocalStatelessSessionProxyFactoryBean would be used, expressed by the XML equivalent jee:local-slsb.
The default JNDI name (jndi-name XML attribute) is <Class Name>(Remote|Local) with OpenEJB.
Obviously, the business interface plays a central role, plus, one needs to specify from where to obtain an InitialContext.

Automated Testing

In general, there are different scopes of testing:
There are different supporting frameworks. At the base level, there are JUnit and TestNG testing frameworks. The Spring TestContext Framework can be run on either of both.
For Web GUI Testing, common frameworks are HttpUnit and JWebUnit. A popular Load Testing framework is The Grinder.

The JUnit Testing Framework

There is a number of ways to configure tests for JUnit. In this article's sample application, this is done via annotations.
Basically, there are test cases and test suites, where the latter may consist of multiple test cases. In the sample application, the AllTestsSuite class runs all test cases available:
@RunWith(Suite.class)
@SuiteClasses( { /* DAO tests: */BusinessUserDaoTest.class,
                CustomerDaoTest.class, OrderDaoTest.class, ProductDaoTest.class,
                UserDaoTest.class, VendorDaoTest.class, /* MVC tests: */
                AdminAddCustomerControllerTest.class, /* Transactions tests: */
                TransactionsTest.class, /* Integration tests: */InsertOrderTest.class,
                HttpLoginTest.class,
                /* Remoting tests (Non-HTTP) */RmiTest.class, Ejb3RemoteSlsbTest.class,
                /* JMS */
                JmsTest.class })
public class AllTestsSuite extends AbstractTests {
}
The @SuiteClasses annotation specifies the classes to be run when a class, AllTestsSuite here, annotated with @RunWith(Suite.class) is run.
In the test cases itself - for instance, in BusinessUserDaoTest - any methods annotated by @Test are executed:
@Test
public void testGetCandidatesForLoginInt() {
        List<BusinessUserWrapper> loginCandidates = businessUserDAO
                        .getCandidatesForLogin(user.getId());

        assertEquals(0, loginCandidates.get(loginCandidates.size() - 1)
                        .getSpringSecurityID());
        assertNotNull(loginCandidates.get(0).getName());
        assertTrue(loginCandidates.get(0).getId() > 0);
}
The org.junit.Assert class provides a large number of assertXXX(..) methods that evaluate conditions to test. If a condition cannot be met, these methods delegate to the fail(..) method, which in turn throws an AssertionError, which will cause this specific test to fail.
Before and after tests are run, additional code can be executed, i.e., establishing or closing a database connection. In those sample application's test cases that test HTTP-based services, an embedded web server is started before the tests run and stopped thereafter:
public class AbstractWebServerTests extends AbstractTests {
        ...

        @Before
        public void startWebServer() {
                ...
                webappRunner.start();
                ...
        }

        @After
        public void stopWebServer() {
                ...
                webappRunner.stop();
                ...
        }
}
Analogously to the @Before and @After annotations on instance methods, there are the @BeforeClass and @AfterClass annotations, to be used with static methods.

Spring Testing Support

Support for automated testing in Spring can be grouped into the following domains:
Out of the box, there is support for the JUnit 3.8, JUnit 4.4, and TestNG frameworks.

Spring TestContext Framework

All test cases in the sample application either extend Spring's AbstractJUnit4SpringContextTests or AbstractTransactionalJUnit4SpringContextTests convenience classes.
Both create an ApplicationContext based on the file locations specified in the @ContextConfiguration annotation, ie.,
@ContextConfiguration(locations = {
        "classpath:applicationContexts/backend/appContext-dataSource.xml",
        "classpath:applicationContexts/backend/appContext-dataAccessObjects.xml"})
public abstract class AbstractDaoTests extends AbstractTransactionalJUnit4SpringContextTests { ...
The AbstractxxxSpringContextTests delegate to the underlying base testing framework (i.e, JUnit), and set up a number of TestExecutionListeners, including a DependencyInjectionTestExecutionListener. The AbstractTransactionalJUnit4SpringContextTests class additionally sets up a TransactionalTestExecutionListener, that processes annotations related to transactional behavior, as well as simple JDBC support. It requires a DataSource to be present in the application context loaded, as well as a PlatformTransactionManager (which name must be "transactionManager").
For each test case, Spring instantiates a TestContextManager, which holds a TestContext, which, in turn, loads an application context by looking at the @ContextConfiguration annotation at the type level. The application context will be cached and re-used for any tests.

AbstractTransactionalxxxSpringContextTests

Spring's AbstractTransactionalxxxSpringContextTests (for each supported testing framework, i.e., AbstractTransactionalJUnit4SpringContextTests) add transactional behavior to each test. By default, data changes will be rolled back, automatically.
These classes provide access to a SimpleJdbcTemplate instance, as well as offering some JDBC convenience methods. The sample application's AbstractDaoTests class, from which all DAO Tests inherit, tests the transactional functionality by using Spring's convenience method countRowsInTable(String):
int[] rowCounts = new int[7];

String[] tableNames = { "authorities", "business_users", "line_items",
                "orders", "products", "users", "vendors_products" };

@BeforeTransaction
public void countTableRowsBeforeTransaction() {
        for (int i = 0; i < rowCounts.length; i++) {
                rowCounts[i] = countRowsInTable(tableNames[i]);
        }
}

@AfterTransaction
public void countTableRowsAfterTransaction() {
        for (int i = 0; i < rowCounts.length; i++) {
                assertEquals("Transaction didn't rollback with table "
                                + tableNames[i], rowCounts[i],
                                countRowsInTable(tableNames[i]));
        }
}
Methods annotated with @BeforeTransaction will be executed before transactions, methods annotated with @AfterTransaction thereafter.
Related annotations include @NotTransactional to indicate that a test method is not transactional, and @Rollback, which takes a boolean value to indicate whether to rollback (which is the default) the transaction or not.
By default, transactions in test contexts behave like with a @Transactional annotation having default values.

Common Annotations

It has been mentioned that application contexts are cached per TestContext (test case class). The @DirtiesContext annotation indicates that a method may change an application context, and causes Spring to rebuild it for subsequent tests.
The @ExpectedException annotation indicates that a test is supposed to throw the exception type specified.
Tests can be executed conditionally, using the @IfProfileValue annotation along with a @ProfileValueSourceConfiguration annotation, pointing to a custom implementation of the ProfileValueSource interface.
Tests can be executed @Repeatedly and @Timed, indicating that the test has failed when its execution time exceeds the specified duration.

Tests in the Sample Application

All tests in the sample application either inherit from AbstractTransactionalTests (extending Spring's AbstractTransactionalJUnit4SpringContextTests) or AbstractNonTransactionalTests (extending Spring's AbstractJUnit4SpringContextTests). Tests that need to start a web server extend AbstractWebServerTests.
The AllTestsSuite class (see chapter Running the Tests) runs all tests.
Other than in a real life scenario, the tests use the "production" settings, including the database.

Excursus: Embedding the Jetty HTTP Server

Vast parts of the sample application - including the MVC/GUI parts and a number of remoting services - are to be accessed via the HTTP protocol, and to be served by a web or application server. In order to allow for automated testing, the application needs to be deployed to such a server, and the server needs to be started.
One way to accomplish this would be to set up an appropriate Maven goal.
In the sample application, however, the Jetty HTTP server and servlet container is embedded, and started (and stopped) during tests. Jetty is started and stopped by the following code:
public class JettyUtils {
        public static Server startServer(Properties serverProps) throws Exception {
                Server server = new Server(Integer.parseInt((String) serverProps
                                .get("port")));
                WebAppContext context = new WebAppContext((String) serverProps
                                .get("webappContextPath"), (String) serverProps
                                .get("webappPartialURL"));
                context.setClassLoader(ClassLoader.getSystemClassLoader());
                server.addHandler(context);
                server.start();

                return server;
        }

        public static void stopServer(Server server) throws Exception {
                if (server != null && !server.isFailed() && !server.isStopped()
                                && !server.isStopping()) {
                        server.stop();
                }
                else {
                        throw new IllegalStateException();
                }
        }
}
To the WebAppContext, the context path is passed (the path to a WAR file or exploded WAR directory), as well as a partial URL (i.e., http://localhost:8080/springarticle).
Alternatively, Jetty can be configured to run as a Spring managed bean, in Spring XML configuration. The blog article Embedding Jetty 6 in Spring provides a sample.

Running the Tests

The tests can either be started using Maven at the command line, or by using the Eclipse GUI.
Several tests start an embedded web server (see chapter Excursus: Embedding the Jetty HTTP Server). Edit src/test/resources/testing-jetty.properties to configure the server. Before tests can be run that start that embedded web server, the application needs to be "deployed", i.e., by executing the following command in a shell:
mvn package -Dmaven.test.skip=true
This will create a WAR file in the target directory.
After that, tests can be run using the command line, again:
mvn test
This will run all tests within classes that are named **/Test*.java, **/*Test.java, or **/*TestCase.java.
To run a specific test, pass the fully qualified class name, i.e.:
mvn test -Dtest=com.acme.sample.test.remoting.http.JaxWsTest
Alternatively to running the tests using the command line, Eclipse can be used: Right-click on the file to test (AllTestsSuite for all tests available) and select Run as —> JUnit Test.

DAO Tests

These tests, located in the com.acme.sample.test.dao package, are transactional (see chapter AbstractTransactionalxxxSpringContextTests).
The generic, abstract, class AbstractAbstractNameableDaoTests<T extends AbstractNameable>, from which most test classes inherit, contains common functionality. There is the convenience AllDaoTestsSuite class that runs all DAO tests.

Remoting Tests

These test the application's remote services (see chapter Integration).
Those tests that test HTTP based remoting services extend AbstractWebServerTests and, thereby, start an embedded web server (see chapter Excursus: Embedding the Jetty HTTP Server).

AOP Tests

The TransactionsTest test case uses several methods of Spring's AopUtils class - isAopProxy(..), isJdkDynamicProxy(..) and canApply(..) - to test whether an AOP transactional advice (see chapter tx:advice XML Configuration) is in place.
This doesn't reach to the method level, though. There are also no tests for functionality.

Integrational Tests

Testing HTML Forms

To test the functionality in login.jsp, the web application is served by the embedded web server (see chapter Excursus: Embedding the Jetty HTTP Server). The HttpUnit framework is used to simulate a user filling in HTML form fields, and submitting the form:
WebConversation conversation = new WebConversation();
WebRequest request = new GetMethodWebRequest(
                "http://localhost:" + serverProps.getProperty("port")
                                + "/springarticle");

WebResponse response = conversation.getResponse(request);
WebForm loginForm = response.getForms()[0];
request = loginForm.getRequest();

request.setParameter("j_username", userName);
request.setParameter("j_password", password);

response = conversation.getResponse(request);

assertTrue("Login for " + userName + "/" + password
                + " not successful.", response.getText().indexOf(
                "Main Page") > -1);

Testing a MVC Controller

In the sample application (in package com.acme.sample.test.mvc), there is only one, demonstrational, test case, which tests the AdminAddCustomerController MVC controller.
In the @Before method, a Spring-managed instance of this controller is obtained by querying the ApplicationContext AbstractJUnit4SpringContextTests provides:
@Before
public void setUp() {
        this.controller = (AdminAddCustomer) applicationContext
        .getBean("adminAddCustomerController");
}
The managed bean could also be retrieved by using the @Autowired annotation.
That way (not creating the instance with the new keyword), the bean is managed by Spring, as well as its dependencies (e.g., autowired or otherwise dependency-injected instance fields).
As the MVC controller needs a HttpServletRequest (it might need a HttpServletResponse and HttpSession, too), the request object needs to be replaced by a mock object for testing purposes:
@Test
public void testFormBackingObjectHttpServletRequest() {
        MockHttpServletRequest request = new MockHttpServletRequest();
        try {
                assertEquals(new Customer(), controller.formBackingObject(request));
        }
        catch (Exception e) {
                fail(e.toString());
        }
}
The controllers validation can be tested by providing a BindException instance:
@Test
public void testOnBindAndValidateHttpServletRequestObjectBindException() {
        MockHttpServletRequest request = new MockHttpServletRequest();
        Object command = new Customer();
        BindException errors = new BindException(command, "customer");

        // validate a Customer with an empty name
        try {
                controller.onBindAndValidate(request, command, errors);
        }
        catch (Exception e) {
                fail(e.toString());
        }

        assertEquals(1, errors.getAllErrors().size());

        // validate a valid Customer
        errors = new BindException(command, "customer");
        ((Customer) command).setName(StringUtils.getRandomString());
        try {
                controller.onBindAndValidate(request, command, errors);
        }
        catch (Exception e) {
                fail(e.toString());
        }

        assertEquals(0, errors.getAllErrors().size());
}
Finally, the controller's submit action gets invoked:
@Test
public void testDoSubmitActionObject() {
        Customer customer = new Customer();
        customer.setName(StringUtils.getRandomString());

        try {
                controller.doSubmitAction(customer);
                        
                Customer savedCustomer = customerDAO.get(customer.getId());
                assertEquals(customer, savedCustomer);
        }
        catch (Exception e) {
                fail(e.toString());
        }
}
Under the hood, the application's service layer is used to perform the action, which is secured by ...
@RolesAllowed( { "ROLE_ADMINISTRATOR" })
public interface AdminFacade {
        ...
However, this annotation does not get interpreted as Spring - with the test case - is not configured to do so:
<global-method-security jsr250-annotations="enabled"
        secured-annotations="enabled" />
... is missing in the configuration files passed to the ApplicationContext that runs the tests (see chapter Authorization).
Spring's ModelAndViewAssert convenience class contains several methods to test for the validity of a controller's ModelAndView:
ModelAndView mav = controller.handleRequest(request, response);

ModelAndViewAssert.assertAndReturnModelAttributeOfType(mav,
                "customer", Customer.class);
ModelAndViewAssert.assertAndReturnModelAttributeOfType(mav,
                "supportedLocales", Map.class);

ModelAndViewAssert.assertModelAttributeAvailable(mav, "customer");

ModelAndViewAssert.assertModelAttributeValue(mav, "customer",
                new Customer());

ModelAndViewAssert.assertViewName(mav, "adminAddCustomer");

Testing the "Insert Order" Use Case

From a testing point of view, there is nothing special with this test. However, it covers a larger number of secondary use cases, along with their functionalities.
See the chapters Use Cases: Customers and Notify Vendor on Order Placement for more information on that use case.

Patterns in Spring

Architectural Patterns

Dependency Injection Pattern

Problem

Classes, resp., components, should be loosely coupled in order to faciliate substitution (i.e., substituting the data access layer for testing purposes, externalize service layers, change presentation layer components, etc.).

Solution

Spring provides a Dependency Injection (DI) container that injects concrete instances into classes managed by Spring. Ideally, the latter classes refer to their dependencies by specifying interfaces instead of implementation classes. In Spring, there is constructor, field, setter, and method argument injection.
While DI can be configured by Java 5 annotations in Spring, it can also be configured by XML configuration files. In case of using configuration files, implementation details can be substituted without recompiling.
Dependency Injection is a sub-form of the Inversion of Control (IoC) Pattern, which, in terms of Design Patterns, can also be implemented by the Factory Pattern, the Observer and Visitor Patterns, callback functions or any type of plug-ins.
See chapter Dependency Injection for more implementation details.

Model-View-Controller (MVC) Pattern

The MVC pattern may be regarded an architectural as well as a design pattern.

Problem

In rather loosely structured applications, data access code, business logic code, and presentation code may be mixed. Such applications are difficult to maintain and test as concerns are highly coupled. Modifications of either layer will affect the others.
Applications may have different, even multiple, presentation layers, i.e., web (i.e., Java Server Faces with or without AJAX support) or rich client (i.e., Swing or SWT) client GUIs. The presentation layer should be exchangeable, without affecting the business logic.
Data access code, and the resulting data structures, may be used by multiple presentation layers across an application. Data access code should be reusable.

Solution

The MVC (Model-View-Controller) pattern separates concerns into model, view, and controller:
The model represents the domain-specific information on which the application operates (domain model). This may be the result of a database query for a specific list of customers. Submodels may be combined, that is, a model may contain different types of data.
A model may also contain application or session state (application model), i.e., the display language a user has selected for the presentation layer.
Generally, the model contains (at least) any variable data to be rendered in a view of the presentation layer.
The model in Spring is a Map containing arbitrary types of objects.
 
The view renders the contents of the model, typically into a GUI (graphical user interface), and possibly offers user interaction facilities (like input or selection). By default, Spring MVC provides views for web pages, Excel and PDF documents, and others. These extend the AbstractView class.
 
The controller processes and responds to events that typically arise from user interactions (like clicking a link or posting a form).
The controller may validate and interpret user interactions, and update the model.
Controllers in Spring MVC implement the Controller interface (and typically extend the AbstractController class), and their handleRequest(..) method returns a ModelAndView instance.
The model the controller returns may consist of the complete data the controller acquired for a specific request, or just a subset. It is called command object.
 
BTW, the model and the view objects may compose of one or more sub objects, implementing the Composite Pattern. Model and view issue commands to each other (i.e., a view to a model, when posting a form) (Command Pattern). As model and view don't know about each other, these commands can be seen as adapters, according to the Adapter Pattern (also see chapter Exporter Pattern).
 
Based on HandlerMappings, Spring's central DispatcherServlet decides which handler object to execute - typically, a controller.
Further information is available in chapter Spring MVC.

Design Patterns

Commonly, design patterns are described by their context, the underlying problem, and the resulting solution, and pattern, finally. This article abstains from following this more comprehensive methodology.

Creational Design Patterns

Factory Pattern

The Factory Pattern slightly differs from the Abstract Factory Pattern and the Method Factory Pattern, which are not discussed at this place.
Problem
The creation of an object may require additional processes to be involved rather than mere instantiation. There may be the need to determine which object - also, object of which type - actually to instantiate, in which scope to instantiate it (see the chapters Singleton Pattern and Bean Scopes), to configure it, i.e., provide it with its dependencies, etc.
If the code necessary to create an object instance exceeds a certain amount (and thus would lead to duplicate code within an application), or if the type of the object to be created may vary, instantiation code should be centralized into a factory.
Solution
A factory defines one or more methods for other classes to obtain an instance of the target object.
The root interface for accessing a Spring bean container is BeanFactory (one of its implementations is ClassPathXmlApplicationContext), with their (overloaded) method Object getBean(..). Analogously, Spring AOP ProxyFactory instances - implementing AopProxy - analogously define a method Object getProxy().

Singleton Pattern

Problem
An application needs to make sure that only one instance of a class exists, which is globally accessible. This way the application can hold global state, i.e., user settings.
Solution
In a normal Java application, the following code would ensure that there is at most one instance of UserSettings per classloader:
public class UserSettings {
        private static UserSettings userSettings;

        private UserSettings() {}

        public static UserSettings getInstance() {
                if (userSettings == null) {
                        userSettings = new UserSettings();
                }
                return userSettings;
        }

        public Locale getLocale() {
                ...
        }
}
It is quite important to realize that Spring beans' singleton pattern, resp., scope, fundamentally differs from the Singleton Pattern the GoF (Gang of Four) described.
Firstly, Spring beans are typically not meant to maintain state that is specific to a client. Rather, they act as services, where all necessary parameters are passed to the methods being executed.
Furthermore, in contrast to the "traditional" Singleton approach, only one bean instance exists per application context, not per classloader.
It is possible to define Spring beans in other scopes than singleton. With prototype-scoped beans, a new instance is created for every BeanFactory.getBean(..) call. Additional, pre-defined, scopes include the HTTP request scope. See chapter Bean Scopes for a discussion.

Structural Design Patterns

Exporter Pattern

Problem
An object needs to be exposed to an API (or infrastructure) that requires a specific interface to be implemented, or a specific class to be inherited from. The object, however, does not fulfill that contract because it needs to be independant from that target infrastructure, or because the Java language does not support multiple inheritance.
For instance, an object shall be made available remotely via RMI. However, it does not implement the necessary Remote interface, and does not throw RemoteExceptions.
Solution
An exporter locates and wraps the target object, delegates to it, and provides the target infrastructure with an object that fulfills the required contract.
The Adapter Pattern is quite similar in structure, however, it usually implements the delegating functionality more hard-coded. - A Spring exporter normally just needs to be configured:
<bean id="rmiServiceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter"
        p:serviceName="VendorRmiConnector" p:serviceInterface="com.vendor1.erp.remoting.rmi.RmiService"
        p:registryPort="1199">
        <property name="service">
                <bean class="com.vendor1.erp.remoting.rmi.RmiServiceImpl"></bean>
        </property>
</bean>
That way arbitrary Spring beans can be exported to all Remoting infrastructures Spring supports by mere configuration.

Proxy Pattern

Problem
A target object is to be accessed but, for various possible reasons, it shall not be accessed directly.
For example, the target object exists in a remote system, and additional code is required to obtain an instance of it, while it is desirable to treat it as any other local object. Other reasons include the need to perform additional security checks, or to cache one or more instances of the target object, etc.
Solution
A proxy object implements the target object's interface, delegates to the target object, may perform additional actions, and can be accessed in place of the target object.
In Spring, for example, an RmiProxyFactoryBean is used to create a proxy for a remote object:
<bean id="vendorRmiConnector" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
        p:serviceUrl="rmi://localhost:1199/VendorRmiConnector"
        p:serviceInterface="com.vendor1.erp.remoting.rmi.RmiService" />
The above statements, such as, the proxy delegates to the target object, are simplyfied: Actually, the factory bean performs the delegation and additional work.

Data Access Object (DAO) Pattern

Problem
Persistent data - typically modeled in object-orientated entities (entity beans, domain objects) - needs to be accessed and manipulated.
If, however, these portions of code are mixed with other logic (i.e., business logic), the separation of concerns principle gets violated: Maintainability decreases, changing the underlying data access technology becomes difficult, and testing the business logic independently of the persistence layer becomes complicated.
Data access code should be encapsulated and interchangeable.
Solution
For each domain object, there is a DAO (Data Access Object) that contains code to access and manipulate the data, but hides the persistence technology it is using.
There is a challenge with object networks (when a domain object refers to one or more other, related, objects). Depending on a number of factors, eager fetching or lazy fetching may be preferrable.
In this article's sample application, the DAOs reside in the com.acme.sample.dao.impl.hibernate and com.acme.sample.dao.impl.jdbc packages.

Decorator Pattern

Problem
An existing class' functionality shall be extended without modifying it.
Solution
In Spring AOP, proxies (so-called advices) add functionality to proxied classes and delegate calls to them while implementing their interfaces.
In basic Java programming, the decorating functionality is often achieved by passing the target object as a constructor argument, i.e.:
public GZIPOutputStream(OutputStream out) .. { ...

Exception Translator Pattern

Problem
Instead of "reinventing the wheel", the Spring framework commonly uses other, existing, frameworks. In instance, it wraps a number of data access frameworks, under a unified API.
All of these frameworks used throw their own exception types. Thus, different types of exceptions may be thrown for the same cause by different frameworks. In part, the exceptions' causes are not even reflected by their type, but hidden in the exceptions' messages.
The exception hierarchy of different frameworks should be unified.
Moreover, often checked exceptions are thrown. Checked exceptions need to be excplicitely handled in code. On the other hand, many exceptions - for example, most data access exceptions - are fatal, which means, they cannot be recovered, anyways. The - mandantory - handling of such exceptions is tedious and unnecessary work for programmers.
Fatal exceptions should be unchecked (derive from the RuntimeException type).
Solution
Spring translates exceptions thrown by underlying frameworks into its own, unified, exception hierarchy. Examples are DataAccessException and TransactionException and their subclasses.
These, translated, exceptions are unchecked: They do not need to be handled but, of course, they can be if that is useful.
Spring's DataAccessException hierarchy is illustrated by the following image:
DataAccessException Hierarchy

Behavioral Design Patterns

Listener Pattern

The Listener Pattern is close-by related to the Observer Pattern, which is not discussed in this article. See a Sun Java Tech Tip for more information.
Problem
One or more objects need to be notified on certain events of a target object.
Solution
EventListeners implement a specific interface, which defines one or more methods, in which EventObjects are passed. These event objects may contain information on the state of the target object, or even a reference to it, so they can access or manipulate it.
The event listeners register (possibly also unregister) with the target object, they subscribe to be notified.
The target object provides methods to register (add) and unregister (remove) listeners that implement the aforementioned specific interface. When appropriate, it calls the aforementioned interface methods on any registered listener (it thereby publishes an event).
Spring's AbstractApplicationContext contains the method addListener(ApplicationListener) to allow a listener to be subscribed. The ApplicationListener interface defines the method onApplicationEvent(ApplicationEvent), which the AbstractApplicationContext (indirectly, in this case) calls on any registered ApplicationListener.
An ApplicationListener implementation is Spring's central DispatcherServlet (with its superclass FrameworkServlet implementing the onApplicationEvent(ApplicationEvent) method. If the ApplicationEvent is of type ContextRefreshedEvent (which means, all beans have been configured), the DispatcherServlet will initialize its Strategy objects, including bean handler mappings and view resolvers.

Strategy Pattern

Problem
Depending on a context, alternative algorithms shall be used for the same task.
Solution
The tasks are encapsulated in classes which all implement the same, strategy, interface. The context application instantiates a strategy implementation, possibly, based on configuration.
In Spring, Scope is such a strategy interface. Depending on the implementation used, different rules apply regarding the decision on whether to create a new bean or reuse an existing instance.
In the sample application, the DAO interfaces (in package com.acme.sample.dao) are implemented by Hibernate and JDBC implementations. Implementations that were using other frameworks could be added and interchanged by merely changing the bean configuration.

Template Pattern

Problem
In commonly used operations there are amounts of variant and invariant code.
Specifically, APIs are used that require external resources that need to be freed after operating on them completes (whether successfully or unsuccessfully).
For example, with JDBC, all, the ResultSet, the Statement, and the Connection must be closed. Error handling, in this case, can be tedious and error-prone.
Resource handling, as well as other common operations, should be externalized to a central place.
Solution
Template objects take care of handling resources. The code that needs those resources gets passed to the template. Usually, the template defines an interface that the code must implement. The template then provides the resources to the code, executes the code, and finally frees the resources.
Instead of implementing an interface, such code can be passed to the template as an anonymous inner class - a callback object. This inner class has access to the template's instance variables, if needed.
In the following example, an anonymous RowMapper is passed to the JdbcTemplate:
return (List<BusinessUserWrapper>) this.jdbcTemplate.query(query, new Object[] { loginID }, 
        
        new RowMapper() {

                @Override
                public BusinessUserWrapper mapRow(ResultSet rs, int rowNum)
                        throws SQLException {
                        BusinessUserWrapper user = new BusinessUserWrapper();
                        user.setId(rs.getInt("id"));
                        user.setName(rs.getString("name"));
                        user.setSpringSecurityID(rs.getInt("user_id"));

                        return user;
                }
        }
);
Additionally, a template object is a good place to handle and translate exceptions (see chapter Exception Translator Pattern).
Templates may also provide convenience methods for commonly used operations, for example, there are several overloaded query(..) methods defined in the JdbcTemplate type.

Resources

All links retrieved at the date of publishing.

Spring Framework (Core)

Spring Integration (Remoting, etc.)

Spring Framework (Other)

Hibernate ORM

Testing

Design Patterns

Other Resources

Valid XHTML 1.0 Transitional Valid CSS!