Adding Spring Dependancy Injection to Struts2 Project
This will add Spring for the purpose of dependancy injection(DI) to our project. We will create a simple example showing DI and we will bring spring up to the latest version (as of this writing 3.1.1 however this method should apply for the near future).
This assumes that we are starting with a basic strusts2 application.
1) Add the struts2-spring-plugin
The maven coordinates are:
Artifact Id: struts2-spring-plugin
Group Id: org.apache.struts
Version: 2.3.1.2 (or whatever version of struts2 you are using)
2) Configure web.xml and add applicationContext.xml to our project.
web.xml will need to look like the following:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>/index.action</welcome-file>
</welcome-file-list>
</web-app>
Add applicationContext.xml to src/main/resources (same place log4j.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.yourProjectBase" />
</beans>
Note the above contains more xml name spaces and schemas than nessasary for simple DI however it sets us up nicely for adding Java Persistene API in the next integration tutorial.
Beyond the name spaces and schemas there are three things happening:
1) context:annotation-config is used to activate annotations in beans already registered in the application context. To better understand this and to learn how to avoid using xml to register beans altogether please read this very nice answer on stack overflow: Difference between <context:annotation-config/> vs <context:component-scan/>
2) Was also explained in the previous link. It allows us to define beans outside of the applicationContext via annotations, for that we supply the package(s) which it will scan. Again the above link is very useful in understanding this.
Note: We will add our beans on the blank line preceding </beans>
3) [optional] Upgrade Spring to Latest Version
After adding the struts2-spring-plugin you'll see that the following jars were added to support it:
spring-aop-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
In netbeans 7.1, it is as simple as right clicking the dependancy node and adding the most current dependancy for each of the above a list of availible versions should be provided and you simply select the most current one.
You should be able to determine the coordinates:
Groupd Id for all the above is: org.springframework
Artifact Id for all the above is the first two words including the hypen, for example spring-aop-3.0.5.RELEASE.jar is spring-aop, then as previously stated pick the most recent version.
4) [optional] Basic DI example
The following assumes the use of the conventions plugin. For explanation of this plugin see: using the convention plugin.
Our example will require the following things: 1) A service, 2) an implementation of the service, 3) configure spring to inject our service where we need it, 4) an action to use the service and 5) a view.
Create Service
package com.example.project.service;
public interface Test {
String doTest();
}
Create Service Implementation
package com.example.project.impl;
import com.example.project.service.Test;
public class TestImpl implements Test{
@Override
public String doTest() {
return "From test.";
}
}
Configure Spring to Inject the Service
In applicationContext.xml add the following on the line before </beans>:
<bean id="test" class="com.example.project.impl.TestImpl"/>
Create an Action to use the Bean
package com.example.project.action.test;
import com.example.project.service.Test;
import com.opensymphony.xwork2.ActionSupport;
import org.springframework.beans.factory.annotation.Autowired;
public class SpringTest extends ActionSupport{
@Autowired Test test;
public String output;
@Override
public String execute(){
output = test.doTest();
return SUCCESS;
}
}
The View
Create the JSP /WEB-INF/content/test/spring-test.jsp
<%@taglib prefix="s" uri="/struts-tags"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Spring Test</title>
</head>
<body>
<h1>Spring Test</h1>
Value from spring bean: <s:property value="output"/>
</body>
</html>
Run the example... and append test/spring-test to the end of your application path and you should see the result.
Upgrade Spring to the Latest Version 3.1.1
...soon...