Monday, January 29, 2007

Struts 2 and Spring Communication

The Spring plugin allows Actions, Interceptors, and Results to be created and/or autowired by Spring.

It works by overriding the Struts ObjectFactory to enhance the creation of core framework objects. When an object is to be created, it uses the class attribute in the Struts configuration to correspond to the id attribute in the Spring configuration.

Features
* Allow Actions, Interceptors, and Results to be created by Spring
* Struts-created objects can be autowired by Spring after creation
* Provides two interceptors that autowire actions, if not using the Spring ObjectFactory

USAGE
To enable Spring integration, simply include struts2-spring-plugin-x-x-x.jar in your application.


struts.properties
struts.objectFactory = springAutowiring

The framework enables "autowiring" by default. (Autowiring means to look for objects defined in Spring with the same name as your object property). To change the wiring mode, modify the spring.autowire property.
Wiring Mode
struts.objectFactory.spring.autoWire = type
Enabling Spring integration for other application objects is a two-step process.
  • Configure the Spring listener
web.xml

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

  • Register your objects via the Spring configuration
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >

<beans default-autowire="autodetect">
<bean id="personManagerBean" class="com.acme.PersonManager"/>
<bean id="LoginAction" class="example.Login" singleton="false">
<property name="testManager" ref="personManagerBean"></property>
</bean>
</beans>

Initializing Actions from Spring
Normally, in struts.xml you specify the class for each Action. When using the default SpringObjectFactory, the framework will ask Spring to create the Action and wire up dependencies as specified by the default auto-wire behavior. To do this, all you have to do is configure the bean in your Spring applicationContext.xml and then change the class attribute from your Action in the struts.xml to use the bean name defined in Spring instead of the class name.
struts.xml

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>

<include file="struts-default.xml"/>

<package name="default" extends="struts-default">
<action name="foo" class="com.acme.Foo">

<result>foo.ftl</result>
</action>
</package>

<package name="secure" namespace="/secure" extends="default">

<action name="Login" class="LoginAction">
<result>/jsp/HelloWorld.jsp</result>
</action>
</package>

</struts>
Where you have a Spring bean defined in your applicationContext.xml named "LoginAction". Note that the example.Login Action did not need to be changed, because it can be autowired.

References:
* Spring Plugin
* Struts 2 + Spring 2 + JPA + AJAX

No comments: