blob: 26ab9df6a9b429c59cf5e3a3e1e6720542693166 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="Date-Revision-yyyymmdd" content="20140918"/>
<meta http-equiv="Content-Language" content="en"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Spring</title>
<link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,400italic,600italic,700italic" rel="stylesheet" type="text/css">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link href="/css/main.css" rel="stylesheet">
<link href="/css/custom.css" rel="stylesheet">
<link href="/highlighter/github-theme.css" rel="stylesheet">
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="/js/community.js"></script>
</head>
<body>
<a href="http://github.com/apache/struts" class="github-ribbon">
<img style="position: absolute; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub">
</a>
<header>
<nav>
<div role="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" data-toggle="collapse" data-target="#struts-menu" class="navbar-toggle">
Menu
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="/index.html" class="navbar-brand logo"><img src="/img/struts-logo.svg"></a>
</div>
<div id="struts-menu" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Home<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/index.html">Welcome</a></li>
<li><a href="/download.cgi">Download</a></li>
<li><a href="/releases.html">Releases</a></li>
<li><a href="/announce.html">Announcements</a></li>
<li><a href="http://www.apache.org/licenses/">License</a></li>
<li><a href="https://www.apache.org/foundation/thanks.html">Thanks!</a></li>
<li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Support<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/mail.html">User Mailing List</a></li>
<li><a href="https://issues.apache.org/jira/browse/WW">Issue Tracker</a></li>
<li><a href="/security.html">Reporting Security Issues</a></li>
<li class="divider"></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Migration+Guide">Version Notes</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Security+Bulletins">Security Bulletins</a></li>
<li class="divider"></li>
<li><a href="/maven/project-info.html">Maven Project Info</a></li>
<li><a href="/maven/struts2-core/dependencies.html">Struts Core Dependencies</a></li>
<li><a href="/maven/struts2-plugins/modules.html">Plugin Dependencies</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Documentation<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/birdseye.html">Birds Eye</a></li>
<li><a href="/primer.html">Key Technologies</a></li>
<li><a href="/kickstart.html">Kickstart FAQ</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Home">Wiki</a></li>
<li class="divider"></li>
<li><a href="/getting-started/">Getting Started</a></li>
<li><a href="/security/">Security Guide</a></li>
<li><a href="/core-developers/">Core Developers Guide</a></li>
<li><a href="/tag-developers/">Tag Developers Guide</a></li>
<li><a href="/maven-archetypes/">Maven Archetypes</a></li>
<li><a href="/plugins/">Plugins</a></li>
<li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li>
<li><a href="/tag-developers/tag-reference.html">Tag reference</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/FAQs">FAQs</a></li>
<li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Contributing<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/youatstruts.html">You at Struts</a></li>
<li><a href="/helping.html">How to Help FAQ</a></li>
<li><a href="/dev-mail.html">Development Lists</a></li>
<li><a href="/contributors/">Contributors Guide</a></li>
<li class="divider"></li>
<li><a href="/submitting-patches.html">Submitting patches</a></li>
<li><a href="/builds.html">Source Code and Builds</a></li>
<li><a href="/coding-standards.html">Coding standards</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Contributors+Guide">Contributors Guide</a></li>
<li class="divider"></li>
<li><a href="/release-guidelines.html">Release Guidelines</a></li>
<li><a href="/bylaws.html">PMC Charter</a></li>
<li><a href="/volunteers.html">Volunteers</a></li>
<li><a href="https://gitbox.apache.org/repos/asf?p=struts.git">Source Repository</a></li>
<li><a href="/updating-website.html">Updating the website</a></li>
</ul>
</li>
<li class="apache"><a href="http://www.apache.org/"><img src="/img/apache.png"></a></li>
</ul>
</div>
</div>
</div>
</nav>
</header>
<article class="container">
<section class="col-md-12">
<a class="edit-on-gh" href="https://github.com/apache/struts-site/edit/master/source/getting-started/spring.md" title="Edit this page on GitHub">Edit on GitHub</a>
<a href="index.html" title="back to Getting started"><< back to Getting started</a>
<h1 class="no_toc" id="spring-and-struts-2">Spring and Struts 2</h1>
<ul id="markdown-toc">
<li><a href="#introduction" id="markdown-toc-introduction">Introduction</a></li>
<li><a href="#struts-2-spring-plugin" id="markdown-toc-struts-2-spring-plugin">Struts 2 Spring Plugin</a></li>
<li><a href="#spring-configuration-file" id="markdown-toc-spring-configuration-file">Spring Configuration File</a></li>
<li><a href="#alternative---have-spring-manage-creation-of-actionsupport-class" id="markdown-toc-alternative---have-spring-manage-creation-of-actionsupport-class">Alternative - Have Spring Manage Creation Of ActionSupport Class</a></li>
<li><a href="#summary" id="markdown-toc-summary">Summary</a></li>
</ul>
<p>The example code for this tutorial, <strong>spring-struts</strong>, is available for checkout at <a href="https://github.com/apache/struts-examples">struts-examples</a></p>
<h2 id="introduction">Introduction</h2>
<p>In the execute method of many Struts 2 ActionSupport classes are statements that create objects and then have those
objects execute methods that perform needed tasks. Whenever one class creates an object of another class that introduces
a dependency between the two classes. The Spring framework makes it easier for the application developer to manage these
dependencies and helps make the application more flexible and maintainable. This tutorial will show you how to use Struts 2
and Spring together to manage the dependencies between your ActionSupport classes and other classes in your application.</p>
<blockquote>
<p>This tutorial assumes you understand how to use the Spring framework to manage dependencies between classes. You can
learn more about Spring by reading the documentation at <a href="https://spring.io/docs">https://spring.io/docs</a></p>
</blockquote>
<p>The <a href="http://struts.apache.org/mail.html">Struts 2 user mailing list</a> is an excellent place to get help. If you are having
a problem getting the tutorial example applications to work search the Struts 2 mailing list. If you don’t find an answer
to your problem, post a question on the mailing list.</p>
<p>If you examine the example application for the <a href="themes.html">Struts 2 Themes</a> tutorial you’ll see this code in the
<code class="highlighter-rouge">EditAction</code> class</p>
<p><strong>EditAction Class Hard-Coded Dependency</strong></p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="n">EditService</span> <span class="n">editService</span> <span class="o">=</span> <span class="k">new</span> <span class="n">EditServiceInMemory</span><span class="o">();</span>
</code></pre></div></div>
<p>The above statement hard-codes a dependency between the <code class="highlighter-rouge">EditAction</code> class and the <code class="highlighter-rouge">EditServiceInMemory</code> class. This is
poor design for two reasons.</p>
<ol>
<li>If I need to replace the <code class="highlighter-rouge">EditServiceInMemory</code> with another class that implements the <code class="highlighter-rouge">EditService</code> interface I’ll
have to hunt down and replace all statements where I hard-coded the dependency.</li>
<li>I cannot test <code class="highlighter-rouge">EditAction</code> without using the <code class="highlighter-rouge">EditServiceInMemory</code> class. I cannot isolate <code class="highlighter-rouge">EditAction</code> by using
a stub implementation of <code class="highlighter-rouge">EditService</code> when writing my test case because the use of <code class="highlighter-rouge">EditServiceInMemory</code> is hard-coded.</li>
</ol>
<p>Spring provides a mechanism to manage dependencies by injecting them at run time. Struts 2 ActionSupport classes—like
any other Java class—can be injected with a dependent object by the Spring framework. So instead of having the above code,
I would have this statement in <code class="highlighter-rouge">EditAction</code>.</p>
<p><strong>EditAction Class No Hard-Coded Dependency</strong></p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="n">EditService</span> <span class="n">editService</span><span class="o">;</span>
</code></pre></div></div>
<p>At run time the Spring framework will provide an object of a class that implements the EditService interface.</p>
<h2 id="struts-2-spring-plugin">Struts 2 Spring Plugin</h2>
<p>Struts 2 provides a plugin that enables Spring to inject into the ActionSupport classes any dependent objects you’ve
specified in the Spring configuration file. Consult <a href="../plugins/spring/">Spring Plugin documentation</a> for more information
about how the plugin works.</p>
<p>For a Maven application you’ll need to add a dependency to the struts2-spring-plugin jar (see the Maven example application
for this tutorial). The plugin’s pom.xml includes transitive dependencies to the Spring jar files.</p>
<blockquote>
<p>The current version (<code class="highlighter-rouge">2.5.10.1</code>) of the Struts 2 Spring plugin has transitive dependencies to the Spring <code class="highlighter-rouge">4.1.6.RELEASE</code> version.
If you want to use the latest version of Spring, then you should exclude the transitive dependencies in your pom.xml
for the Struts 2 Spring plugin and then declare dependency nodes to the current version of the Spring jar files.
If you are using Ant and explicitly including the jar files in your application, then just include the latest version
of the Spring jar files.</p>
</blockquote>
<p>In your <code class="highlighter-rouge">ActionSupport</code> class you must have a set method for the dependent object that follows standard Java bean naming
conventions. If you examine the <code class="highlighter-rouge">EditAction</code> class for this tutorial’s application you’ll see this set method.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">setEditService</span><span class="o">(</span><span class="n">EditService</span> <span class="n">editService</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">editService</span> <span class="o">=</span> <span class="n">editService</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Spring will use that set method to provide an object of type <code class="highlighter-rouge">EditService</code> to the <code class="highlighter-rouge">EditAction</code> class at run time.</p>
<p>To make our application “Spring aware” we need to add this line to web.xml.</p>
<p><strong>Spring Listener In web.xml</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;listener&gt;</span>
<span class="nt">&lt;listener-class&gt;</span>org.springframework.web.context.ContextLoaderListener<span class="nt">&lt;/listener-class&gt;</span>
<span class="nt">&lt;/listener&gt;</span>
</code></pre></div></div>
<p>The above code will activate the Spring framework when the application is started up by the Servlet container. By default
Spring will look for a configuration file name applicationContext.xml in WEB-INF (consult the Spring documentation for
how you can change where Spring looks and what the configuration file name is).</p>
<h2 id="spring-configuration-file">Spring Configuration File</h2>
<p>In the Spring configuration file we create a bean node for those objects we want Spring to create an instance of and inject
into our ActionSupport class. In the example application is this <code class="highlighter-rouge">applicationContext.xml</code>.</p>
<p><strong>Spring Configuration File</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="nt">&lt;beans</span> <span class="na">xmlns=</span><span class="s">"http://www.springframework.org/schema/beans"</span>
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span class="na">xsi:schemaLocation=</span><span class="s">"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="nt">&gt;</span>
<span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">"editService"</span> <span class="na">class=</span><span class="s">"org.apache.struts.edit.service.EditServiceInMemory"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/beans&gt;</span>
</code></pre></div></div>
<p>Note the id value above. By default the Spring plugin works with Spring to autowire the dependencies of the ActionClass
by <code class="highlighter-rouge">name</code>. Spring will create an object of class EditServiceMemory and provide that object to any ActionSupport class
that has a setEditService method with an argument of type EditService. Consult the <a href="../plugins/spring/">Spring Plugin</a>
documentation for how to change the default autowire method.</p>
<p>The editService bean created by Spring will have a scope of singleton since that is the default scope. Consult section
3.5 of the <a href="https://spring.io/docs">Spring documentation</a> for how to configure the bean definition to use a different
scope (e.g. request or session).</p>
<h2 id="alternative---have-spring-manage-creation-of-actionsupport-class">Alternative - Have Spring Manage Creation Of ActionSupport Class</h2>
<p>Using the above methodology, the Struts 2 framework will still manage the creation of the <code class="highlighter-rouge">ActionSupport</code> class. If you
prefer you can configure the application so that Spring will create the ActionSupport class also. To support this technique
you need to add a bean node to the Spring configuration file for the ActionSupport class.</p>
<p><strong>Spring Configuration For ActionSupport Class Managed By Spring</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="nt">&lt;beans</span> <span class="na">xmlns=</span><span class="s">"http://www.springframework.org/schema/beans"</span>
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span class="na">xsi:schemaLocation=</span><span class="s">"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="nt">&gt;</span>
<span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">"editService"</span> <span class="na">class=</span><span class="s">"org.apache.struts.edit.service.EditServiceInMemory"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">"editAction"</span> <span class="na">class=</span><span class="s">"org.apache.struts.edit.action.EditAction"</span> <span class="na">scope=</span><span class="s">"prototype"</span><span class="nt">&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"editService"</span> <span class="na">ref=</span><span class="s">"editService"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/bean&gt;</span>
<span class="nt">&lt;/beans&gt;</span>
</code></pre></div></div>
<p>Note in the above that there is an <code class="highlighter-rouge">editAction</code> bean and its <code class="highlighter-rouge">editService</code> property is set to the <code class="highlighter-rouge">editService</code> bean.
Since we are having Spring manage the <code class="highlighter-rouge">EditAction</code> class we must specify any properties of <code class="highlighter-rouge">EditAction</code> that we want Spring
to inject. Please remember that actions must be created on each request, they cannot be <code class="highlighter-rouge">singletons</code>- this is the default
<code class="highlighter-rouge">scope</code> that’s why it must be changed to <code class="highlighter-rouge">prototype</code>.</p>
<p>In the <code class="highlighter-rouge">struts.xml</code> configuration file you must specify the Spring id value for the class attribute of the action node.
This tells Struts to get a bean with that id value from Spring for the Action class.</p>
<p><strong>Struts Configuration For Spring Managed ActionSupport Class</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;action</span> <span class="na">name=</span><span class="s">"edit"</span> <span class="na">class=</span><span class="s">"editAction"</span> <span class="na">method=</span><span class="s">"input"</span><span class="nt">&gt;</span>
<span class="nt">&lt;result</span> <span class="na">name=</span><span class="s">"input"</span><span class="nt">&gt;</span>/edit.jsp<span class="nt">&lt;/result&gt;</span>
<span class="nt">&lt;/action&gt;</span>
</code></pre></div></div>
<h2 id="summary">Summary</h2>
<p>In this tutorial we reviewed how to use the Struts 2 Spring plugin to integrate Spring and Struts. By using the Struts 2
Spring plugin you can have Spring manage the dependencies of your ActionSupport classes. Of course you can also take
advantage of the many other benefits (AOP, Spring JDBC) that the Spring framework provides.</p>
<table>
<tbody>
<tr>
<td>Return to <a href="themes.html">Themes</a></td>
<td>or</td>
<td>onward to <a href="annotations.html">Annotations</a></td>
</tr>
</tbody>
</table>
</section>
</article>
<footer class="container">
<div class="col-md-12">
Copyright &copy; 2000-2018 <a href="http://www.apache.org/">The Apache Software Foundation </a>.
All Rights Reserved.
</div>
<div class="col-md-12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts project logos are
trademarks of The Apache Software Foundation.
</div>
<div class="col-md-12">Logo and website design donated by <a href="https://softwaremill.com/">SoftwareMill</a>.</div>
</footer>
<script>!function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (!d.getElementById(id)) {
js = d.createElement(s);
js.id = id;
js.src = "//platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
}
}(document, "script", "twitter-wjs");</script>
<script src="https://apis.google.com/js/platform.js" async="async" defer="defer"></script>
<div id="fb-root"></div>
<script>(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
</body>
</html>