﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-Rukas - Oh, My Blog!-随笔分类-Spring</title><link>http://www.cnitblog.com/rukas/category/1379.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 30 Sep 2011 13:14:04 GMT</lastBuildDate><pubDate>Fri, 30 Sep 2011 13:14:04 GMT</pubDate><ttl>60</ttl><item><title>Spring 系列，第 3 部分: 进入 Spring MVC</title><link>http://www.cnitblog.com/rukas/archive/2005/11/17/4648.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Thu, 17 Nov 2005 15:20:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/17/4648.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4648.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/17/4648.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4648.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4648.html</trackback:ping><description><![CDATA[<SPAN style="COLOR: #999999">Spring 系列，第 3 部分: </SPAN>进入 Spring MVC<BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width="100%">
<P id=subtitle>用 Spring MVC 轻松进行应用程序开发</P><IMG class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></TD>
<TD class=no-print width=192><IMG height=18 alt=developerWorks src="http://www-128.ibm.com/developerworks/cn/i/dw.gif" width=192></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD width="100%">
<TABLE class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0>
<TBODY>
<TR>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD class=v14-header-1-small>文档选项</TD></TR></TBODY></TABLE>
<TABLE class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=no-padding width=150>
<TABLE cellSpacing=0 cellPadding=0 width=143 border=0><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8> 
<FORM name=email action=https://www-130.ibm.com/developerworks/secure/email-it.jsp><INPUT type=hidden value="在 Naveen Balani 的 Spring 系列的第 3 部分中，学习如何用 Spring 框架开发基于 MVC 的 应用程序。" name=body><INPUT type=hidden value="Spring 系列，第 3 部分: 进入 Spring MVC" name=subject><INPUT type=hidden value=cn name=lang>
<SCRIPT language=JavaScript type=text/javascript>
<!--
document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td><td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td><td width="122"><p><a class="smallplainlink" href="javascript:document.email.submit();"><b>将此页作为电子邮件发送</b></a></p></td></tr>');
//-->
</SCRIPT>
 
<TBODY>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD width=16><IMG height=16 alt=将此页作为电子邮件发送 src="http://www.ibm.com/i/v14/icons/em.gif" width=16 vspace=3></TD>
<TD width=122>
<P><A class=smallplainlink href="javascript:document.email.submit();"><B><FONT color=#5c81a7 size=2>将此页作为电子邮件发送</FONT></B></A></P></TD></TR><NOSCRIPT><tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img src="//www.ibm.com/i/c.gif" height="16" width="16" alt="" /></td><td width="122" class="small"><p><span class="ast">未显示需要 JavaScript 的文档选项</span></p></td></tr></NOSCRIPT></FORM>
<TR vAlign=top>
<TD width=8><FONT color=#5c81a7 size=2><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></FONT></TD>
<TD width=16><FONT color=#5c81a7 size=2><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/fw_bold.gif" width=16 vspace=3 border=0></FONT></TD>
<TD width=122>
<P><A class=smallplainlink href="javascript:void forumWindow()"><B><FONT color=#5c81a7 size=2>讨论</FONT></B></A></P></TD></TR>
<TR vAlign=top>
<TD width=8><FONT color=#5c81a7 size=2><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></FONT></TD>
<TD width=16><FONT color=#5c81a7 size=2><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/dn.gif" width=16 vspace=3 border=0></FONT></TD>
<TD width=122>
<P><A class=smallplainlink href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#download"><B><FONT color=#996699 size=2>样例代码</FONT></B></A></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD class=v14-header-1-small>对此页的评价</TD></TR></TBODY></TABLE>
<TABLE class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=no-padding width=150>
<TABLE cellSpacing=0 cellPadding=0 width=143 border=0>
<TBODY>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/d_bold.gif" width=16 vspace=3 border=0></TD>
<TD width=125>
<P><A class=smallplainlink href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#rate"><B><FONT color=#996699 size=2>帮助我们改进这些内容</FONT></B></A></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE>
<P>级别: 中级</P>
<P><A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#author"><FONT color=#996699>Naveen Balani </FONT></A>, 技术架构师, Webify Solutions<BR></P>
<P>2005 年 10 月 13 日</P>
<BLOCKQUOTE>在 Naveen Balani 的 Spring 系列的第 3 部分中，学习如何用 Spring 框架开发基于 MVC 的 应用程序。</BLOCKQUOTE>
<P>在 <I><A href="http://www.ibm.com/developerworks/views/web/libraryview.jsp?search_by=The+Spring+Series" target=_new><FONT color=#5c81a7>Spring 系列</FONT></A></I> 的第 3 部分中，我介绍 Spring MVC 框架。就像在以前的文章中一样，我用银行示例介绍如何建模和构建简单的应用程序。示例应用程序包含了已经学过的一些技术（例如依赖注入），但是主要演示 Spring MVC 的特性。</P>
<P>在开始之前，请 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#download"><FONT color=#996699>下载这篇文章的源代码</FONT></A>。请参阅 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#resources"><FONT color=#996699>参考资料</FONT></A> 访问 Spring 框架和 Tomcat 5.0，运行示例需要它们。</P>
<P><A name=IDAHTWW><SPAN class=atitle><FONT face=Arial size=4>Spring MVC 框架</FONT></SPAN></A></P>
<P>Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构，可以选择是使用内置的 Spring Web 框架还是 Struts 这样的 Web 框架。通过策略接口，Spring 框架是高度可配置的，而且包含多种视图技术，例如 JavaServer Pages（JSP）技术、Velocity、Tiles、iText 和 POI。Spring MVC 框架并不知道使用的视图，所以不会强迫您只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色，这种分离让它们更容易进行定制。</P>
<P>Spring 的 Web MVC 框架是围绕 <CODE>DispatcherServlet</CODE> 设计的，它把请求分派给处理程序，同时带有可配置的处理程序映射、视图解析、本地语言、主题解析以及上载文件支持。默认的处理程序是非常简单的 <CODE>Controller</CODE> 接口，只有一个方法 <CODE>ModelAndView handleRequest(request, response)</CODE>。Spring 提供了一个控制器层次结构，可以派生子类。如果应用程序需要处理用户输入表单，那么可以继承 <CODE>AbstractFormController</CODE>。如果需要把多页输入处理到一个表单，那么可以继承 <CODE>AbstractWizardFormController</CODE>。</P>
<P>示例应用程序有助于直观地学习这些特性。银行应用程序允许用户检索他们的帐户信息。在构建银行应用程序的过程中，可以学到如何配置 Spring MVC 框架和实现框架的视图层，视图层包括 JSTL 标记（用于显示输出的数据）和JavaServer Pages 技术。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDAFUWW><SPAN class=atitle><FONT face=Arial size=4>配置 Spring MVC</FONT></SPAN></A></P>
<P>要开始构建示例应用程序，请配置 Spring MVC 的 <CODE>DispatcherServlet</CODE>。请在 <I>web.xml</I> 文件中注册所有配置。清单 1 显示了如何配置 <CODE>sampleBankingServlet</CODE>。</P><BR><A name=code1><B>清单 1. 配置 Spring MVC DispatcherServlet</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">&lt;servlet&gt;
   &lt;servlet-name&gt;sampleBankingServlet&lt;/servlet-name&gt;  
   &lt;servlet-class&gt;
      org.springframework.we.servlet.DispatcherServlet
   &lt;servlet-class&gt;
   &lt;load-on-startup&gt;1&lt;load-on-startup&gt;
&lt;servlet&gt;        
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P><CODE>DispatcherServlet</CODE> 从一个 XML 文件装入 Spring 应用程序上下文，XML 文件的名称是 servlet 的名称后面加上 <I>-servlet</I> 。在这个示例中，<CODE>DispatcherServlet</CODE> 会从 <I>sampleBankingServlet-servlet.xml</I> 文件装入应用程序上下文。 </P>
<P><A name=IDANVWW><SPAN class=smalltitle><STRONG><FONT face=Arial>配置应用程序的 URL</FONT></STRONG></SPAN></A></P>
<P>下一步是配置想让 <CODE>sampleBankingServlet</CODE> 处理的 URL。同样，还是要在 <I>web.xml</I> 中注册所有这些信息。</P><BR><A name=code2><B>清单 2. 配置想要处理的 URL</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">&lt;servlet-mapping&gt;
&lt;servlet-name&gt; sampleBankingServlet&lt;servlet-name&gt;
&lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P><A name=loadcfgfile><SPAN class=smalltitle><STRONG><FONT face=Arial>装入配置文件</FONT></STRONG></SPAN></A></P>
<P>下面，装入配置文件。为了做到这点，请为 Servlet 2.3 规范注册 <CODE>ContextLoaderListener</CODE> 或为 Servlet 2.2 及以下的容器注册 <CODE>ContextLoaderServlet</CODE>。为了保障后向兼容性，请用 <CODE>ContextLoaderServlet</CODE>。在启动 Web 应用程序时，<CODE>ContextLoaderServlet</CODE> 会装入 Spring 配置文件。清单 3 注册了 <CODE>ContextLoaderServlet</CODE>。</P><BR><A name=code3><B>清单 3. 注册 ContextLoaderServlet</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">&lt;servlet&gt;
  &lt;servlet-name&gt;context&gt;servlet-name&gt;
  &lt;servlet-class&gt;
     org.springframework.web.context.ContextLoaderServlet
  &lt;/servlet-class&gt;
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;

</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P><CODE>contextConfigLocation</CODE> 参数定义了要装入的 Spring 配置文件，如下面的 servlet 上下文所示。</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">&lt;context-param&gt;
&lt;param-value&gt;contextConfigLocation&lt;/param-value&gt;
&lt;param-value&gt;/WEB-INF/sampleBanking-services.xml&lt;/param-value&gt;
&lt;/context-param&gt;
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P><I>sampleBanking-services.xml</I> 文件代表示例银行应用程序服务的配置和 bean 配置。如果想装入多个配置文件，可以在 <CODE>&lt;param-value&gt;</CODE> 标记中用逗号作分隔符。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDAZXWW><SPAN class=atitle><FONT face=Arial size=4>Spring MVC 示例</FONT></SPAN></A></P>
<P>示例银行应用程序允许用户根据惟一的 ID 和口令查看帐户信息。虽然 Spring MVC 提供了其他选项，但是我将采用 JSP 技术作为视图页面。这个简单的应用程序包含一个视图页用于用户输入（ID 和口令），另一页显示用户的帐户信息。</P>
<P>我从 <CODE>LoginBankController</CODE> 开始，它扩展了 Spring MVC 的 <CODE>SimpleFormController</CODE>。<CODE>SimpleFormContoller</CODE> 提供了显示从 <CODE>HTTP GET</CODE> 请求接收到的表单的功能，以及处理从 <CODE>HTTP POST</CODE> 接收到的相同表单数据的功能。<CODE>LoginBankController</CODE> 用 <CODE>AuthenticationService</CODE> 和 <CODE>AccountServices</CODE> 服务进行验证，并执行帐户活动。“ <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#cnfgvwprop"><FONT color=#996699>配置视图属性</FONT></A> ”一节中的 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#code5"><FONT color=#996699>清单 5</FONT></A> 描述了如何把 <CODE>AuthenticationService</CODE> 和 <CODE>AccountServices</CODE> 连接到 <CODE>LoginBankController</CODE>。 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/sidefile1.html"><FONT color=#5c81a7>清单 4</FONT></A> 显示了 <CODE>LoginBankController</CODE> 的代码。</P>
<P><A name=cnfgvwprop><SPAN class=smalltitle><STRONG><FONT face=Arial>配置视图属性</FONT></STRONG></SPAN></A></P>
<P>下面，我必须注册在接收到 <CODE>HTTP GET</CODE> 请求时显示的页面。我在 Spring 配置中用 <CODE>formView</CODE> 属性注册这个页面，如清单 5 所示。<CODE>sucessView</CODE> 属性代表表单数据提交而且 <CODE>doSubmitAction()</CODE> 方法中的逻辑成功执行之后显示的页面。<CODE>formView</CODE> 和 <CODE>sucessView</CODE> 属性都代表被定义的视图的逻辑名称，逻辑名称映射到实际的视图页面。</P><BR><A name=code5><B>清单 5. 注册 LoginBankController</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section><FONT face="Lucida Console">  
   &lt;bean id="loginBankController"
         class="springexample.controller.LoginBankController"&gt;
      &lt;property name="sessionForm"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
   &lt;property name="commandName"&gt;&lt;value&gt;loginCommand&lt;/value&gt;&lt;/property&gt;
   &lt;property name="commandClass"&gt;
      &lt;value&gt;springexample.commands.LoginCommand&lt;/value&gt;
   &lt;/property&gt;

      &lt;property name="authenticationService"&gt;
         &lt;ref bean="authenticationService" /&gt;
      &lt;/property&gt;
      &lt;property name="accountServices"&gt;
         &lt;ref bean="accountServices" /&gt;
      &lt;/property&gt;
      &lt;property name="formView"&gt;
         &lt;value&gt;login&lt;/value&gt;
      &lt;/property&gt;
      &lt;property name="successView"&gt;
         &lt;value&gt;accountdetail&lt;/value&gt;
      &lt;/property&gt;

   &lt;/bean&gt;
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P><CODE>commandClass</CODE> 和 <CODE>commandName</CODE> 标记决定将在视图页面中活动的 bean。例如，可以通过 <I>login.jsp</I> 页面访问 <CODE>loginCommand</CODE> bean，这个页面是应用程序的登录页面。一旦用户提交了登录页面，应用程序就可以从 <CODE>LoginBankController</CODE> 的 <CODE>onSubmit()</CODE> 方法中的命令对象检索出表单数据。</P>
<P><A name=IDACECUB><SPAN class=smalltitle><STRONG><FONT face=Arial>视图解析器</FONT></STRONG></SPAN></A></P>
<P>Spring MVC 的 <I>视图解析器</I> 把每个逻辑名称解析成实际的资源，即包含帐户信息的 JSP 文件。我用的是 Spring 的 <CODE>InternalResourceViewResolver</CODE>，如 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/sidefile2.html"><FONT color=#5c81a7>清单 6</FONT></A> 所示。</P>
<P>因为我在 JSP 页面中使用了 JSTL 标记，所以用户的登录名称解析成资源 <I>/jsp/login.jsp</I>，而 <CODE>viewClass</CODE> 成为 <CODE>JstlView</CODE>。</P>
<P><A name=IDABFCUB><SPAN class=smalltitle><STRONG><FONT face=Arial>验证和帐户服务</FONT></STRONG></SPAN></A></P>
<P>就像前面提到的，<CODE>LoginBankController</CODE> 内部连接了 Spring 的 <CODE>AccountServices</CODE> 和 <CODE>AuthenticationService</CODE>。<CODE>AuthenticationService</CODE> 类处理银行应用程序的验证。<CODE>AccountServices</CODE> 类处理典型的银行服务，例如查找交易和电汇。清单 7 显示了银行应用程序的验证和帐户服务的配置。</P><BR><A name=code7><B>清单 7. 配置验证和帐户服务</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console">&lt;beans&gt;

   &lt;bean id="accountServices" 
      class="springexample.services.AccountServices"&gt;

   &lt;/bean&gt;

   &lt;bean id="authenticationService" 
      class="springexample.services.AuthenticationService"&gt;

   &lt;/bean&gt;

&lt;/beans&gt;
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>以上服务在 <I>sampleBanking-services.xml</I> 中注册，然后装入 <I>web.xml</I> 文件中，就像 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#loadcfgfile"><FONT color=#996699>前面讨论的那样</FONT></A>。控制器和服务配置好后，这个简单的应用程序就完成了。现在我们来看看部署和测试它时会发生什么!</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDAQGCUB><SPAN class=atitle><FONT face=Arial size=4>部署应用程序</FONT></SPAN></A></P>
<P>我把示例应用程序部署在 Tomcat servlet 容器中。Tomcat 是 Java Servlet 和 Java ServerPagest 技术的官方参考实现中使用的 servlet 容器。如果以前没这么做过，请 <A href="http://jakarta.apache.org/site/downloads/downloads_tomcat-5.cgi" target=_new><FONT color=#5c81a7>下载 jakarta-tomcat-5.0.28.exe</FONT></A> 并运行它把 Tomcat 安装到自己喜欢的任何位置，例如 <CODE>c:\tomcat5.0</CODE>。</P>
<P>接下来，<A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#download"><FONT color=#996699>下载示例代码</FONT></A> 并释放到驱动器（例如 <I>c:\</I> ）上。创建了 Spring 项目的文件夹之后，打开它并把 <I>spring-banking</I> 子文件夹拷贝到 <I>c:\tomvat5.0\webapps</I>。spring-banking 文件夹是一个 Web 档案，里面包含 Spring MVC 示例应用程序。lib 文件夹包含应用程序需要的 Spring 框架、与Spring 相关的 MVC 库以及 JSTL 标记库和 jar 文件。</P>
<P>要启动 Tomcat 服务器，请使用以下命令：</P><CODE>cd bin C:\Tomcat 5.0\bin&gt; catalina.bat start</CODE> 
<P>Tomcat 应当启动并部署 Spring MVC 示例应用程序。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDASHCUB><SPAN class=atitle><FONT face=Arial size=4>测试应用程序</FONT></SPAN></A></P>
<P>要测试应用程序，请打开 Web 浏览器，指向 http://localhost:<I>tomcatport</I>/springbanking 并用 Tomcat 服务器实际运行的端口替换 <I>tomcatport</I>。应当看到图 1 所示的登录屏幕。输入用户 ID “admin”和口令“password”，并按下登录按钮。其他用户 ID 或口令会造成来自验证服务的错误。</P><BR><A name="spring framework"><B>图 1. Spring MVC 示例登录屏幕</B></A><BR><IMG height=445 alt="Spring MVC 示例登录屏幕的截屏" src="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/image1.jpg" width=600><BR>
<P>登录成功之后，会看到图 2 所示的帐户细节页面。</P><BR><A name="spring framework"><B>图 2. Spring MVC 示例帐户细节页面</B></A><BR><IMG height=200 alt="Spring MVC 示例帐户细节页面的截屏" src="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/image2.jpg" width=600><BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDA1ICUB><SPAN class=atitle><FONT face=Arial size=4>结束语</FONT></SPAN></A></P>
<P>在三部分的 <I><A href="http://www.ibm.com/developerworks/views/web/libraryview.jsp?search_by=The+Spring+series" target=_new><FONT color=#5c81a7>Spring 系列</FONT></A></I> 的第三篇文章中，我介绍了 Spring MVC 框架的特性。我演示了如何配置和开发 Spring MVC 应用程序、如何配置 Spring MVC 控制器和向其中插入依赖项、如何用 JavaServer Pages 技术开发应用程序视图，以及如何把自己的页面与 Spring MVC 的视图层集成。总结这篇文章时，我演示了如何在 Tomcat servlet 容器中部署应用程序以及如何在浏览器中测试它。</P>
<P>请继续关注 <I>Spring 系列</I> 的下一篇文章。在下一篇文章中，我将介绍如何把基于 JMS 的应用程序与 Spring 框架集成。同时，请参阅 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#resources"><FONT color=#996699>参考资料</FONT></A> 学习更多有关 Spring 框架和 Spring MVC 的内容。</P><BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><SPAN class=atitle><A name=download><FONT face=Arial size=4>下载</FONT></A></SPAN></P>
<TABLE class=data-table-1 cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TH>描述</TH>
<TH>名字</TH>
<TH style="TEXT-ALIGN: right">大小</TH>
<TH>&nbsp;下载方法</TH></TR>
<TR>
<TD class=tb-row>Example source code, spring files, jar files</TD>
<TD noWrap>wa-spring3-SpringProjectPart3.zip</TD>
<TD style="TEXT-ALIGN: right" noWrap>1966 KB</TD>
<TD noWrap>&nbsp;<A class=fbox href="ftp://www6.software.ibm.com/software/developer/library/wa-spring2-SpringProjectPart2.zip"><B><FONT color=#5c81a7>FTP</FONT></B></A></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR vAlign=top>
<TD colSpan=5><FONT color=#5c81a7><IMG height=12 alt="" src="http://www.ibm.com/i/c.gif" width=12 border=0></FONT></TD></TR>
<TR>
<TD><FONT color=#5c81a7><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" width=16></FONT></TD>
<TD><A class=fbox href="http://www-128.ibm.com/developerworks/cn/whichmethod.html"><FONT color=#5c81a7>关于下载方法的信息</FONT></A></TD>
<TD><FONT color=#5c81a7><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=50></FONT></TD>
<TD><FONT color=#5c81a7><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/sout.gif" width=16></FONT></TD>
<TD><A class=fbox href="http://www.adobe.com/products/acrobat/readstep2.html"><FONT color=#5c81a7>获取 Adobe® Reader®</FONT></A></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><FONT color=#5c81a7><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></FONT></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><FONT color=#5c81a7><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></FONT></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=resources><SPAN class=atitle><FONT face=Arial size=4>参考资料 </FONT></SPAN></A></P><B>学习</B><BR>
<UL>
<LI>您可以参阅本文在 developerWorks 全球站点上的 <A href="http://www.ibm.com/developerworks/web/library/wa-spring3/" target=_blank><FONT color=#5c81a7>英文原文</FONT></A>。<BR><BR>
<LI>“<A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/"><FONT color=#996699>Spring 系列，第 1 部分: Spring 框架简介</FONT></A>”（developerWorks，2005 年 6 月）和“<A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/"><FONT color=#996699>Spring 系列，第 2 部分: 当 Hibernate 遇上 Spring</FONT></A>” （developerWorks，2005 年 8 月）：介绍了如何用 Spring 技术构建轻量级的、健壮的 J2EE 应用程序以及如何把 Hibernate 事务与 Spring 的面向方面编程（AOP）集成形成可靠的持久性框架。<BR><BR>
<LI>“<A href="http://www-128.ibm.com/developerworks/cn/java/j-aopwork1"><FONT color=#5c81a7>AOP@Work: AOP 工具比较，第 1 部分</FONT></A>”（Mik Kersten，developerWorks，2005 年 2 月）：比较了 Spring AOP 和 AOP 框架。<BR><BR>
<LI>“<A href="http://www-128.ibm.com/developerworks/cn/opensource/os-lightweight3/"><FONT color=#5c81a7>轻量级开发的成功秘诀，第 3 部分: Spring 露出水面</FONT></A>”（Bruce Tate，developerWorks，2005 年 6 月）：演示了 Spring 作为轻量级容器的意义。<BR><BR>
<LI>“<A href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails"><FONT color=#5c81a7>Ruby on Rails 和 J2EE：两者能否共存？</FONT></A>”（Aaron Rustad， developerWorks，2005 年 7 月）：比较了不太为人所知的 J2EE 框架替代品，像 EJB 和 Spring。<BR><BR>
<LI><A href="http://www.ibm.com/developerworks/java/"><FONT color=#5c81a7>Java 技术专区</FONT></A>：有数百篇文章，覆盖基于 Java Web 的解决方案。</LI></UL><BR><B>获得产品和技术</B><BR>
<UL>
<LI><A href="http://prdownloads.sourceforge.net/springframework/"><FONT color=#5c81a7>Spring 主页</FONT></A>：下载 Spring 框架。<BR><BR>
<LI><A href="http://ant.apache.org/"><FONT color=#5c81a7>Ant 主页</FONT></A>：下载 Apache Ant。<BR><BR></LI></UL><BR><B>讨论</B><BR>
<UL>
<LI>加入本文的<A href="javascript:void forumWindow()"><FONT color=#5c81a7>论坛</FONT></A> 。(您也可以通过点击文章顶部或者底部的论坛链接参加讨论。)<BR><BR>
<LI><A href="http://www.ibm.com/developerworks/blogs/"><FONT color=#5c81a7>developerWorks blogs</FONT></A>：加入 developerWorks 社区。 <BR><BR></LI></UL><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring3/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=author><SPAN class=atitle><FONT face=Arial size=4>关于作者</FONT></SPAN></A></P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD colSpan=2><FONT face=Arial size=4><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></FONT></TD></TR>
<TR vAlign=top align=left>
<TD>
<P><FONT face=Arial size=4></FONT></P></TD>
<TD>
<P>Naveen Balani 把他的大部分时间花在设计和开发基于 J2EE 的框架和产品上。他为 IBM developerWorks 撰写了各类文章，涉及的主题有 ESB、SOA、JMS、Web 服务架构、CICS、AXIS、DB2、XML Extender、WebSphere Studio、MQSeries、Java 无线设备和 DB2 Everyplace for Palm、J2ME、MIDP、Java-Nokia、Visual Studio .Net 以及无线数据同步。可以给他发邮件，他的地址是：<A href="mailto:naveenbalani@rediffmail.com?cc=htc@us.ibm.com"><FONT color=#5c81a7>naveenbalani@rediffmail.com</FONT></A> 。</P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.cnitblog.com/rukas/aggbug/4648.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-17 23:20 <a href="http://www.cnitblog.com/rukas/archive/2005/11/17/4648.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 系列，第 2 部分: 当 Hibernate 遇上 Spring</title><link>http://www.cnitblog.com/rukas/archive/2005/11/17/4647.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Thu, 17 Nov 2005 15:10:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/17/4647.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4647.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/17/4647.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4647.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4647.html</trackback:ping><description><![CDATA[<BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width="100%">
<P id=subtitle>Hibernate 事务天生适合 Spring AOP</P><IMG class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></TD>
<TD class=no-print width=192><IMG height=18 alt=developerWorks src="http://www-128.ibm.com/developerworks/cn/i/dw.gif" width=192></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD width="100%">
<TABLE class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0>
<TBODY>
<TR>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD class=v14-header-1-small>文档选项</TD></TR></TBODY></TABLE>
<TABLE class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=no-padding width=150>
<TABLE cellSpacing=0 cellPadding=0 width=143 border=0><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8> 
<FORM name=email action=https://www-130.ibm.com/developerworks/secure/email-it.jsp><INPUT type=hidden value="Naveen Balani 继续他的 Spring 系列，介绍把 Hibernate 事务与 Spring 面向方面编程（AOP）集成的知识。结果是一个可以依靠的持久性框架。" name=body><INPUT type=hidden value="Spring 系列，第 2 部分: 当 Hibernate 遇上 Spring" name=subject><INPUT type=hidden value=cn name=lang>
<SCRIPT language=JavaScript type=text/javascript>
<!--
document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td><td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td><td width="122"><p><a class="smallplainlink" href="javascript:document.email.submit();"><b>将此页作为电子邮件发送</b></a></p></td></tr>');
//-->
</SCRIPT>
 
<TBODY>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD width=16><IMG height=16 alt=将此页作为电子邮件发送 src="http://www.ibm.com/i/v14/icons/em.gif" width=16 vspace=3></TD>
<TD width=122>
<P><A class=smallplainlink href="javascript:document.email.submit();"><B><FONT color=#5c81a7 size=2>将此页作为电子邮件发送</FONT></B></A></P></TD></TR><NOSCRIPT>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="//www.ibm.com/i/c.gif" width=8></TD>
<TD width=16><IMG height=16 alt="" src="//www.ibm.com/i/c.gif" width=16></TD>
<TD class=small width=122>
<P><SPAN class=ast>未显示需要 JavaScript 的文档选项</SPAN></P></TD></TR></NOSCRIPT></FORM>
<TR vAlign=top>
<TD width=8><FONT color=#5c81a7 size=2><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></FONT></TD>
<TD width=16><FONT color=#5c81a7 size=2><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/dn.gif" width=16 vspace=3 border=0></FONT></TD>
<TD width=122>
<P><A class=smallplainlink href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#download"><B><FONT color=#996699 size=2>样例代码</FONT></B></A></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD class=v14-header-1-small>对此页的评价</TD></TR></TBODY></TABLE>
<TABLE class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=no-padding width=150>
<TABLE cellSpacing=0 cellPadding=0 width=143 border=0>
<TBODY>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/d_bold.gif" width=16 vspace=3 border=0></TD>
<TD width=125>
<P><A class=smallplainlink href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#rate"><B><FONT color=#996699 size=2>帮助我们改进这些内容</FONT></B></A></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE>
<P>级别: 中级</P>
<P><A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#author"><FONT color=#996699>Naveen Balani </FONT></A>, 技术架构师, Webify Solutions<BR></P>
<P>2005 年 9 月 26 日</P>
<BLOCKQUOTE>Naveen Balani 继续他的 Spring 系列，介绍把 Hibernate 事务与 Spring 面向方面编程（AOP）集成的知识。结果是一个可以依靠的持久性框架。</BLOCKQUOTE>
<P>在这个系列的 <A href="http://www.ibm.com/developerworks/cn/java/wa-spring1/" target=_new><FONT color=#5c81a7>前一期中</FONT></A>，我介绍了 Spring 框架的 7 个模块，包括 Spring AOP 和控制反转（IOC）容器。然后我用一个简单的示例演示了 IOC 模式（由 Spring IOC 容器实现）如何用松散耦合的方式集成分散的系统。</P>
<P>现在，我从我上次结束的地方开始，采用与上次类似的示例，演示 Spring AOP 和 Spring Hibernate 持久性支持的声明性事务处理，所以我首先从对这两项技术的深入研究开始。</P>
<P><A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#download"><FONT color=#996699>下载这篇文章的源代码</FONT></A>。请参阅 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#resources"><FONT color=#996699>参考资料</FONT></A> 访问 Spring 框架和 Apache Ant，运行这篇文章的示例应用程序需要它们。</P>
<P><A name=IDAETSW><SPAN class=atitle><FONT face=Arial size=4>Spring AOP</FONT></SPAN></A></P>
<P>软件系统通常由多个组件构成，每个组件负责一个特定的功能领域。但是，这些组件也经常承担它们的核心功能之外的额外责任。系统服务（例如日志、事务管理和安全性）经常发现自己跑到了别的组件的领域里，而这些组件的核心职责是其他事情。结果就是所谓的“代码纠缠”，或者更简单点儿说“一团糟”。面向方面编程是一种试图解决这个问题的编程技术，它把关注点的隔离提升为核心的编程概念。</P>
<P>使用 AOP 时，仍然是在一个地方定义系统的公共功能，但是可以声明性地定义 <I>如何</I> 和 <I>在哪里</I> 应用这个功能。如果对横切关注点（例如日志和事务管理）进行了模块化，那么不用修改每个单独的类，就可以向代码中添加新特性。这类模块化的关注点称作 <I>方面</I>。</P>
<TABLE cellSpacing=0 cellPadding=0 width="40%" align=right border=0>
<TBODY>
<TR>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
<TBODY>
<TR>
<TD bgColor=#eeeeee><A name=IDAUTSW><B>您知道么？</B></A><BR>
<P>可以在任何 Java™ 企业版（J2EE） 服务器中使用 Spring 框架的功能。而且，还可以调整它的大多数功能，使其适合不受控环境。Spring 的中心焦点就是支持不被束缚在特定 J2EEE 服务上的可重用业务和数据访问对象。可以跨 J2EE 环境（Web 或企业 JavaBean（EJB））、独立应用程序、测试环境等等重用这类对象，而不会有任何麻烦。</P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<P>以一个企业应用程序为例。这类应用程序通常要求类似于安全性和事务支持的服务。显然，可以把这些服务的支持直接编写到要求服务的每个类当中，但是更希望能够不必为大量事务性上下文编写同样的事务处理代码。如果使用 Spring AOP 进行事务处理，那么可以声明性地安排适当的方法调用，而不必逐个安排。</P>
<P>Spring AOP 提供了几个方面，可以为 JavaBean 声明事务。例如，<CODE>TransactionProxyFactoryBean</CODE> 是个方便的代理类，能够拦截对现有类的方法调用，并把事务上下文应用到事务 bean。在下面的示例中会看到这个类的实际应用。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDACUSW><SPAN class=atitle><FONT face=Arial size=4>Hibernate</FONT></SPAN></A></P>
<P>Spring 框架提供了对 Hibernate、JDO 和 iBATIS SQL Maps 的集成支持。Spring 对 Hibernate 的支持是第一级的，整合了许多 IOC 的方便特性，解决了许多典型的 Hibernate 集成问题。框架对 Hibernate 的支持符合 Spring 通用的事务和数据访问对象（DAO）异常层次结构。</P>
<P>Spring 为使用选择的 OR 映射层来创建数据访问应用程序提供了支持。因为所有东西都设计成一组可重用 JavaBean，所以不管选择什么技术，都能以库的格式访问大多数 Spring 的 OR 映射支持。 <CODE>ApplicationContext</CODE> 或 <CODE>BeanFactory</CODE> 内部的 OR 映射的好处是简化了配置和部署。</P>
<P>Hibernate 是 Java 平台上一个功能全面的、开源的 OR 映射框架。Hibernate 支持开发符合常规 Java 理念的持久性类 —— 包括关联、继承、多态、复合以及 Java 集合框架。Hibernate 查询语言（HQL）被设计成 SQL 的一个微型面向对象扩展，它是对象和关系世界之间的桥梁。Hibernate 也支持用原始 SQL 或基于 Java 的标准和示例查询表达查询。Hibernate 使用 XML（<I>*.hbm.xml</I>） 文件把 Java 类映射到表，把 JavaBean 属性映射到数据库表。</P>
<P>通过 JDBC 技术，支持所有的 SQL 数据库管理系统。Hibernate 与所有流行的 J2EE 应用程序服务器和 Web 容器都很好地集成。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDAYUSW><SPAN class=atitle><FONT face=Arial size=4>实际示例</FONT></SPAN></A></P>
<P>一个银行应用程序示例可以让您自己看到 Spring AOP 和 Hibernate 一起工作有多么好。银行帐户用例允许用户 （<CODE>Customer</CODE>） 在一个事务中打开一个或多个银行帐户。用户可以申请多个银行帐户，可以选择是支票帐户类型或者是储蓄帐户类型。</P>
<P>应用程序数据库（Cloudscape™）容纳所有客户和帐户信息。在这个例子中，假设在 <CODE>Customer</CODE> 和 <CODE>Account</CODE> 类之间存在 <I>1:N</I> 的关联。在实际生活场景中，关联可能需要按 <I>m:n</I> 建模，才能支持联合帐户。</P>
<P>由于用户必须可以在一个事务中申请多个帐户，所以首先要为数据库交互实现一个 DOA 模式。然后要设置 Spring AOP 的 <CODE>TransactionProxyFactoryBean</CODE>，让它拦截方法调用并声明性地把事务上下文应用到 DOA。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDAYVSW><SPAN class=atitle><FONT face=Arial size=4>Hibernate 实践</FONT></SPAN></A></P>
<P>在 Spring 框架中，像 JDBC <CODE>DataSource</CODE> 或 Hibernate <CODE>SessionFactory</CODE> 这样的资源，在应用程序上下文中可以用 bean 实现。需要访问资源的应用程序对象只需通过 bean 引用得到这类预先定义好的实例的引用即可（这方面的更多内容在 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#analyze"><FONT color=#996699>下一节中</FONT></A>）。在清单 1 中，可以看到示例银行应用程序的一段摘录：XML 应用程序上下文定义显示了如何设置 JDBC <CODE>DataSource</CODE>，并在上面放一个 Hibernate <CODE>SessionFactory</CODE>。</P><BR><A name=code1><B>清单 1. JDBC DataSource 和 HibernateSessionFactory 连接</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>

<FONT face="Lucida Console">&lt;!-- DataSource Property --&gt;
&lt;bean id="exampleDataSource" 
    class="org.apache.commons.dbcp.BasicDataSource"&gt;
 &lt;property name="driverClassName"&gt;
   &lt;value&gt;org.apache.derby.jdbc.EmbeddedDriver&lt;/value&gt;
 &lt;/property&gt;
 &lt;property name="url"&gt;
   &lt;value&gt;jdbc:derby:springexample;create=true&lt;/value&gt;
 &lt;/property&gt;
&lt;/bean&gt; 

&lt;!-- Database Property --&gt;
&lt;bean id="exampleHibernateProperties" 
 class="org.springframework.beans.factory.config.PropertiesFactoryBean"&gt;
 &lt;property name="properties"&gt;
  &lt;props&gt;
   &lt;prop key="hibernate.hbm2ddl.auto"&gt;update&lt;/prop&gt;
   &lt;prop 
    key="hibernate.dialect"&gt;net.sf.hibernate.dialect.DerbyDialect&lt;/prop&gt;
   &lt;prop 
    key="hibernate.query.substitutions"&gt;true 'T', false 'F'&lt;/prop&gt;
   &lt;prop key="hibernate.show_sql"&gt;false&lt;/prop&gt;
   &lt;prop key="hibernate.c3p0.minPoolSize"&gt;5&lt;/prop&gt;
   &lt;prop key="hibernate.c3p0.maxPoolSize"&gt;20&lt;/prop&gt;
   &lt;prop key="hibernate.c3p0.timeout"&gt;600&lt;/prop&gt;
   &lt;prop key="hibernate.c3p0.max_statement"&gt;50&lt;/prop&gt;
   &lt;prop 
     key="hibernate.c3p0.testConnectionOnCheckout"&gt;false&lt;/prop&gt;
  &lt;/props&gt;
 &lt;/property&gt;
&lt;/bean&gt;



&lt;!-- Hibernate SessionFactory --&gt;
&lt;bean id="exampleSessionFactory" 
   class="org.springframework.orm.hibernate.LocalSessionFactoryBean"&gt;
 &lt;property name="dataSource"&gt;
     &lt;ref local="exampleDataSource"/&gt;
 &lt;/property&gt;
 &lt;property name="hibernateProperties"&gt;
     &lt;ref bean="exampleHibernateProperties" /&gt;
 &lt;/property&gt;
 &lt;!--  OR mapping files. --&gt;
 &lt;property name="mappingResources"&gt;
    &lt;list&gt;
       &lt;value&gt;Customer.hbm.xml&lt;/value&gt;
       &lt;value&gt;Account.hbm.xml&lt;/value&gt;
    &lt;/list&gt;
 &lt;/property&gt;


&lt;/bean&gt;

</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P><A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#code1"><FONT color=#996699>清单 1</FONT></A> 显示了如何为示例应用程序数据库（是 Cloudscape）配置数据源 bean （<CODE>exampleDataSource</CODE>）。<CODE>exampleDatasource</CODE> 被连接到 Spring Hibernate 的 <CODE>SessionFactory</CODE>。请注意 <I>*.hbm.xml</I> 指定了示例应用程序的 OR 映射文件。 </P>
<P>数据源和会话工厂设置好之后，下一步就是在 DAO 中连接，在 <CODE>CustomerDAOImpl</CODE> 示例中，要使用 <CODE>SessionFactory</CODE>。接下来，插入 Spring 的 <CODE>TransactionProxyFactoryBean</CODE>，它会拦截对应用程序的 <CODE>CustomerDAOImpl</CODE> 对象的方法调用，并声明性地在它上面应用事务。</P>
<P>在 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/sidefile1.html" target=_new><FONT color=#5c81a7>清单 2</FONT></A> 的这个示例中，<CODE>CustomerDAOImpl</CODE> 类的 <CODE>addCustomer</CODE> 方法是作为事务的一部分执行的，有一个事务属性 <CODE>PROPAGATION_REQUIRED</CODE>。这个属性等价于 EJB 容器的 <CODE>TX_REQUIRED</CODE>。如果想让这个方法一直在事务中运行，可以使用 <CODE>PROPAGATION_REQUIRED</CODE>。如果事务已经在运行，那么 bean 方法会加入事务，否则 Spring 的轻量级事务管理器会启动一个事务。如果想在调用组件服务时总是启动新事务，可以使用 <CODE>PROPAGATION_REQUIRES_NEW</CODE> 属性。</P>
<P>应用程序的连接完成之后，现在来进一步查看源代码。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=analyze><SPAN class=atitle><FONT face=Arial size=4>分析这个!</FONT></SPAN></A></P>
<P>如果以前没这么做过，那么请 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#download"><FONT color=#996699>下载这篇文章的源代码</FONT></A>。把源 zip 文件释放到计算机中的任何位置上，例如 <I>c:\</I>。会创建一个叫作 <I>SpringProjectPart2</I> 的文件夹。<I>src\spring</I> 文件夹包含示例应用程序的 Hibernate 映射文件和 Spring 配置文件。<I>src\springexample\hibernate</I> 文件包含应用程序的源代码。</P>
<P>在这里会发现两个类，即 <CODE>Customer</CODE> 和 <CODE>Account</CODE>，它们用 Hibernate 映射文件映射到两个表。<CODE>Customer</CODE> 类代表客户信息，<CODE>Account</CODE> 代表客户的帐户信息。正如前面提到的，我把这两个类按照 <I>1: N</I> 关系进行建模，即一个 <CODE>Customer</CODE> 可以拥有多个 <CODE>Account</CODE>。清单 3 显示了 <CODE>Customer</CODE> 对象的 Hibernate 映射文件。</P><BR><A name=code3><B>清单 3. Customer 对象的 Hibernate 映射文件</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>

<FONT face="Lucida Console">&lt;?xml version="1.0"?&gt;

&lt;!DOCTYPE hibernate-mapping PUBLIC
         "-//Hibernate/Hibernate Mapping DTD 2.0//EN" 
         "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"&gt;

&lt;hibernate-mapping&gt;
   &lt;class
      name="springexample.hibernate.Customer"
      table="TBL_CUSTOMER"
      dynamic-update="false"
      dynamic-insert="false"&gt;

      &lt;id
         name="id"
         column="CUSTOMER_ID"
         type="java.lang.Long"
         unsaved-value="-1"
      &gt;
         &lt;generator class="native"&gt;
         &lt;/generator&gt;
      &lt;/id&gt;


      &lt;set name ="accounts"
         inverse = "true"
         cascade="all-delete-orphan"&gt;
         &lt;key column ="CUSTOMER_ID"/&gt;
         &lt;one-to-many class="springexample.hibernate.Account"/&gt;

      &lt;/set&gt;


      &lt;property
         name="email"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_EMAIL"
         length="82"
         not-null="true"

      /&gt;

      &lt;property
         name="password"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_PASSWORD"
         length="10"
         not-null="true"

      /&gt;

      &lt;property
         name="userId"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_USERID"
         length="12"
         not-null="true"
         unique="true"

      /&gt;

      &lt;property
         name="firstName"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_FIRSTNAME"
         length="25"
         not-null="true"

      /&gt;

      &lt;property
         name="lastName"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_LASTTNAME"
         length="25"
         not-null="true"
  
      /&gt;

   &lt;/class&gt;


&lt;/hibernate-mapping&gt;
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P><CODE>set name="accounts"</CODE> 和一对多类标签指定了 <CODE>Customer</CODE> 和 <CODE>Account</CODE> 之间的关系。我还在 <I>Account.hbm.xml</I> 文件中定义了 <CODE>Account</CODE> 对象的映射。</P>
<P><CODE>CustomerDAOImpl.java</CODE> 代表应用程序的 DAO，它在应用程序数据库中插入客户和帐户信息。<CODE>CustomerDAOImpl</CODE> 扩展了 Spring 的 <CODE>HibernateDaoSupport</CODE>，它用 Spring HibernateTemplate 简化了会话管理。这样，可以通过 <CODE>getHibernateTemplate()</CODE> 方法保存或检索数据。下面显示的 <CODE>getCustomerAccountInfo()</CODE> 对 <CODE>Customer</CODE> 进行 <I>查找</I>，通过 <CODE>getHibernateTemplate().find</CODE> 方法用 HQL 得到客户的帐户信息，如清单 4 所示。</P><BR><A name=code4><B>清单 4. DAO 实现</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>

<FONT face="Lucida Console">public class CustomerDAOImpl extends HibernateDaoSupport 
           implements CustomerDAO{



  public void addCustomer(Customer customer) {
    getHibernateTemplate().save(customer);
    // TODO Auto-generated method stub

  }

  public Customer getCustomerAccountInfo(Customer customer) {
    Customer cust = null;
    List list = getHibernateTemplate().find("from Customer customer " +
          "where customer.userId = ?" ,
          customer.getUserId(),Hibernate.STRING); 

    if(list.size() &gt; 0){
          cust = (Customer)  list.get(0);
    }

    return cust;


  }

</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>所有这些都应当很容易掌握。现在来看代码的实际应用!</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDA5E2W><SPAN class=atitle><FONT face=Arial size=4>运行应用程序</FONT></SPAN></A></P>
<P>要运行示例应用程序，必须首先 <A href="http://prdownloads.sourceforge.net/springframework/spring-framework-1.2-rc2-with-dependencies.zip?download" target=_new><FONT color=#5c81a7>下载 Spring 框架</FONT></A> 和它的全部依赖文件。接下来，释放框架到某一位置（比如 <I>c:\</I> ），这会创建文件夹 <I>C:\spring-framework-1.2-rc2</I>（针对当前发行版）。在继续之前还必须下载和释放 <A href="http://ant.apache.org/" target=_new><FONT color=#5c81a7>Apache Ant</FONT></A> 和 <A href="https://www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=cloudscape" target=_new><FONT color=#5c81a7>Cloudscape</FONT></A>。下载 Cloudscape 之后，把它释放到 <I>c:\ </I>，这会创建文件夹 <I>C:\Cloudscape_10.0</I>。</P>
<P>接下来，释放源代码到 <I>c:\</I> ，这会创建 <I>SpringProject2</I> 文件夹。接下来修改 <I>build.xml</I> 文件的入口，用实际安装 Spring 的位置代替 <I>C:\spring-framework-1.2-rc2</I>，用实际安装 Cloudscape 的位置代替 <I>C:\Program Files\IBM\Cloudscape_10.0</I>。</P>
<P>打开命令行提示符，进入 <I>SpringProject</I> 目录，在命令行提示符下输入以下命令：<CODE>build</CODE>. </P>
<P>这会构建并运行 <CODE>CreateBankCustomerClient</CODE> 类，它会创建 <CODE>Customer</CODE> 类对象，用数据填充它，创建 <CODE>Account</CODE> 对象，填充它，并把它添加到 <CODE>Customer</CODE> 对象。</P>
<P>然后 <CODE>CreateBankCustomerClient</CODE> 会调用 <CODE>CustomerDAOImpl.addCustomer</CODE> 类，添加客户和帐户信息。一旦插入完成，<CODE>CreateBankCustomerClient</CODE> 会调用 <CODE>CustomerDAOImpl.getCustomerAccountInfo</CODE> 方法，根据 <CODE>userid</CODE> 得到客户和帐户信息。如果 <CODE>CreateBankCustomerClient</CODE> 执行成功，会在控制台上看到打印出 <CODE>userid</CODE>。也可以查询 Cloudscape 数据库检索客户和帐户信息。 </P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=IDAEI2W><SPAN class=atitle><FONT face=Arial size=4>结束语</FONT></SPAN></A></P>
<P>在三部分的 <I>Spring 系列</I> 的第 2 部分中，我介绍了如何集成 Spring Hibernate 和 Spring AOP。结果是一个强健的持久性框架，支持声明性的实现事务。</P>
<P>在这个系列的下一篇，也是最后一篇文章中，我将介绍 Spring 的 MVC 模块，介绍如何用它来简化基于 Web 的应用程序的创建。</P><BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><SPAN class=atitle><A name=download><FONT face=Arial size=4>下载</FONT></A></SPAN></P>
<TABLE class=data-table-1 cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TH>描述</TH>
<TH>名字</TH>
<TH style="TEXT-ALIGN: right">大小</TH>
<TH>&nbsp;下载方法</TH></TR>
<TR>
<TD class=tb-row>Example source code, spring files, build scripts</TD>
<TD noWrap>wa-spring2-SpringProjectPart2.zip</TD>
<TD style="TEXT-ALIGN: right" noWrap>12 KB</TD>
<TD noWrap>&nbsp;<A class=fbox href="ftp://www6.software.ibm.com/software/developer/library/wa-spring2-SpringProjectPart2.zip"><B><FONT color=#5c81a7>FTP</FONT></B></A></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR vAlign=top>
<TD colSpan=5><FONT color=#5c81a7><IMG height=12 alt="" src="http://www.ibm.com/i/c.gif" width=12 border=0></FONT></TD></TR>
<TR>
<TD><FONT color=#5c81a7><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" width=16></FONT></TD>
<TD><A class=fbox href="http://www-128.ibm.com/developerworks/cn/whichmethod.html"><FONT color=#5c81a7>关于下载方法的信息</FONT></A></TD>
<TD><FONT color=#5c81a7><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=50></FONT></TD>
<TD><FONT color=#5c81a7><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/sout.gif" width=16></FONT></TD>
<TD><A class=fbox href="http://www.adobe.com/products/acrobat/readstep2.html"><FONT color=#5c81a7>获取 Adobe® Reader®</FONT></A></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><FONT color=#5c81a7><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></FONT></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><FONT color=#5c81a7><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></FONT></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=resources><SPAN class=atitle><FONT face=Arial size=4>参考资料 </FONT></SPAN></A></P><B>学习</B><BR>
<UL>
<LI>您可以参阅本文在 developerWorks 全球站点上的 <A href="http://www.ibm.com/developerworks/web/library/wa-spring2/" target=_blank><FONT color=#5c81a7>英文原文</FONT></A>。<BR><BR>
<LI>虽然 Spring AOP 提供了独特的优势，但它并不是惟一的 AOP 实现。请阅读“<A href="http://www.ibm.com/developerworks/cn/java/j-aopwork1/"><FONT color=#5c81a7>AOP@Work: AOP 工具比较，第 1 部分</FONT></A>”了解 Spring AOP 的构成（<I>developerWorks</I>，2005 年 2 月）。<BR><BR>
<LI>通过“<A href="http://www-128.ibm.com/developerworks/cn/java/j-hibern/"><FONT color=#5c81a7>无需容器的对象关系映射</FONT></A>”（<I>developerWorks</I>，2004 年 4 月）学习用 Hibernate 和 Spring AOP 开发事务性持久性层。<BR><BR>
<LI><A href="http://www.ibm.com/developerworks/web/"><FONT color=#5c81a7>Web 架构专区</FONT></A> 的文章专门涉及各种基于 Web 的解决方案。</LI></UL><BR><B>获得产品和技术</B><BR>
<UL>
<LI>从 <A href="http://prdownloads.sourceforge.net/springframework/"><FONT color=#5c81a7>Spring 主页</FONT></A> 下载 Spring 框架。<BR><BR>
<LI>从 <A href="http://ant.apache.org/"><FONT color=#5c81a7>Ant 主页</FONT></A> 下载 Apache Ant。<BR><BR></LI></UL><BR><B>讨论</B><BR>
<UL>
<LI>通过参与 <A href="http://www.ibm.com/developerworks/blogs/"><FONT color=#5c81a7>developerWorks blogs</FONT></A> 加入 developerWorks 社区。 <BR><BR></LI></UL><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring2/#main"><B><FONT color=#996699>回页首</FONT></B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=author><SPAN class=atitle><FONT face=Arial size=4>关于作者</FONT></SPAN></A></P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD colSpan=2><FONT face=Arial size=4><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></FONT></TD></TR>
<TR vAlign=top align=left>
<TD>
<P><FONT face=Arial size=4></FONT></P></TD>
<TD>
<P>Naveen Balani 把他的大部分时间花在设计和开发基于 J2EE 的框架和产品上。他为 IBM developerWorks 撰写了各类文章，涉及的主题有 ESB、SOA、JMS、Web 服务架构、CICS、AXIS、DB2、XML Extender、WebSphere Studio、MQSeries、Java 无线设备和 DB2 Everyplace for Palm、J2ME、MIDP、Java-Nokia、Visual Studio .Net 以及无线数据同步。可以给他发邮件，他的地址是：<A href="mailto:naveenbalani@rediffmail.com?cc=htc@us.ibm.com"><FONT color=#5c81a7>naveenbalani@rediffmail.com</FONT></A> 。</P></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE><img src ="http://www.cnitblog.com/rukas/aggbug/4647.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-17 23:10 <a href="http://www.cnitblog.com/rukas/archive/2005/11/17/4647.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 系列，第 1 部分: Spring 框架简介</title><link>http://www.cnitblog.com/rukas/archive/2005/11/17/4646.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Thu, 17 Nov 2005 14:53:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/17/4646.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4646.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/17/4646.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4646.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4646.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width="100%">
<H1><SPAN style="COLOR: #999999">Spring 系列: </SPAN>Spring 框架简介</H1>
<P id=subtitle><EM>Spring AOP 和 IOC 容器入门</EM></P><IMG class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></TD>
<TD class=no-print width=192><IMG height=18 alt=developerWorks src="http://www-128.ibm.com/developerworks/i/dw.gif" width=192></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD width="100%">
<TABLE class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0>
<TBODY>
<TR>
<TD width=10><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></TD>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD class=v14-header-1-small>文档选项</TD></TR></TBODY></TABLE>
<TABLE class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=no-padding width=150>
<TABLE cellSpacing=0 cellPadding=0 width=143 border=0><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8> 
<FORM name=email action=https://www-130.ibm.com/developerworks/secure/email-it.jsp><INPUT type=hidden value="在这由三部分组成的介绍 Spring 框架的系列文章的第一期中，将开始学习如何用 Spring 技术构建轻量级的、强壮的 J2EE 应用程序。" name=body><INPUT type=hidden value="Spring 系列: Spring 框架简介" name=subject><INPUT type=hidden value=cn name=lang>
<SCRIPT language=JavaScript type=text/javascript>
<!--
document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td><td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td><td width="122"><p><a class="smallplainlink" href="javascript:document.email.submit();"><b>将此页作为电子邮件发送</b></a></p></td></tr>');
//-->
</SCRIPT>
 
<TBODY>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD width=16><IMG height=16 alt=将此页作为电子邮件发送 src="http://www.ibm.com/i/v14/icons/em.gif" width=16 vspace=3></TD>
<TD width=122>
<P><A class=smallplainlink href="javascript:document.email.submit();"><B>将此页作为电子邮件发送</B></A></P></TD></TR><NOSCRIPT><tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img src="//www.ibm.com/i/c.gif" height="16" width="16" alt="" /></td><td width="122" class="small"><p><span class="ast">未显示需要 JavaScript 的文档选项</span></p></td></tr></NOSCRIPT></FORM>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD width=16><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/dn.gif" width=16 vspace=3 border=0></TD>
<TD width=122>
<P><A class=smallplainlink href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#download"><B>Sample code</B></A></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD class=v14-header-1-small>对此页的评价</TD></TR></TBODY></TABLE>
<TABLE class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=no-padding width=150>
<TABLE cellSpacing=0 cellPadding=0 width=143 border=0>
<TBODY>
<TR vAlign=top>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></TD>
<TD><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/d_bold.gif" width=16 vspace=3 border=0></TD>
<TD width=125>
<P><A class=smallplainlink href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#rate"><B>帮助我们改进这些内容</B></A></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE>
<P>级别: 初级</P>
<P><A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#author">Naveen Balani </A>, 技术架构师, Webify Solutions<BR></P>
<P>2005 年 8 月 18 日</P>
<BLOCKQUOTE>在这由三部分组成的介绍 Spring 框架的系列文章的第一期中，将开始学习如何用 Spring 技术构建轻量级的、强壮的 J2EE 应用程序。developerWorks 的定期投稿人 Naveen Balani 通过介绍 Spring 框架开始了他由三部分组成的 <I>Spring 系列</I>，其中还将介绍 Spring 面向方面的编程（AOP）和控制反转（IOC）容器。</BLOCKQUOTE>
<P>Spring 是一个开源框架，是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构，分层架构允许您选择使用哪一个组件，同时为 J2EE 应用程序开发提供集成的框架。</P>
<P>在这篇由三部分组成的 <I>Spring 系列</I> 的第 1 部分中，我将介绍 Spring 框架。我先从框架底层模型的角度描述该框架的功能，然后将讨论两个最有趣的模块：Spring 面向方面编程（AOP）和控制反转 （IOC） 容器。接着将使用几个示例演示 IOC 容器在典型应用程序用例场景中的应用情况。这些示例还将成为本系列后面部分进行的展开式讨论的基础，在本文的后面部分，将介绍 Spring 框架通过 Spring AOP 实现 AOP 构造的方式。</P>
<P>请参阅 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#download">下载</A>，下载 Spring 框架和 Apache Ant，运行本系列的示例应用程序需要它们。</P>
<P><A name=1><SPAN class=atitle><FONT face=Arial size=4>Spring 框架</FONT></SPAN></A></P>
<P>Spring 框架是一个分层架构，由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上，核心容器定义了创建、配置和管理 bean 的方式，如图 1 所示。</P><BR><A name=fig1><B>图 1. Spring 框架的 7 个模块</B></A><BR><IMG height=288 alt="Spring 框架图示" src="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/spring_framework.gif" width=555><BR>
<P>组成 Spring 框架的每个模块（或组件）都可以单独存在，或者与其他一个或多个模块联合实现。每个模块的功能如下： 
<UL>
<LI><B>核心容器</B>：核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 <CODE>BeanFactory</CODE>，它是工厂模式的实现。<CODE>BeanFactory</CODE> 使用<I>控制反转</I> （IOC） 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。 
<LI><B>Spring 上下文</B>：Spring 上下文是一个配置文件，向 Spring 框架提供上下文信息。Spring 上下文包括企业服务，例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。 
<LI><B>Spring AOP</B>：通过配置管理特性，Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以，可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP，不用依赖 EJB 组件，就可以将声明性事务管理集成到应用程序中。 
<LI><B>Spring DAO</B>：JDBC DAO 抽象层提供了有意义的异常层次结构，可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理，并且极大地降低了需要编写的异常代码数量（例如打开和关闭连接）。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。 
<LI><B>Spring ORM</B>：Spring 框架插入了若干个 ORM 框架，从而提供了 ORM 的对象关系工具，其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。 
<LI><B>Spring Web 模块</B>：Web 上下文模块建立在应用程序上下文模块之上，为基于 Web 的应用程序提供了上下文。所以，Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。 
<LI><B>Spring MVC 框架</B>：MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口，MVC 框架变成为高度可配置的，MVC 容纳了大量视图技术，其中包括 JSP、Velocity、Tiles、iText 和 POI。</LI></UL>
<P></P>
<P>Spring 框架的功能可以用在任何 J2EE 服务器中，大多数功能也适用于不受管理的环境。Spring 的核心要点是：支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问，这样的对象可以在不同 J2EE 环境 （Web 或 EJB）、独立应用程序、测试环境之间重用。 </P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=2><SPAN class=atitle><FONT face=Arial size=4>IOC 和 AOP</FONT></SPAN></A></P>
<P>控制反转模式（也称作依赖性介入）的基本概念是：不创建对象，但是描述创建它们的方式。在代码中不直接与对象和服务连接，但在配置文件中描述哪一个组件需要哪一项服务。容器 （在 Spring 框架中是 IOC 容器） 负责将这些联系在一起。</P>
<P>在典型的 IOC 场景中，容器创建了所有对象，并设置必要的属性将它们连接在一起，决定什么时间调用方法。下表列出了 IOC 的一个实现模式。</P>
<TABLE cellSpacing=4 cellPadding=2 width="80%" border=1>
<TBODY>
<TR vAlign=top>
<TD>类型 1</TD>
<TD>服务需要实现专门的接口，通过接口，由对象提供这些服务，可以从对象查询依赖性（例如，需要的附加服务）</TD></TR>
<TR vAlign=top>
<TD>类型 2</TD>
<TD>通过 JavaBean 的属性（例如 setter 方法）分配依赖性</TD></TR>
<TR vAlign=top>
<TD>类型 3</TD>
<TD>依赖性以构造函数的形式提供，不以 JavaBean 属性的形式公开</TD></TR></TBODY></TABLE>
<P>Spring 框架的 IOC 容器采用类型 2 和类型3 实现。</P>
<P><A name=IDAUFYMB><SPAN class=smalltitle>面向方面的编程</SPAN></A></P>
<P><I>面向方面的编程</I>，即 AOP，是一种编程技术，它允许程序员对横切关注点或横切典型的职责分界线的行为（例如日志和事务管理）进行模块化。AOP 的核心构造是<I>方面</I>，它将那些影响多个类的行为封装到可重用的模块中。</P>
<P>AOP 和 IOC 是补充性的技术，它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中，可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中，可以反过来将日志服务<I>模块化</I>，并以声明的方式将它们应用到需要日志的组件上。当然，优势就是 Java 类不需要知道日志服务的存在，也不需要考虑相关的代码。所以，用 Spring AOP 编写的应用程序代码是松散耦合的。</P>
<P>AOP 的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=3><SPAN class=atitle><FONT face=Arial size=4>IOC 容器</FONT></SPAN></A></P>
<P>Spring 设计的核心是 <CODE>org.springframework.beans</CODE> 包，它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用，而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 <CODE>BeanFactory</CODE> 接口，它是工厂设计模式的实现，允许通过名称创建和检索对象。<CODE>BeanFactory</CODE> 也可以管理对象之间的关系。</P>
<P><CODE>BeanFactory</CODE> 支持两个对象模型。</P>
<UL>
<LI><B>单态</B> 模型提供了具有特定名称的对象的共享实例，可以在查询时对其进行检索。Singleton 是默认的也是最常用的对象模型。对于无状态服务对象很理想。 
<LI><B>原型</B> 模型确保每次检索都会创建单独的对象。在每个用户都需要自己的对象时，原型模型最适合。</LI></UL>
<P>bean 工厂的概念是 Spring 作为 IOC 容器的基础。IOC 将处理事情的责任从应用程序代码转移到框架。正如我将在下一个示例中演示的那样，Spring 框架使用 JavaBean 属性和配置数据来指出必须设置的依赖关系。</P>
<P><A name=IDAFHYMB><SPAN class=smalltitle>BeanFactory 接口</SPAN></A></P>
<P>因为 <CODE>org.springframework.beans.factory.BeanFactory</CODE> 是一个简单接口，所以可以针对各种底层存储方法实现。最常用的 <CODE>BeanFactory</CODE> 定义是 <CODE>XmlBeanFactory</CODE>，它根据 XML 文件中的定义装入 bean，如清单 1 所示。</P><BR><A name=IDAZHYMB><B>清单 1. XmlBeanFactory</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console" size=2>BeanFactory factory = new XMLBeanFactory(new FileInputSteam("mybean.xml"));
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>在 XML 文件中定义的 Bean 是被消极加载的，这意味在需要 bean 之前，bean 本身不会被初始化。要从 <CODE>BeanFactory</CODE> 检索 bean，只需调用 <CODE>getBean()</CODE> 方法，传入将要检索的 bean 的名称即可，如清单 2 所示。</P><BR><A name=IDAPAANB><B>清单 2. getBean()</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console" size=2>MyBean mybean = (MyBean) factory.getBean("mybean");
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>每个 bean 的定义都可以是 POJO （用类名和 JavaBean 初始化属性定义） 或 <CODE>FactoryBean</CODE>。<CODE>FactoryBean</CODE> 接口为使用 Spring 框架构建的应用程序添加了一个间接的级别。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=4><SPAN class=atitle><FONT face=Arial size=4>IOC 示例</FONT></SPAN></A></P>
<P>理解控制反转最简单的方式就是看它的实际应用。在对由三部分组成的 <I>Spring 系列</I> 的第 1 部分进行总结时，我使用了一个示例，演示了如何通过 Spring IOC 容器注入应用程序的依赖关系（而不是将它们构建进来）。</P>
<P>我用开启在线信用帐户的用例作为起点。对于该实现，开启信用帐户要求用户与以下服务进行交互： 
<UL>
<LI>信用级别评定服务，查询用户的信用历史信息。 
<LI>远程信息链接服务，插入客户信息，将客户信息与信用卡和银行信息连接起来，以进行自动借记（如果需要的话）。 
<LI>电子邮件服务，向用户发送有关信用卡状态的电子邮件。</LI></UL>
<P></P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=5><SPAN class=atitle><FONT face=Arial size=4>三个接口</FONT></SPAN></A></P>
<P>对于这个示例，我假设服务已经存在，理想的情况是用松散耦合的方式把它们集成在一起。以下清单显示了三个服务的应用程序接口。</P><BR><A name=IDAZBANB><B>清单 3. CreditRatingInterface</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console" size=2>public interface CreditRatingInterface {

   public boolean getUserCreditHistoryInformation(ICustomer iCustomer);

}
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>清单 3 所示的信用级别评定接口提供了信用历史信息。它需要一个包含客户信息的 <CODE>Customer</CODE> 对象。该接口的实现是由 <CODE>CreditRating</CODE> 类提供的。</P><BR><A name=IDAMCANB><B>清单 4. CreditLinkingInterface</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>

<FONT face="Lucida Console" size=2>public interface CreditLinkingInterface {

public String getUrl();

		public void setUrl(String url);

		public void linkCreditBankAccount() throws Exception ;

}
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P>信用链接接口将信用历史信息与银行信息（如果需要的话）连接在一起，并插入用户的信用卡信息。信用链接接口是一个远程服务，它的查询是通过 <CODE>getUrl()</CODE> 方法进行的。URL 由 Spring 框架的 bean 配置机制设置，我稍后会讨论它。该接口的实现是由 <CODE>CreditLinking</CODE> 类提供的。</P><BR><A name=IDA5CANB><B>清单 5. EmailInterface</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>

<FONT face="Lucida Console" size=2>public interface EmailInterface {

      public void sendEmail(ICustomer iCustomer);

      public String getFromEmail();

      public void setFromEmail(String fromEmail) ;

      public String getPassword();

      public void setPassword(String password) ;

      public String getSmtpHost() ;

      public void setSmtpHost(String smtpHost);

      public String getUserId() ;

      public void setUserId(String userId);
   }
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR>
<P><CODE>EmailInterface</CODE> 负责向客户发送关于客户信用卡状态的电子邮件。邮件配置参数（例如 SMPT 主机、用户名、口令）由前面提到的 bean 配置机制设置。<CODE>Email</CODE> 类提供了该接口的实现。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=6><SPAN class=atitle><FONT face=Arial size=4>Spring 使其保持松散</FONT></SPAN></A></P>
<P>这些接口就位之后，接下来要考虑的就是如何用松散耦合方式将它们集成在一起。在 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/listing1.html">清单 6</A> 中可以看到信用卡帐户用例的实现。</P>
<P>注意，所有的 setter 方法都是由 Spring 的配置 bean 实现的。所有的依赖关系 （也就是三个接口）都可以由 Spring 框架用这些 bean 注入。<CODE>createCreditCardAccount()</CODE> 方法会用服务去执行其余实现。在 <A href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/listing2.html">清单 7 </A>中可以看到 Spring 的配置文件。我用箭头突出了这些定义。 </P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=7><SPAN class=atitle><FONT face=Arial size=4>运行应用程序</FONT></SPAN></A></P>
<P>要运行示例应用程序，首先必须 <A href="http://prdownloads.sourceforge.net/springframework/spring-%20framework-1.2-rc2-with-dependencies.zip?download" target=_new>下载 Spring 框架</A> 及其所有依赖文件。接下来，将框架释放到（比如说）磁盘 <I>c:\</I>，这会创建 <I>C:\spring-framework-1.2-rc2</I> （适用于当前发行版本） 这样的文件夹。在继续后面的操作之前，还必须下载和释放 <A href="http://ant.apache.org/" target=_new>Apache Ant</A>。</P>
<P>接下来，将源代码释放到文件夹，例如 <I>c:\</I> 盘，然后创建 <I>SpringProject</I>。将 Spring 库（即 <I>C:\spring-framework-1.2-rc2\dist</I> 下的 <I>spring.jar</I> 和 <I>C:\spring-framework-1.2-rc2\lib\jakarta-commons</I> 下的 <I>commons-logging.jar</I>）复制到 <I>SpringProject\lib</I> 文件夹中。完成这些工作之后，就有了必需的构建依赖关系集。</P>
<P>打开命令提示符，将当前目录切换到 <I>SpringProject</I>，在命令提示符中输入以下命令：<CODE>build</CODE>。 </P>
<P>这会构建并运行 <CODE>CreateCreditAccountClient</CODE> 类，类的运行将创建 <CODE>Customer</CODE> 类对象并填充它，还会调用 <CODE>CreateCreditCardAccount</CODE> 类创建并链接信用卡帐户。<CODE>CreateCreditAccountClient</CODE> 还会通过 <CODE>ClassPathXmlApplicationContext</CODE> 装入 Spring 配置文件。装入 bean 之后，就可以通过 <CODE>getBean()</CODE> 方法访问它们了，如清单 8 所示。</P><BR><A name=code8><B>清单 8. 装入 Spring 配置文件</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>
<FONT face="Lucida Console" size=2>ClassPathXmlApplicationContext appContext = 
                    new ClassPathXmlApplicationContext(new String[] {
     "springexample-creditaccount.xml"
    });

CreateCreditCardAccountInterface creditCardAccount = 
                    (CreateCreditCardAccountInterface)
	appContext.getBean("createCreditCard");
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><FONT face="Lucida Console" size=2><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></FONT></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><FONT face="Lucida Console" size=2><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></FONT></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=8><SPAN class=atitle><FONT face=Arial size=4>结束语</FONT></SPAN></A></P>
<P>在这篇由三部分组成的 <I>Spring 系列</I> 的第一篇文章中，我介绍了 Spring 框架的基础。我从讨论组成 Spring 分层架构的 7 个模块开始，然后深入介绍了其中两个模块：Spring AOP 和 IOC 容器。</P>
<P>由于学习的最佳方法是实践，所以我用一个工作示例介绍了 IOC 模式 （像 Spring 的 IOC 容器实现的那样）如何用松散耦合的方式将分散的系统集成在一起。在这个示例中可以看到，将依赖关系或服务注入工作中的信用卡帐户应用程序，要比从头开始构建它们容易得多。</P>
<P>请继续关注这一系列的下一篇文章，我将在这里学习的知识基础上，介绍 Spring AOP 模块如何在企业应用程序中提供持久支持，并让您开始了解 Spring MVC 模块和相关插件。 </P><BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><SPAN class=atitle><A name=download><FONT face=Arial size=4>下载</FONT></A></SPAN></P>
<TABLE class=data-table-1 cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TH>描述</TH>
<TH>Name</TH>
<TH style="TEXT-ALIGN: right">Size</TH>
<TH>&nbsp;Download method</TH></TR>
<TR>
<TD class=tb-row>Examples: source code, spring files, build scripts</TD>
<TD noWrap>wa-spring1-SpringProject.zip</TD>
<TD style="TEXT-ALIGN: right" noWrap>9 KB</TD>
<TD noWrap>&nbsp;<A class=fbox href="ftp://www6.software.ibm.com/software/developer/library/wa-spring1-SpringProject.zip"><B>FTP</B></A></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR vAlign=top>
<TD colSpan=5><IMG height=12 alt="" src="http://www.ibm.com/i/c.gif" width=12 border=0></TD></TR>
<TR>
<TD><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" width=16></TD>
<TD><A class=fbox href="http://www-128.ibm.com/developerworks/cn/whichmethod.html">Information about download methods</A></TD>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=50></TD>
<TD><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/sout.gif" width=16></TD>
<TD><A class=fbox href="http://www.adobe.com/products/acrobat/readstep2.html">Get Adobe® Reader®</A></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=resources><SPAN class=atitle><FONT face=Arial size=4>参考资料 </FONT></SPAN></A></P>
<UL>
<LI>您可以参阅本文在 developerWorks 全球站点上的 <A href="http://www.ibm.com/developerworks/web/library/wa-spring1/" target=_blank>英文原文</A> 。<BR><BR>
<LI>虽然 Spring AOP 提供了独特的优势，但它并不是惟一的 AOP 实现。请参阅“<A href="http://www-128.ibm.com/developerworks/cn/java/j-aopwork1/">AOP@Work: AOP 工具比较，第 1 部分</A>”（<I>developerWorks</I>，2005 年 2 月），了解 Spring AOP 的构成。<BR><BR>
<LI>通过“<A href="http://www.ibm.com/developerworks/cn/java/j-hibern/">无需容器的对象关系映射</A>”（<I>developerWorks</I>，2004 年 4 月）学习如何用 Hibernate 和 Spring AOP 开发事务性的持久层（persistence layer）。<BR><BR>
<LI>请从 <A href="http://prdownloads.sourceforge.net/springframework/">Spring homepage</A> 下载 Spring 框架。<BR><BR>
<LI>请从 <A href="http://ant.apache.org/">Ant homepage</A> 下载 Apache Ant。<BR><BR>
<LI>通过参与 <A href="http://www.ibm.com/developerworks/blogs/">developerWorks blogs</A> 加入 developerWorks 社区。<BR><BR>
<LI>还请参阅 <I>developerWorks</I> 上的一些丰富的参考资料： 
<UL>
<LI><A href="http://www.ibm.com/developerworks/web/">Web 架构专区</A> 中的文章专门介绍了各种基于 Web 的解决方案。 
<LI><A href="http://devworks.krcinfo.com/">Developer Bookstore</A> 提供了技术书籍的完整清单，其中包括数百本 Web 相关主题的书籍。</LI></UL><BR></LI></UL><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox href="http://www-128.ibm.com/developerworks/cn/java/wa-spring1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=author><SPAN class=atitle><FONT face=Arial size=4>关于作者</FONT></SPAN></A></P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD colSpan=2><FONT face=Arial size=4><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></FONT></TD></TR>
<TR vAlign=top align=left>
<TD>
<P><FONT face=Arial size=4></FONT></P></TD>
<TD>
<P>Naveen Balani 把他的大多数时间都花在了设计和开发基于 J2EE 的框架和产品上。他为 IBM <I>developerWorks</I> 撰写了各种不同的文章，涉及的主题包括：ESB、SOA、JMS、WebServices Architectures、CICS、AXIS、DB2 XML Extender、WebSphere Studio、MQSeries 和 Java Wireless Devices，以及 DB2 Everyplace for Palm、J2ME、MIDP、Java-Nokia、Visual Studio .Net 和无线数据同步。您可以通过 <A href="mailto:naveenbalani@rediffmail.com?cc=htc@us.ibm.com">naveenbalani@rediffmail.com</A> 与他联系。 </P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.cnitblog.com/rukas/aggbug/4646.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-17 22:53 <a href="http://www.cnitblog.com/rukas/archive/2005/11/17/4646.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Introduction to the Spring Framework</title><link>http://www.cnitblog.com/rukas/archive/2005/11/17/4637.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Thu, 17 Nov 2005 12:58:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/17/4637.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4637.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/17/4637.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4637.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4637.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: May 2005 Discuss this ArticleOther Spring ArticlesSpring Web Flow Spring Webwork 2 Integration Sending Velocity-based E-mail with Spring Tech Talk: Rod Johnson on The Spring Framework, A...&nbsp;&nbsp;<a href='http://www.cnitblog.com/rukas/archive/2005/11/17/4637.html'>阅读全文</a><img src ="http://www.cnitblog.com/rukas/aggbug/4637.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-17 20:58 <a href="http://www.cnitblog.com/rukas/archive/2005/11/17/4637.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>