Tuesday, October 21, 2008

Using the Spring Framework with WebSphere Application Server v7.0

IBM has been working with SpringSource for a few years now to ensure that WebSphere Application Server continues to be an excellent platform for customers wishing to use the Spring Framework. WebSphere Application Server v7.0 is no exception, and there are a number of new features that you can take advantage of.

AspectJ support
From Spring 2.5 onwards, Spring’s AspectJ support can be utilised. In this example we first define a <tx:advice> that indicates that all methods starting with "get" are PROPAGATION_REQUIRED and all methods starting with "set" are PROPAGATION_REQUIRES_NEW. All other methods use the default transaction settings.

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="set*" propagation="REQUIRES_NEW" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
Then use <aop:config> to apply those settings to any executed operation defined within the class MyService.

<aop:config>
<aop:pointcut id="myServiceOperation"
expression="execution(* sample.service.MyService.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut-ref="myServiceOperation"/>
</aop:config>
Annotation based configuration
Another alternative mechanism for declaring transaction settings is to use the Spring annotation-based transaction support. This requires the use of Java 5+, and therefore cannot be used with WebSphere Application Server V6.0.2.x.
First add the following to the spring.xml configuration:

<tx:annotation-driven/>

Any methods that require transactional attributes should then be marked with the @Transactional annotation:

@Transactional(readOnly = true)
public String getUserName()
{ ...
JPA configuration
The EJB 3.0 specification defines the Java Persistence API (JPA) as the means for providing portable persistent Java entities. WebSphere Application Server V7 and the WebSphere Application Server V6.1 EJB 3 feature pack both provide implementations of EJB 3 and JPA; it is also possible to use the Apache OpenJPA implementation of JPA with WebSphere Application Server V6.1

Using an Annotation style injection of a JPA EntityManager is possible:

@PersistenceContext
private EntityManager em;
You need this XML code to turn on EntityManager injection in the Spring XML configuration:
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
JMS templates
For JMS message sending or synchronous JMS message receipt, JMSTemplates can be used. This includes the use of Spring’s dynamic destination resolution functionality both via JNDI and true dynamic resolution.

The following example shows the configuration of a resource reference for a ConnectionFactory. This reference is mapped during application deployment to point to a configured, managed ConnectionFactory stored in the application server’s JNDI namespace. The ConnectionFactory is required to perform messaging and should be injected into the Spring JMSTemplate.
<resource-ref>
<res-ref-name>jms/myCF</res-ref-name>
<res-type>javax.jms.ConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
There is now a defined JNDI name for your ConnectionFactory within the application that can be looked up and injected into the JMSTemplate:
<jee:jndi-lookup id="jmsConnectionFactory" jndi-name=" jms/myCF "/>

<bean id="jmsQueueTemplate"
class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="jmsConnectionFactory"/>
</property>
<property name="destinationResolver">
<ref bean="jmsDestResolver"/>
</property>
...
</bean>

<!-- A dynamic resolver -->
<bean id="jmsDestResolver" class="
org.springframework.jms.support.destination.DynamicDestinationResolver"/>

<!-- A JNDI resolver -->
<bean id="jmsDestResolver"
class=" org.springframework.jms.support.destination.JndiDestinationResolver"/>
At run time, the JMSTemplate can locate destinations based on either their JNDI name (as configured in an application resource reference) or through "dynamic resolution," based on the administrative name of the destination configured in WebSphere Application Server; for example, for the JMS myQueue queue, bound to a JNDI reference of jms/myQueue:

JNDI resolution:
jmsTemplate.send("java:comp/env/jms/myQueue", messageCreator);

Dynamic resolution:

jmsTemplate.send("myQueue", messageCreator);


If you have been using the Spring Framework with
WebSphere Application Server already, you may have come across this developerWorks article http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html

I
t has had a facelift recently, and is updated with new content including further configuration details of using WebSphere Application Server with the Spring Framework.

4 comments:

Anonymous said...

And? AND?

I prithee wouldst though deign to tell us how any of this applies to websphere? I see nothing in this post that was not cut and pasted from general Spring articles.

Sara Mitchell said...

The purpose of my post was to highlight the revised content of the 'best practices' developerWorks article cited in the post (AOP, Annotations, JPA and EJB3, JMSTemplates) and provides code examples for people who like them.

The material was taken from that article, but as co-author of the article and lead of the team that tests Spring function on WebSphere I am eager to see people use Spring on WebSphere Application Server successfully and so felt a subset of that information would find a different audience in this format.

I apologise if it has irritated you. That was not my intention.

Anonymous said...

Nice article thanks,

I have one question as follows:

How can SpringFramework if possible use JTA from the application server container managed transaction, to be used along with Persistence layer?

Thanks,
http://www.interview-questions-tips-forum.net

Ian Robinson said...

"How can SpringFramework if possible use JTA from the application server container managed transaction, to be used along with Persistence layer?
"

Spring components are configured to use the underlying AppServer's JTA support as described in this post (and in the WAS InfoCenter). Under the covers, this causes the Spring container that processes the Spring application context to delegate to WAS transaction support and set up the appropriate transaction context - for example, if you configure your Spring bean with
tx:method name="set*" propagation="REQUIRES_NEW"
then that method will run under a new JTA transaction just the same as if you had deployed an EJB with a transaction attribute of RequresNew. In either case, any entity whose persistence is managed by a persistence f/w is accessed in the context of a WAS JTA transaction. So long as the persistence layer is configured for JTA, then it doesn't matter how WAS started the JTA transaction.