In this post we are going to have a little fun with Spring. We show how dependency injection works, how to provide aspects to beans, see how to integrate Hibernate, how to obtain resources such as data sources, JMS connection factories and JMS queues from JNDI, how to create message-driven pojos, how to use commonj WorkManagers on which the thread model of WebLogic is based such that Spring does not spawn unmanaged threads, and if that was not enough see how to use Spring MVC. How good can it get, I love this stuff, hope you do too!

What is Spring?

Spring is a container/framework for dependence injection and aspect oriented programming (AOP), i.e.,

  • Dependency injection – objects get their dependencies in a passive manner, instead of creating objects by hand.
  • Aspect oriented – cohesive development by separating application logic from system services, such as transactions.
  • Container – contains and manages the lifecycle and configuration of the application objects.
  • Framework – configure and compose complex applications by using simple components.

Dependency injection

In a Spring-based application, the objects live in the Spring container. The container creates the objects, wires the objects, configures the objects and manages the objects lifecycle. Two Spring containers are available:

  • Bean factories (BeanFactory provide the basis for dependency injection.
  • Application contexts (ApplicationContext built upon bean factories by providing application services.

The following gives an example of how bean wiring (creating assocations between application components) works:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>model/entities/Department.hbm.xml</value>
                <value>model/entities/Employee.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.current_session_context_class">${hibernate.current_session_context_class}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
            </props>
        </property>
    </bean>
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="jdbc/exampleDS"/>
        <property name="resourceRef" value="true"/>
    </bean>
</beans>

Note that in the example above properties are referenced by using ${hibernate.dialect}, in order for this to work we need to add the following bean:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="locations">
		<list>
			<value>classpath:spring.properties</value>
		</list>
	</property>
</bean>

in which spring.properties is a custom file that is placed in the root of the classpath. This information is provided to Spring by using classpath:. Note that the properties file is nothing more than a basic key/value pair file, i.e.,

hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.current_session_context_class=thread
hibernate.show_sql=false
hibernate.format_sql=false

As we are talking about properties. When configuring we sometimes run into the issue that we need to configure a bean that contains a java.util.Date. By default, we can configure bean properties by using basic Java objects, such as Strings. To be able to set properties of type java.util.Date as a String we have to configure the following:

<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
	<property name="customEditors">
		<map>
			<entry key="java.util.Date" value-ref="customDateEditor"/>
		</map>
	</property>
</bean>
<bean id="customDateEditor" class="org.springframework.beans.propertyeditors.CustomDateEditor">
	<constructor-arg ref="simpleDateFormat"/>
	<constructor-arg value="false"/>
</bean>
<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
	<constructor-arg value="dd-MM-yyyy"/>
</bean>

Spring now automatically converts a String to a Date object. Note that this is not handled by Spring itself but by a JavaBeans API feature. The interface PropertyEditor provides the possibility to map String values to other types. A handy implementation of the PropertyEditor interface is PropertyEditorSupport that contains two useful methods:

  • getAsText – gets the property value as a String.
  • setAsText(String value) – sets the property value by parsing a given String.

When we try to map a String value to another type, the setAsText method is called to execute the conversion. Spring provides a couple of editors which are based on PropertyEditorSupport, such as CustomDateEditor(DateFormat dateFormat, boolean allowEmpty). This class is used to convert a String to a Date and vice versa. The CustomEditorConfigurer is a so-called BeanFactoryPostProcessor which load editors in the BeanFactory by calling the registerCustomEditor method.

Aspect oriented programming

Systems typically consist of a number of components that are each responsible for a specific piece of functionality. These components usually use some kind of system service, such as transactions. System services are used by multiple components. Now we could duplicate code into each of the components that use system services or we could configure it and Spring handle it. Of course we are going for the latter option as we do not want our code to be obfuscated by code that is not part of the core functionality.

It may help to think of aspects as blankets that cover many components of an application. At its core, an application consists of modules that implement business functionality. With AOP, we can cover the core application with layers of functionality. These layers can be applied declarative throughout the application in a manner without the core application even knowing they exist. This is a powerful concept, as it keeps the transaction (and, for example, security) concerns from littering the application’s core business logic.

Aspects help to modularize cross-cutting concerns. In short, a cross-cutting concern can be described as any functionality that affects multiple points of an application. Security, for example, is a cross-cutting concern in that many methods in an application can have security rules applied to them. A common object-oriented technique for reusing common functionality is to apply inheritance or delegation. But inheritance can lead to a brittle object hierarchy if the same base class is used throughout an application, and delegation can be cumbersome because complicated calls to the delegate object may be required. Aspects offer an alternative to inheritance and delegation that can be cleaner in many circumstances. With AOP, we still define the common functionality in one place, but we can declarative define how and where this functionality is applied without having to modify the class to which we are applying the new feature. Cross-cutting concerns can now be modularized into special objects called aspects. This has two benefits:

  • First, the logic for each concern is now in one place, as opposed to being scattered all over the code base.
  • Second, our service modules are now cleaner since they only contain code for their primary concern (or core functionality) and secondary concerns have been moved to aspects.

Aspects are often described in terms of advice, pointcuts, and joinpoints. Aspects have a purpose – a job that they are meant to do. In AOP terms, the job of an aspect is called advice. Advice defines both the what and the when of an aspect. In addition to describing the job that an aspect will perform, advice addresses the question of when to perform the job. Should it be applied before a method is invoked? After the method is invoked? Both before and after method invocation? Or should it only be applied if a method throws an exception?

An application has opportunities for an advice to be applied. These opportunities are known as joinpoints. A joinpoint is a point in the execution of the application where an aspect can be plugged in. This point could be a method being called, an exception being thrown, or a field being modified. These are the points where the aspect’s code can be inserted into the normal flow of the application to add new behavior.

An aspect does not necessarily advise all joinpoints in an application. Pointcuts help narrow down the joinpoints advised by an aspect. If an advice defines the what and when of aspects then pointcuts define the where. A pointcut definition matches one or more joinpoints at which advice should be woven. Often we specify these pointcuts using explicit class and method names or through regular expressions that define matching class and method name patterns.

An aspect is the merger of advice and pointcuts. Taken together, advice and pointcuts define everything there is to know about an aspect – what it does and where and when it does it. Spring employs AOP to provide enterprise services such as declarative transactions. Transactions allow us to group several operations into a single unit of work that either fully happens or fully does not happen. When writing to a database, we must ensure that the integrity of the data is maintained by performing the updates within a transaction.

A transaction can be described by the acronym ACID. In short, ACID stands for:

  • Atomic – Transactions are made up of one or more activities bundled together as a single unit of work. Atomicity ensures that all the operations in the transaction happen or that none of them happen. If all the activities succeed, the transaction is a success. If any of the activities fail, the entire transaction fails and is rolled back.
  • Consistent – Once a transaction ends, the system is left in a state that is consistent with the business that it models. The data should not be corrupted with respect to reality.
  • Isolated – Transactions should allow multiple users to work with the same data, without each user’s work getting tangled up with the others. Therefore, transactions should be isolated from each other, preventing concurrent reads and writes to the same data from occurring. (Note that isolation typically involves locking rows and/or tables in a database.)
  • Durable – Once the transaction has completed, the results of the transaction should be made permanent so that they will survive any sort of system crash. This typically involves storing the results in a database or some other form of persistent storage.

Spring provides support for both programmatic and declarative transaction management support. While programmatic transaction management affords flexibility in precisely defining transaction boundaries in the code, declarative transactions help to decouple an operation from its transaction rules. Choosing between programmatic and declarative transaction management is largely a decision of fine-grained control versus convenience. Spring does not directly manage transactions. Instead, it comes with a selection of transaction managers that delegate responsibility for transaction management to a platform-specific transaction implementation provided by either JTA or the persistence mechanism. To use a transaction manager, we must declare it in the application context, for example,

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
	<property name="sessionFactory" ref="sessionFactory"/>
</bean>

Spring’s support for declarative transaction management is implemented through Spring’s AOP framework. A Spring transaction is sort of an aspect that ‘wraps’ a method with transactional boundaries. In Spring, declarative transactions are defined with transaction attributes. A transaction attribute is a description of how transaction policies should be applied to a method. To declare transactions we must set five parameters, which govern how transaction policies are administered:

  • Propagation behavior – Defines the boundaries of the transaction with respect to the client and to the method being called.
  • Isolation level – Defines how much a transaction may be impacted by the activities of other concurrent transactions. Realizing that perfect isolation can impact performance and because not all applications will require perfect isolation, sometimes it is desirable to be flexible with regard to transaction isolation.
  • Read-only – If a transaction performs only read operations against the underlying data store, the data store may be able to apply certain optimizations that take advantage of the read-only nature of the transaction. By declaring a transaction as read-only, we give the underlying data store the opportunity to apply those optimizations as it sees fit.
  • Transaction timeout – For an application to perform well, its transactions can not carry on for a long time. Suppose that the transaction becomes unexpectedly long-running. Because transactions may involve locks on the underlying data store, long-running transactions can tie up database resources unnecessarily. Instead of waiting it out, we can declare a transaction to automatically roll back after a certain number of seconds.
  • Rollback rules – A set of rules that define what exceptions prompt a rollback and which ones do not. By default, transactions are rolled back only on runtime exceptions and not on checked exceptions. However, we can declare that a transaction be rolled back on specific checked exceptions as well as runtime exceptions. Likewise, we can declare that a transaction not roll back on specified exceptions, even if those exceptions are runtime exceptions.

Declarative transaction management is accomplished by proxying classes with Spring’s TransactionProxyFactoryBean, for example,

<bean id="departmentDAOTarget" class="model.logic.DepartmentDAOBean">
	<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
<bean id="departmentDAO" parent="transactionTemplate">
	<property name="target" ref="departmentDAOTarget"/>
	<property name="proxyInterfaces" value="model.logic.DepartmentDAO"/>
</bean>
<bean id="transactionTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
	<property name="transactionManager" ref="transactionManager"/>
	<property name="transactionAttributes">
		<props>
			<prop key="add*">PROPAGATION_REQUIRED</prop>
			<prop key="remove*">PROPAGATION_REQUIRED</prop>
			<prop key="update*">PROPAGATION_REQUIRED</prop>
			<prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
		</props>
	</property>
</bean>

The second bean entry (transactionTemplate) is an abstract declaration which is used as a template. From this abstract declaration, we can make any number of beans transactional by using transactionTemplate as the parent declaration of the bean.

The DepartmentDAOBean has no idea that its methods are being called within the context of a transaction. If any object makes calls directly to the DepartmentDAOBean, those calls will not be transactional. Instead, collaborating objects should invoke methods on the proxy that is produced by TransactionProxyFactoryBean. The proxy will ensure that transactional rules are applied and then proxy the call to the real DepartmentDAOBean. Therefore, rather than inject the service directly into those objects that use it, we will inject the DepartmentDAOBean proxy into those objects. This means that the proxy produced by TransactionProxyFactoryBean must pretend to be a DepartmentDAOBean. That is the purpose of the proxyInterfaces property. Here we are telling TransactionProxyFactoryBean to produce a proxy that implements the DepartmentDAO interface. The transactionManager property supplies the appropriate transaction manager bean.

TransactionProxyFactoryBean will use the transaction manager to start, suspend, commit, and roll back transactions based on the transaction attributes defined in the transactionAttributes property of TransactionProxyFactoryBean. The transactionAttributes property declares which methods are to be run within a transaction and what the transaction attributes are to be. This property is given a props collection where the key of each prop is a method name pattern and the value defines the transaction attributes for the method(s) selected. The value of each prop given to the transactionAttributes property is a comma-separated value (Propagation Behavior, Isolation Level – Optional, Is the transaction read only? – Optional, Rollback Rules (-Exception, +Exception) – Optional). Note that a ‘-’ prefix forces a rollback while a ‘+’ prefix specifies commit (this allows commit on unchecked exceptions). In the case of the DepartmentDAOBean, we are declaring that all methods whose name starts with add should be run within a transaction. Methods starting with find support transactions (but do not necessarily require a transaction) and are read-only.

We can also accomplish this by using annotations, the only thing we need to add to the Spring application context is:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
	...
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
	<tx:annotation-driven/>
</beans>

Note that the transaction-manager attribute of tx:annotation-driven defaults to transactionManager and needs to be specified when an other name is used. The tx:annotation-driven configuration element tells Spring to examine the beans in the application context and to look for beans that are annotated with Transactional. For every bean that is Transactional, tx:annotation-driven will automatically advise it with transaction advice. The transaction attributes of the advice will be defined by parameters of the Transactional annotation. In our code we can use the following:

package model.logic;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public abstract class GenericHibernateSpringDAO<T, ID extends Serializable> implements GenericDAO<T, ID> {

    private Class<T> persistentClass;
    private HibernateTemplate hibernateTemplate;

    public GenericHibernateSpringDAO() {
        Type type = getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            setPersistentClass((Class<T>) parameterizedType.getActualTypeArguments()[0]);
        } else {
            System.out.println("Not an instance of parameterized type: " + type);
        }
    }

    public Class<T> getPersistentClass() {
        return persistentClass;
    }

    public void setPersistentClass(Class<T> persistentClass) {
        this.persistentClass = persistentClass;
    }

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    public T addEntity(T entity) {
        getHibernateTemplate().save(entity);
        return entity;
    }

    public void removeEntity(ID id) {
        getHibernateTemplate().delete(findEntity(id));
    }

    public void updateEntity(T entity) {
        getHibernateTemplate().update(entity);
    }

    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public T findEntity(ID id) {
        return (T) getHibernateTemplate().get(getPersistentClass(), id);
    }

    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public List<T> findEntities() {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(getPersistentClass());
        return getHibernateTemplate().findByCriteria(detachedCriteria);
    }
}

Integrating Hibernate

Hibernate (an object/relational mapping framework) defines a technique to map an object oriented data model to a relational data model.

Even though there are many steps to the data access process, we are only actively involved in a couple of those steps. The carrier itself is responsible for driving the process. We are only involved when we need to be; the rest is just ‘taken care of’. This mirrors a powerful design pattern: the Template Method pattern. A template method defines the skeleton of a process. The process itself is fixed; it never changes. At certain points, however, the process delegates its work to a subclass to fill in some implementation-specific details. In software terms, a template method delegates the implementation-specific portions of the process to an interface. Different implementations of this interface define specific implementations of this portion of the process.

This is the same pattern that Spring applies to data access. No matter what technology we are using, certain data access steps are required. For example, we always need to obtain a connection to our data store and clean up resources when we are done. These are the fixed steps in a data access process. But each data access method we write is slightly different. We query for different objects and update the data in different ways. These are the variable steps in the data access process. Spring separates the fixed and variable parts of the data access process into two distinct classes, templates and callbacks:

  • Templates manage the fixed part of the process.
  • Callbacks handle the variable part, such as custom data access code.

Spring’s template classes handle the fixed parts of data access – controlling transactions, managing resources, and handling exceptions. Meanwhile, the specifics of data access as they pertain to the application – creating statements, binding parameters, and marshaling result sets – are handled in the callback implementation. In practice, this makes for an elegant framework because all we have to worry about is the data access logic. Spring comes with several templates to choose from, depending on the persistence platform choice. When using Hibernate then we can use HibernateTemplate as was done in the example above.

Applications that have a persistent state must in one way or another have interaction with the persistence provider, when a certain in-memory state must be persisted to the database (or vice versa). In the case of Hibernate this is the interface Session. Each Session is associated with a persistence context. A persistence context is some sort of cache that tracks object changes in a certain transaction. Note that Spring’s HibernateTemplate provides an abstract layer for the Session interface.

The complete Spring configuration looks as follows:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    <bean id="departmentDAO" class="model.logic.DepartmentDAOBean">
        <property name="hibernateTemplate" ref="hibernateTemplate"/>
    </bean>
    <bean id="employeeDAO" class="model.logic.EmployeeDAOBean">
        <property name="hibernateTemplate" ref="hibernateTemplate"/>
    </bean>
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>model/entities/Department.hbm.xml</value>
                <value>model/entities/Employee.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.current_session_context_class">${hibernate.current_session_context_class}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
            </props>
        </property>
    </bean>
    <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
        <property name="driverType" value="${jdbc.driverClassName}"/>
        <property name="URL" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:spring.properties</value>
            </list>
        </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <tx:annotation-driven/>
</beans>

Obtaining beans

Now, that we have the configuration in place we need a way to obtain the configured beans. In Spring, objects are not responsible for finding or creating other objects that they need to do their job. Instead, they are given references to the objects that they collaborate with by the container. The act of creating these associations between application objects is the essence of dependency injection and is commonly referred to as wiring. Spring comes with several container implementations that can be categorized into two distinct types:

  • Bean factories provide basic dependency injection support. A bean factory is an implementation of the Factory design pattern, i.e., it is a class whose responsibility it is to create and dispense beans and is able to create associations between collaborating objects as they are instantiated. A bean factory also takes part in the lifecycle of a bean, such as making calls to initialization and destruction methods, if those methods are defined.
  • Application contexts provide application framework services, such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners.

Before we can retrieve a bean from the application context, it needs to be created. This can be accomplished by using ClassPathXmlApplicationContext (Loads a context definition from an XML file located in the classpath, treating context definition files as classpath resources). Once we have an ApplicationContext instance we can use the getBean method to retrieve a bean, for example,

package model.utils;

import model.logic.DepartmentDAO;
import model.logic.EmployeeDAO;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Utilities {

    private static ApplicationContext context;

    private Utilities() {
    }

    static {
        context = new ClassPathXmlApplicationContext("spring-config.xml");
    }

    public static DepartmentDAO getDepartmentDAO() {
        return (DepartmentDAO) context.getBean("departmentDAO");
    }

    public static EmployeeDAO getEmployeeDAO() {
        return (EmployeeDAO) context.getBean("employeeDAO");
    }
}

A difference between an application context and a bean factory is how singleton beans are loaded. A bean factory lazily loads all beans, deferring bean creation until the getBean method is called. An application context is a bit smarter and preloads all singleton beans upon context start up. To take advantage of the opportunities offered by Spring to customize bean creation we have to understand the lifecycle:

  1. Instantiate – instantiate the bean.
  2. Populate properties – inject the bean’s properties.
  3. Set bean name – if the bean implements BeanNameAware, the bean’s ID is passed to setBeanName.
  4. Set bean factory – if the bean implements BeanFactoryAware, the bean factory is passed to setBeanFactory. If the bean implements ApplicationContextAware interface, the setApplicationContext method is called.
  5. Postprocess – if there are any BeanPostProcessors, Spring calls the postProcessBeforeInitialization method.
  6. Initialize beans – if the bean implements InitializingBean, the afterPropertiesSet method will be called. If the bean has an init-method declared, the specified method will be called.
  7. Postprocess – if there are any BeanPostProcessors, the postProcessAfterInitialization method will be called.
  8. At this point the bean is ready to be used by the application and will remain in the bean factory until it is no longer needed.
  9. Destroy bean – if the bean implements DisposableBean, the destroy method will be called. If the bean has a destroy-method declared, the specified method will be called.

By default, all Spring beans are singletons, i.e., when the container dispenses a bean it will always hand out the exact same instance of the bean. When declaring a bean in Spring, we have the option of declaring a scope for the bean. For example, to let Spring produce a new bean instance each time one is needed, we must declare the bean’s scope attribute to be prototype, for example

<bean id="cacheStore" class="com.tangosol.coherence.hibernate.HibernateCacheStore" scope="prototype">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

Spring offers a handful scoping options:

  • singleton – scopes the bean definition to a single instance per container (default).
  • prototype – allows a bean to be instantiated any number of times (once per use).
  • request – scopes a bean definition to an HTTP request. Only valid when used with a web capable Spring context (such as with Spring MVC).
  • session – scopes a bean definition to an HTTP session. Only valid when used with a web capable Spring context (such as with Spring MVC).
  • global-session – scopes a bean definition to a global HTTP session. Only valid when used in a portlet context.

Usually, the scope will be singleton, sometimes the prototype scope is useful, for example, when other programs need to manage the life cycle.

Obtain objects from JNDI

In distributed applications some components need to access resources, such as, database servers and messaging systems. Resources are typically identified by a unique name – a JNDI name and are in general configured on an application server. When we need objects that are not configured as beans in Spring but in JNDI we can use JndiObjectFactoryBean.

When the application is deployed on the server where the resources, such as data sources, are configured we can proceed as follows. To create a data source bean we add the following entry:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiName" value="jdbc/exampleDS"/>
	<property name="resourceRef" value="true"/>
</bean>

In order for this work we need to add the following entry in the web.xml file

<resource-ref>
	<res-ref-name>jdbc/exampleDS</res-ref-name>
	<res-type>javax.sql.DataSource</res-type>
	<res-auth>Container</res-auth>
</resource-ref>

The resource-ref makes the resource known to the (Web) container. The container makes the resources available in the local java:comp/env/ environment.

To access resources remotely, we first have to define a JNDI template, for example,

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
	<property name="environment">
		<props>
			<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
			<prop key="java.naming.provider.url">t3://hostname:portnumber</prop>
		</props>
	</property>
</bean>

To create beans of remote resources, we can use the following

<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiTemplate" ref="jndiTemplate"/>
	<property name="jndiName" value="jms/ConnectionFactory"/>
</bean>
<bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiTemplate" ref="jndiTemplate"/>
	<property name="jndiName" value="jms/Queue"/>
</bean>

Now that we know how to retrieve resources, let us use this in an example that uses messaging.

Messaging

JMS can be divided into two functional areas, i.e., production and consumption of messages. The building blocks of a JMS application constist of:

  • Administrative objects (usually configured in an application server)
    • Connection factories – @Resource(name = "jms/ConnectionFactory", type = ConnectionFactory.class) ConnectionFactory connectionFactory;
    • Destinations (Queues or Topics) – @Resource(name = "jms/CompanyQueue", type = Queue.class) Queue destination;
  • Connections – Connection connection = connectionFactory.createConnection();
  • Sessions – Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  • Message producers – MessageProducer messageProducer = session.createProducer(destination);
  • Message consumers – MessageConsumer messageConsumer = session.createConsumer(otherDestination);
  • Messages – ObjectMessage message = session.createObjectMessage(); message.setObject(person); messageProducer.send(message);

Just as that Spring offers templates for data access it also provides a JMSTemplate. The JMSTemplate can be used for message production and synchronous message consumption. For asynchronous consumption (such as message-driven beans), a message listener container can be used. To create a JMSTemplate we can use the following:

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
	<property name="connectionFactory" ref="connectionFactory"/>
	<property name="defaultDestination" ref="destination"/>
</bean>

Code that uses a JMSTemplate only needs to implement a callback interface. For example, MessageCreator creates a message using a Session that is provided by the JMSTemplate:

package model.logic;

import model.entities.Department;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import javax.jms.*;

public class JMSSender {

    private JmsTemplate jmsTemplate;

    public JmsTemplate getJmsTemplate() {
        return jmsTemplate;
    }

    public void setJmsTemplate(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    public void sendTextMessage() {
        getJmsTemplate().send(new MessageCreator(){
            public Message createMessage(Session session) throws JMSException {
                TextMessage message = session.createTextMessage();
                message.setText("Testing the JMS set-up one-two, one-two test");
                return message;
            }
        });
    }

    public void sendMessage(final Department department) {
        getJmsTemplate().send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                ObjectMessage message = session.createObjectMessage();
                message.setObject(department);
                return message;
            }
        });
    }
}

To inject the JMSTemplate into the JMSSender we can use the following:

<bean id="sender" class="model.logic.JMSSender">
	<property name="jmsTemplate" ref="jmsTemplate"/>
</bean>

To receive messages asynchronously we can use message listener containers (Spring’s equivalent to message-driven beans). A message listener container is used to receive messages from a queue and drive the MessageListener that is injected into it. The listener container is responsible for all the threading of message consumption and dispatches to the listener for processing. Three message listeners are available:

The following shows an example message listener container configuration:

<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
	<property name="connectionFactory" ref="connectionFactory"/>
	<property name="destination" ref="destination"/>
	<property name="messageListener" ref="receiver"/>
</bean>
<bean id="receiver" class="model.logic.JMSReceiver"/>

in which the JMSReceiver looks as follows:

package model.logic;

import model.entities.Department;
import javax.jms.*;

public class JMSReceiver implements MessageListener {

    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            TextMessage text = (TextMessage) message;
            try {
                message.acknowledge();
                System.out.println("received the following message: " + text.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }

        if (message instanceof ObjectMessage) {
            ObjectMessage objectMessage = (ObjectMessage) message;
            try {
                message.acknowledge();
                Department department = (Department) objectMessage.getObject();
                System.out.println("received the following message: " + department);
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
}

When we choose the run Spring JMS on an application server, for example WebLogic, we run into the fact that the threads spawned by Spring are unmanaged. To make sure the thread are managed we can couple the message listener container to a work manager. First we add the following entry to the web.xml file

<resource-ref>
	<res-ref-name>default</res-ref-name>
	<res-type>commonj.work.WorkManager</res-type>
	<res-auth>Container</res-auth>
	<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

Now, we are able to create the following TaskExecutor:

<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
	<property name="workManagerName" value="java:comp/env/default"/>
	<property name="resourceRef" value="true"/>
</bean>

To inject the TaskExecutor into the message listener container we can use:

<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
	<property name="connectionFactory" ref="connectionFactory"/>
	<property name="destination" ref="destination"/>
	<property name="messageListener" ref="receiver"/>
	<property name="taskExecutor" ref="taskExecutor"/>
</bean>

Spring MVC

Spring MVC is designed around a DispatcherServlet that dispatches requests to handlers. The default handler is a Controller interface. In general, application controllers will subclass controllers such as AbstractController. Basically, the following classes will be involved in processing a request:

  • The DispatcherServlet reads the configuration file (<dispatcher-servlet-name>-servlet.xml and creates a respository with configuration objects.
  • The DispatcherServlet acts as a front controller and delegates requests to other components (Controllers).
  • Based on handler mappings it is determined which controller should process the request. The handler mapping uses the URL to choose the appropriate controller.
  • The Controller processes the request that results in information that should be returned to the requester:
    • The information is made available as a Model.
    • The information is handed to a View (for example, a JSP), such that the Model can be formatted as HTML.
  • The controller packages the Model data and the name of the View into a ModelAndView object and gives this to the DispatcherServlet.
  • The DispatherServlet uses a ViewResolver to determine the View.
  • The DispatherServlet passes the Model data to the View.

Let us just give an example of how to set this up. First, we have to configure the DispatcherServlet in the web.xml file, for example,

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-config.xml</param-value>
   </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/spring/*</url-pattern>
    </servlet-mapping>
</web-app>

Note that based on the servlet-name a certain Spring configuration file is loaded. In this case the name of the configuration file must be spring-servlet.xml. By using the context parameter contextConfigLocation we can control which other configuration files must be loaded from the classpath.

To create a Controller, we subclass the AbstractController. In this case we need to override the handleRequestInternal method, for example,

package userinterface.controllers;

import model.entities.Department;
import model.logic.DepartmentDAO;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public class DepartmentController extends AbstractController {

    private DepartmentDAO departmentDAO;

    public DepartmentController() {
    }

    public DepartmentDAO getDepartmentDAO() {
        return departmentDAO;
    }

    public void setDepartmentDAO(DepartmentDAO departmentDAO) {
        this.departmentDAO = departmentDAO;
    }

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        List<Department> departments = getDepartmentDAO().findEntities();
        if (departments != null) {
            for (Department department: departments) {
                System.out.println(department);
            }
        }

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("departments", departments);
        modelAndView.setViewName("departments");
        return modelAndView;
    }
}

To inject the DepartmentDAO instance into the Controller we add the following in the spring-servlet.xml file:

<bean name="departmentController" class="userinterface.controllers.DepartmentController">
	<property name="departmentDAO" ref="departmentDAO"/>
</bean>

Note that the departmentDAO bean is configured in the spring-config.xml file.

The HandlerMapping is set-up as follows. By using a handler mapping we map incoming requests to appropriate handlers. When the request comes in, the DispatcherServlet will hand it over to the handler mapping to let it inspect the request and come up with the appropriate HandlerExecutionChain. Then the DispatcherServlet will execute the handler. A very handy handler mapping is the SimpleUrlHandlerMapping, for example,

<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="mappings">
		<props>
			<prop key="/departments.html">departmentController</prop>
		</props>
	</property>
</bean>

This handler mapping routes requests for departments.html to the departmentController.

Next, we need to resolve the view. To this end, Spring provides view resolvers, which enable us to render models in a browser without tying them to a specific view technology. The ViewResolver interface provides a mapping between view names and actual views. When using JSP as the view technology we can use the InternalResourceViewResolver, for example,

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/"/>
	<property name="suffix" value=".jsp"/>
</bean>

The following shows an example of a view in this case a JSP page (departments.jsp):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
	<head><title>Departments</title></head>
	<body>
		<h1>Hello</h1>
		<table>
			<c:forEach items="${departments}" var="department">
				<tr>
					<td><c:out value="${department.departmentName}"/></td>
				</tr>
			</c:forEach>
		</table>
	</body>
</html>

Note that the departments variable is set by the departmentController through the returned ModelAndView instance. When we put a request in the form of http://hostname:port/<context-root>/spring/departments.html the following happens:

  • As we configured an url-mapping in the web.xml file, the /spring/* part of the URL makes sure that the DispatcherServlet handles the request.
  • The DispatcherServlet receives a request with the following URL /departments.html.
  • By using the SimpleUrlHandlerMapping the DispatcherServlet determines which controller to use. In this case it finds a mapping to the DepartmentController.
  • The DispatcherServlet passes the request to the DepartmentController.
  • The DepartmentController creates a ModelAndView object, in which
    • The Model contains a List with all the Department objects and maps this to a property named departments.
    • The View contains a logical name, in this case departments.
  • The DispatcherServlet uses the InternalResourceViewResolver to determine which JSP the Model has to render.
  • The DispatcherServlet passes the request to the departments.jsp page.

References

[1] Walls, “Spring in Action”, Manning, 2008. All you ever wanted to know about Spring (also a good reference when you are going for your Spring certification).
[2] The Spring Framework – Reference Documentation.