Tag Archives: jee

Starting of Spring context in web application

Using Spring in a web application, we need to load the context when the application starts. Fortunately, it can be done in a simple way, by adding the right listener in the application web.xml.

Using Maven, you need to add the Spring-web dependency in your pom.xml:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.0.0.RELEASE</version>
  <scope>compile</scope>
</dependency>

And in the web.xml:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Access Spring context from web application

As I am using JSF with Spring, the beans managed by Spring are not accessible in my page, I used this Siegfried Bolz’s blog as a basis and used the facade pattern to hide access to the context.

The Spring context is loaded when the application starts using ContextLoaderListener in the apllication web.xml:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

We need the following dependency:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.0.0.RELEASE</version>
</dependency>

Define the object which will reference the Spring context:

package net.classnotfound.spring.context;

import org.springframework.context.ApplicationContext;

public class AppContext {
    private static ApplicationContext ctx;

    /**
     * Injected from the class "ApplicationContextProvider" which is automatically
     * loaded during Spring-Initialization.
     */
    public static void setApplicationContext(ApplicationContext applicationContext) {
        ctx = applicationContext;
    }

    /**
     * Get access to the Spring ApplicationContext from everywhere in your Application.
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return ctx;
    }
}

Now, define the object that give you access to it:

package net.classnotfound.spring.context;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
 * This class provides an application-wide access to the 
 * Spring ApplicationContext! The ApplicationContext is 
 * injected in a static method of the class "AppContext". 
 * 
 * Use AppContext.getApplicationContext() to get access 
 * to all Spring Beans. 
 * 
 * @author Siegfried Bolz 
 *
 */
public class ApplicationContextProvider implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        AppContext.setApplicationContext(applicationContext);

    }

}

And now this is the facade object which gives access to the Spring beans:

package net.classnotfound.spring.context;

import org.springframework.context.ApplicationContext;

public class ServiceFacade {

	private static ServiceFacade instance = new ServiceFacade();
	
	private static ApplicationContext applicationContext;

	private ServiceFacade() {
		applicationContext = AppContext.getApplicationContext();
	}

	public static ServiceFacade getInstance() {
		return instance;
	}

	//Add here the method to get the different services available 
	// in the Spring Context
	public SpringBean getMyBean() {
		return (SpringBean) applicationContext.getBean("myBean");
	}
}

Don’t forget to ask Spring to create the bean:

<bean id="contextApplicationContextProvider" 
      class="net.classnotfound.spring.context.ApplicationContextProvider"/>

To use it:

SpringBean bean = ServiceFacade.getInstance().getMyBean();

Done!

Simple Spring configuration

Spring configuration for use of a simple transaction manager (non XA). The data source must be defined in a JNDI repository (Tomcat in my case).

application.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<bean id="entityManagerFactory"
                class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
                <property name="generateDdl" value="false" />
            </bean>
        </property>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        </property>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.connection.SetBigStringTryClob">true</prop> <!-- should be done via system properties -->
                <prop key="hibernate.jdbc.batch_size">0</prop>
                <prop key="hibernate.jdbc.use_streams_for_binary">true</prop>
            </props>
        </property>
    </bean>

	<!-- DBCP data source -->

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

	<!-- the transaction manager -->
	<tx:annotation-driven transaction-manager="txManager" />

	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<!-- exceptions translation -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

	<!-- persistance annotations -->
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

</beans>

Maven dependencies:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.framework.version>3.0.7.RELEASE</spring.framework.version>
    <hibernate.version>3.6.9.Final</hibernate.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <version>1.0.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
</dependencies>

To start automatically the Spring Ccontext, add in your web.xml:

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>