﻿<?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>BlogJava-风人园-文章分类-Spring</title><link>http://www.blogjava.net/wuxufeng8080/category/12357.html</link><description>弱水三千，只取一瓢，便能解渴；佛法无边，奉行一法，便能得益。</description><language>zh-cn</language><lastBuildDate>Fri, 02 Dec 2011 01:32:17 GMT</lastBuildDate><pubDate>Fri, 02 Dec 2011 01:32:17 GMT</pubDate><ttl>60</ttl><item><title>SSH配置：Hibernate的packagesToScan路径解析分析 (zt)</title><link>http://www.blogjava.net/wuxufeng8080/articles/363835.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Tue, 15 Nov 2011 06:29:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/363835.html</guid><wfw:comment>http://www.blogjava.net/wuxufeng8080/comments/363835.html</wfw:comment><comments>http://www.blogjava.net/wuxufeng8080/articles/363835.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuxufeng8080/comments/commentRss/363835.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuxufeng8080/services/trackbacks/363835.html</trackback:ping><description><![CDATA[1.&nbsp; &lt;property name="packagesToScan" value="<span style="color: #ff0000">com.xxx.entity</span>" /&gt;， 会解析成"classpath*:com/xxx/<span style="color: #0000ff"><span style="color: #ff0000">entity</span>**/*.class</span>"，这个路径可以找出com/xxx/<span style="color: #000000">entity</span>根目录下的类文件 <br /><br />2. &lt;property name="packagesToScan" value="com.xxx.entity<span style="color: #0000ff">.*</span>" /&gt;， 会解析成"classpath*:com/xxx/<span style="color: #0000ff"><span style="color: #0000ff">entity</span>/***/*.class</span>"，这个路径可以找出com/xxx/entity根目录下一级子目录中的类文件，如com/xxx/entity/son/Hi.class ，<span style="color: #ff0000">而不能找出com/xxx/entity目录下的类文件。</span><br /><br />3.&nbsp; &lt;property name="packagesToScan" value="com.xxx.entity<span style="color: #0000ff">.</span>" /&gt;(注意最后的点) ， 会转换成"classpath*:com/xxx/entity<span style="color: #0000ff">/**/*.class</span>"，这个路径可以找出com/xxx/entity根目录下及其子孙目录下所有的类文件. 一般来讲，这些就是我们要的文件。<br /><br />转载自 <a href="http://saberhaha.iteye.com/blog/772083">http://saberhaha.iteye.com/blog/772083</a> <img src ="http://www.blogjava.net/wuxufeng8080/aggbug/363835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2011-11-15 14:29 <a href="http://www.blogjava.net/wuxufeng8080/articles/363835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring MVC异常处理(ZT)</title><link>http://www.blogjava.net/wuxufeng8080/articles/191150.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Mon, 07 Apr 2008 00:15:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/191150.html</guid><wfw:comment>http://www.blogjava.net/wuxufeng8080/comments/191150.html</wfw:comment><comments>http://www.blogjava.net/wuxufeng8080/articles/191150.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wuxufeng8080/comments/commentRss/191150.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuxufeng8080/services/trackbacks/191150.html</trackback:ping><description><![CDATA[Web应用中对于异常的处理方式与其他形式的应用并没有太大的不同――通过try/catch<br />
语句针对不同的异常进行相应处理。<br />
但是在具体实现中，由于异常层次、种类繁杂，我们往往很难在Servlet、JSP层妥善的处<br />
理好所有异常情况，代码中大量的try/catch代码显得尤为凌乱。<br />
我们通常面对下面两个主要问题：<br />
1． 对异常实现集中式处理<br />
典型情况：对数据库异常记录错误日志。一般处理方法无外两种，一是在各处数据库<br />
访问代码的异常处理中，加上日志记录语句。二是将在数据访问代码中将异常向上抛<br />
出，并在上层结构中进行集中的日志记录处理。<br />
第一种处理方法失之繁琐、并且导致系统难以维护，假设后继需求为&#8220;对于数据库异<br />
常，需记录日志，并发送通知消息告知系统管理员&#8221;。我们不得不对分散在系统中的各<br />
处代码进行整改，工作量庞大。<br />
第二种处理方法实现了统一的异常处理，但如果缺乏设计，往往使得上层异常处理过<br />
于复杂。<br />
这里，我们需要的是一个设计清晰、成熟可靠的集中式异常处理方案。<br />
2． 对未捕获异常的处理<br />
对于Unchecked Exception而言，由于代码不强制捕获，往往被程序员所忽略，如果<br />
运行期产生了Unchecked Exception，而代码中又没有进行相应的捕获和处理，则我<br />
们可能不得不面对尴尬的500服务器内部错误提示页面。<br />
这里，我们需要一个全面而有效的异常处理机制。<br />
上面这两个问题，从技术角度上而言并算不上什么大的难点。套用一些短平快的设计模式，<br />
我们也能进行处理并获得不错的效果。同时，目前大多数服务器也都支持在Web.xml中通过<br />
&lt;error-page&gt;（Websphere/Weblogic）或者&lt;error-code&gt;(Tomcat)节点配置特定异常情<br />
况的显示页面。<br />
Spring MVC中提供了一个通用的异常处理机制，它提供了一个成熟的，简洁清晰的异常处<br />
理方案。如果基于Spring MVC开发Web应用，那么利用这套现成的机制进行异常处理也更加自<br />
然和有效。<br />
Spring MVC中的异常处理：<br />
以前面的注册系统为例，首先，在Dispatcher配置文件Config.xml中增加id为<br />
&#8220;exceptionResolver&#8221;的bean定义：<br />
&lt;bean id="exceptionResolver"<br />
class="org.springframework.web.servlet.handler.SimpleMappingEx<br />
ceptionResolver"&gt;<br />
&lt;property name="defaultErrorView"&gt;<br />
&lt;value&gt;failure&lt;/value&gt;<br />
&lt;/property&gt;<br />
&lt;property name="exceptionMappings"&gt;<br />
&lt;props&gt;<br />
&lt;prop key="java.sql.SQLException"&gt;showDBError&lt;/prop&gt;<br />
&lt;prop key="java.lang.RuntimeException"&gt;showError&lt;/prop&gt;<br />
&lt;/props&gt;<br />
&lt;/property&gt;<br />
&lt;/bean&gt;<br />
通过SimpleMappingExceptionResolver我们可以将不同的异常映射到不同的jsp页<br />
面（通过exceptionMappings属性的配置），同时我们也可以为所有的异常指定一个默认的异<br />
常提示页面（通过defaultErrorView属性的配置），如果所抛出的异常在exceptionMappings<br />
中没有对应的映射，则Spring将用此默认配置显示异常信息（注意这里配置的异常显示界面均<br />
仅包括主文件名，至于文件路径和后缀已经在viewResolver中指定）。<br />
一个典型的异常显示页面如下：<br />
&lt;html&gt;<br />
&lt;head&gt;&lt;title&gt;Exception!&lt;/title&gt;&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;% Exception ex = (Exception)request.getAttribute("exception"); %&gt;<br />
&lt;H2&gt;Exception: &lt;%= ex.getMessage();%&gt;&lt;/H2&gt;<br />
&lt;P/&gt;<br />
&lt;% ex.printStackTrace(new java.io.PrintWriter(out)); %&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;<br />
exception 实在SimpleMappingExceptionResolver 被存放到request中的，具体可以查看源代码。<br />
如果SimpleMappingExceptionResolver无法满足异常处理的需要，我们可以针对<br />
HandlerExceptionResolver接口实现自己异常处理类，这同样非常简单（只需要实现一个<br />
resolveException方法）。<br />
<br />
如果有ViewResolver，则制定的jsp页面必须在那个页面下，到时候如果找不到页面，可以根据错误提示再调整页面路径 
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/191150.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2008-04-07 08:15 <a href="http://www.blogjava.net/wuxufeng8080/articles/191150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 2中autowire="byName" /"byType" </title><link>http://www.blogjava.net/wuxufeng8080/articles/101859.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Mon, 05 Mar 2007 03:30:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/101859.html</guid><description><![CDATA[     如果userDAO设置了autowire="byName" ，假设ServiceImpl有一个属性名为userDAO，Spring就会在配置文件里查找有没有名字为userDAO的bean, 自动为ServiceImpl注入。<br />     如果bean有两个属性，一个想默认注入，一个想自定义，只要设定了autowire，然后显式的声明那个想自定义的，就可以达到要求。这就应了需求，在需要特别配置的时候就提供配置，否则给我一个默认注入。<br />    还可以在根部的&lt;beans&gt;节点写一句default-autovwrie="byName"，可以让文件里的所有bean 都默认autowrie。不过有人认为开发期可以这样，但Production Server上不应该使用Autowire。但有人认为那些自定义一次的地方比如TranscationManager应该详细定义，而Dao,Service这种大量重复定义的bean就可以这样做。<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/101859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2007-03-05 11:30 <a href="http://www.blogjava.net/wuxufeng8080/articles/101859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring2.0--单元测试要点 </title><link>http://www.blogjava.net/wuxufeng8080/articles/98819.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Thu, 08 Feb 2007 09:11:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/98819.html</guid><description><![CDATA[今天复习了一下 造福无数人<a href="http://www.redsaga.com/spring_ref/2.0RC2/html/testing.html" target="blank">Spring2.0 参考手册中文翻译--第8章 测试</a>，浓缩即精华的更新了<a href="http://wiki.springside.org.cn/">SpringSide wiki</a>中的--<a href="http://wiki.springside.org.cn/display/springside/SpringUnitTest" target="blank">Spring下的单元测试要点</a>。
<p>     注意，文档还在不断修改中，建议直接看<a href="http://wiki.springside.org.cn/display/springside/SpringUnitTest">Wiki 上的最新版本</a>。</p><h2>1. 需要Spring 依赖注入的测试</h2><p>   为了测试Spring管理下的Bean，可以自行构造BeanFactory，也可以继承于<span class="nobr"><a title="Visit page outside Confluence" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/test/AbstractDependencyInjectionSpringContextTests.html" rel="nofollow">AbstractDependencyInjectionSpringContextTests</a></span>，实现public String[] getConfigLocations()函数， 返回applicationContext文件路径的数组。</p><div class="code"><div class="codeContent"><pre class="code-java"> <span class="code-keyword">protected</span><span class="code-object">String</span>[] getConfigLocations() {        <span class="code-keyword">return</span><span class="code-keyword">new</span><span class="code-object">String</span>[]{<span class="code-quote">"classpath*:spring/*.xml"</span>,  <span class="code-quote">"classpath*:spring/test/*.xml"</span>}; } </pre></div></div><p>  并显式写一些需要注入的变量的setter函数。</p><p>    tips1：此基类有一个applicationContext的成员变量，所以除了依靠setter注入外，还可以随时用applicationContext.getBean() 取出所需的bean。 </p><p>    tips2：注意此基类 默认是autowire by type的，所以如果context文件里有两个相同类型的Bean就会报错，可能需要在getConfigLocations()函数里，setAutowireMode(AUTOWIRE_BY_NAME);把它设回by name，或者取消setter函数，自行用applicationContext.getBean()来显式查找Bean。</p><h2><a name="SpringUnitTest-2.Dao%E6%B5%8B%E8%AF%95"></a>2. Dao测试</h2><p><span class="nobr"><a title="Visit page outside Confluence" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/test/AbstractTransactionalDataSourceSpringContextTests.html" rel="nofollow">AbstractTransactionalDataSourceSpringContextTests</a></span> 继承于AbstractDependencyInjectionSpringContextTests，除了拥有上类的能力外，还管理了每个测试的事务，会在每个测试后默认回滚所有的操作。</p><p>深层解释：此类的实现其实依赖于Application Context中定义的 <tt>PlatformTransactionManager</tt>。由于使用了Autowrie by type，可以任意取名。</p><p>         另依赖于Application Context中定义的<tt>DataSource，同样可以任意取名。</tt> </p><p>tips1：如果需要在测试后提交，需要setRollBack(false); 或者调用setComplete()</p><p>tips2：此基类还通过注入的DataSource创建了一个JDBCTemplate 变量，可以跑SQL帮忙核对Hibernate的结果，Spring将确保该查询在同一个事务内执行。为正常工作你需要告诉你的ORM工具'刷新'它的已改变内容，例如使用Hibernate <tt>Session</tt> 接口的 <tt>flush()</tt> 方法。</p><p>tips3：除了tips2以外，还有countRowsInTable(String tableName)，deleteFromTables(String[] names) ，executeSqlScript(String sqlResourcePath, boolean continueOnError)三个简便函数。</p><h2><a name="SpringUnitTest-3.Controller%E6%B5%8B%E8%AF%95"></a>3. Controller测试</h2><p>Controller测试一般要用MockObject 分离Service层，要copy WEB-INF/下的相关文件copy 到classpath，而且Controller不含太多的逻辑，所有测试controller有点吃力不讨好，建议直接用Selenium进行集成测试，见(<a title="Selenium" href="http://wiki.springside.org.cn/display/springside/Selenium">Selenium测试概述</a>)。</p><h2><a name="SpringUnitTest-4.SpringSide%E9%87%8C%E7%9A%84%E6%B5%8B%E8%AF%95"></a>4.SpringSide里的测试</h2><p>因为Spring默认的基类名字较长，<a href="http://www.springside.org.cn/">SpringSide </a>在core 的org.springside.core.test 中重新继承了它们，并提供了默认读取所有按springside 文件存放规则存放的context 文件的getConfigLocations()函数。</p><p>默认读取所有context文件的getConfigLocations()函数对速度和测试的隔离化都有影响，可以在子类重新实现。不过自己重新一个个写相关context文件也好烦，而且其实在全lazy-load的情况下，速度也还可以接受。如何取舍要自己平衡了。</p><p>对于CRUD的测试，在helloworld示例里的变量名都作了泛化，可以快速copy到另一个测试里。</p><p>另外，留意resources/spring/test 下的文件，利用了Spring的<span class="nobr"><a title="Visit page outside Confluence" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/PropertyOverrideConfigurer.html" rel="nofollow">PropertyOverrideConfigurer<sup><img class="rendericon" height="7" alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a></span>，新设定测试时的ApplicatonContext 里各个Bean的属性如指定测试用的DataSource，详细用法见<a title="SpringConfig" href="http://wiki.springside.org.cn/display/springside/SpringConfig">Spring配置要点</a>。</p><img src ="http://www.blogjava.net/wuxufeng8080/aggbug/98819.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2007-02-08 17:11 <a href="http://www.blogjava.net/wuxufeng8080/articles/98819.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring 中集成 xfire(ZT)</title><link>http://www.blogjava.net/wuxufeng8080/articles/60521.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Fri, 28 Jul 2006 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/60521.html</guid><description><![CDATA[XFire可以很好的集成到Spring中，Spring的代码已经做了这方面的集成。<br />首先，我们先创建我们的Web服务，采用接口和实现类的方式：<br /><br />接口MathService.java：<br /><div class="codeStyle"><ol><li><i><font color="#339900">package com.kuaff.xfire.samples;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">public interface MathService</font></i></li><li></li><li>{
</li><li></li><li><i><font color="#339900">    public long add(int p1, int p2);</font></i></li><li></li><li>}</li></ol></div><br /><br />实现类：<br /><div class="codeStyle"><ol><li><i><font color="#339900">package com.kuaff.xfire.samples;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">public class MathServiceImpl implements MathService</font></i></li><li></li><li>{
</li><li></li><li><i><font color="#339900">    public long add(int p1, int p2)</font></i></li><li></li><li><i><font color="#339900">    {</font></i></li><li></li><li><i><font color="#339900">        return p1 + p2;</font></i></li><li></li><li><i><font color="#339900">    }</font></i></li><li></li><li>}</li></ol></div><br /><br />META-INF/xfire/service.xml文件可以省略了，因为web服务的定义在xfire-servlet.xml中可以找到。<br />下面要做的工具就是配置了。<br />在WEB-INF文件夹下创建applicationContext.xml文件，这是Spring的配置文件，如果你使用其他的Spring配置文件，可以将下面的bean添加到那个配置文件中：<br /><br /><br /><div class="codeStyle"><ol><li><i><font color="#339900">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;beans&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;bean id="mathBean" class="com.kuaff.xfire.samples.MathServiceImpl"/&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;/beans&gt;</font></i></li></ol></div><br /><br />定义了mathBean，这个Bean就是我们的实现类，当然你也可以在这个文件中定义其他的需要Spring管理的bean。<br /><br />在WEB-INF文件夹下创建xfire-servlet.xml文件，根据Spring规范，这个文件名起做xfire-servlet.xml,其中xfire是web.xml配置的DispatcherServlet的名称:<br /><br /><div class="codeStyle"><ol><li><i><font color="#339900">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;beans&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;property name="urlMap"&gt;</font></i></li><li></li><li><i><font color="#339900">            &lt;map&gt;</font></i></li><li></li><li><i><font color="#339900">                &lt;entry key="/MathService"&gt;</font></i></li><li></li><li><i><font color="#339900">                    &lt;ref bean="math"/&gt;</font></i></li><li></li><li><i><font color="#339900">                &lt;/entry&gt;</font></i></li><li></li><li><i><font color="#339900">            &lt;/map&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;/property&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;/bean&gt;</font></i></li><li></li><li><i><font color="#339900">   </font></i></li><li></li><li><i><font color="#339900">    &lt;bean id="math" class="org.codehaus.xfire.spring.remoting.XFireExporter"&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;property name="serviceFactory"&gt;</font></i></li><li></li><li><i><font color="#339900">            &lt;ref bean="xfire.serviceFactory"/&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;/property&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;property name="xfire"&gt;</font></i></li><li></li><li><i><font color="#339900">            &lt;ref bean="xfire"/&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;/property&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;property name="serviceBean"&gt;</font></i></li><li></li><li><i><font color="#339900">            &lt;ref bean="mathBean"/&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;/property&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;property name="serviceClass"&gt;</font></i></li><li></li><li><i><font color="#339900">            &lt;value&gt;com.kuaff.xfire.samples.MathService&lt;/value&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;/property&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;/bean&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;/beans&gt;</font></i></li></ol></div><br /><br />这个文件的上半部分将MathService这个URL和math这个bean联系在一起。下半部分定义了Web服务的bean和服务接口。其中mathBean是我们在applicationContext.xml中配置的那个Bean。<br /><br />最后一步就是修改web.xml文件：<br /><div class="codeStyle"><ol><li><i><font color="#339900">&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">&lt;!DOCTYPE web-app</font></i></li><li></li><li><i><font color="#339900">    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"</font></i></li><li></li><li><i><font color="#339900">    "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;web-app&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;context-param&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;param-value&gt;/WEB-INF/applicationContext.xml</font></i></li><li></li><li><i><font color="#339900">        classpath:org/codehaus/xfire/spring/xfire.xml&lt;/param-value&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;/context-param&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">    &lt;context-param&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;/context-param&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">    &lt;listener&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;/listener&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">    &lt;listener&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;/listener&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">    &lt;servlet&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;servlet-name&gt;xfire&lt;/servlet-name&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;/servlet&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">    &lt;servlet-mapping&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;servlet-name&gt;xfire&lt;/servlet-name&gt;</font></i></li><li></li><li><i><font color="#339900">        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;/servlet-mapping&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;/web-app&gt;</font></i></li></ol></div><br /><br />需要注意这个文件的三个部分：<br /><br /> <br /><br />1．      在定义contextConfigLocation参数时一定要加上classpath:org/codehaus/xfire/spring/xfire.xml。<br /><br />2．      定义listener: org.springframework.web.context.ContextLoaderListener<br /><br />3．      定义DispatcherServlet: xfire<br /><br />这样，你就可以访问http://localhost:8080/xfire/MathService来调用这个Web服务，也可以通过网址http://localhost:8080/xfire/MathService?wsdl来查看wsdl文档。 <img src ="http://www.blogjava.net/wuxufeng8080/aggbug/60521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-07-28 11:28 <a href="http://www.blogjava.net/wuxufeng8080/articles/60521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring--使用quartz实现定时作业 (ZT)</title><link>http://www.blogjava.net/wuxufeng8080/articles/58707.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Tue, 18 Jul 2006 02:58:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/58707.html</guid><description><![CDATA[定时批处理作业是J2EE企业应用里很重要的一环，用来在晚间进行财务挂账，数据转存，新闻联播等等操作。
<p>&nbsp;&nbsp;&nbsp; 而在Spring里，已经很好的集成了Quartz，简单到像配cron一样，在xml文件里面配一下时间就可以自动执行，不需要写一行代码。Spring对Quartz大刀阔斧的简化堪称范例，Quartz项目组也许可以学习一下。</p>
<pre>&nbsp;&nbsp;&nbsp; &lt;bean id="methodInvokingJobDetail"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="targetObject"&gt;&lt;ref bean="financeDAO"/&gt;&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="targetMethod"&gt;&lt;value&gt;confirmOrder&lt;/value&gt;&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</pre>
<pre><br />
&nbsp;&nbsp;&nbsp; &lt;bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="jobDetail"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="methodInvokingJobDetail"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="cronExpression"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;0 0 6,12,20 * * ?&lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</pre>
<pre>&nbsp;&nbsp;&nbsp; &lt;bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="triggers"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt;&lt;ref local="cronTrigger"/&gt;&lt;/list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</pre>
<p>上面这段配置文件规定了在早上6点和晚上8点执行financeDAO对象的confirmOrder()方法.<br />
</p>
<p><br />
附：cronExpression配置说明</p>
<p>&nbsp;</p>
<table cellspacing="8">
    <tbody>
        <tr>
            <th align="left">字段</th>
            <th align="left">&nbsp;</th>
            <th align="left">允许值</th>
            <th align="left">&nbsp;</th>
            <th align="left">允许的特殊字符</th>
        </tr>
        <tr>
            <td align="left"><code>秒</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>0-59</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code></td>
        </tr>
        <tr>
            <td align="left"><code>分</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>0-59</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code></td>
        </tr>
        <tr>
            <td align="left"><code>小时</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>0-23</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code></td>
        </tr>
        <tr>
            <td align="left"><code>日期</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>1-31</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * ? / L W C</code></td>
        </tr>
        <tr>
            <td align="left"><code>月份</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>1-12&nbsp;或者 JAN-DEC</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code></td>
        </tr>
        <tr>
            <td align="left"><code>星期</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>1-7&nbsp;或者 SUN-SAT</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * ? / L C #</code></td>
        </tr>
        <tr>
            <td align="left"><code>年（可选）</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>留空, 1970-2099</code></td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<div class="cnt">"Cron-Expression"与linux中的crontab有很大的不同，昨天差点迷惑了我。 <br />
"Cron-Expression"由6到7个用空格分开的字段组成的表达式这6或7个字段必须遵循下面的顺序和格式： <br />
Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0-59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , - * / <br />
Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0-59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,- * / <br />
Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0-23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , - * / <br />
Day-of-month&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1-31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , - * ? / L W C <br />
Month&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1-12 or JAN-DEC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , - * / <br />
Day-of-Week&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">1-7 or SUN-SAT</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , - * ? / L C # <br />
Year (Optional)&nbsp;&nbsp;&nbsp;&nbsp; empty, 1970-2099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , - * /<br />
*是一个通配符，表示任何值，用在Minutes字段中表示每分钟。<br />
?只可以用在day-of-month或者Day-of-Week字段中，用来表示不指定特殊的值。<br />
-用来表示一个范围，比如10-12用在Month中表示10到12月。<br />
,用来表示附加的值，比如MON,WED,FRI在day-of-week字段中表示礼拜一和礼拜三和礼拜五。<br />
/用来表示增量，比如0/15用在Minutes字段中表示从0分开始0和15和30和45分。<br />
L只可以用在day-of-month或者Day-of-Week字段中，如果用在Day-of-month中，表示某个月的最后一天，1月则是表示31号，2月则表示28号（非闰年），如果用在Day-of-Week中表示礼拜六（数字7）；但是如果L与数字组合在一起用在Day-of-month中，比如6L，则表示某个月的最后一个礼拜六；<br />
C<br />
W<br />
#<br />
<br />
0 1 0 1 1-12 ?表示每月1号0点1分执行。<br />
0 0 21 ? * 1表示每个礼拜天 21点0分执行。<br />
0 0 0 * * ?表示每天0点0分执行。<br />
0 * 22 * * ?表示每天22点开始每分钟<br />
0 * 0-23 * * ?表示每天每分钟</div>
<br />
<br />
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">Cron</span><span style="font-size: 9pt; font-family: 宋体">表达式的时间字段除允许设置数值外，还可使用一些特殊的字符，提供列表、范围、通配符等功能，细说如下：</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt; font-family: 宋体">星号</span><span style="font-size: 9pt">(*)</span><span style="font-size: 9pt; font-family: 宋体">：可用在所有字段中，表示对应时间域的每一个时刻，例如，</span><span style="font-size: 9pt">*</span><span style="font-size: 9pt; font-family: 宋体">在分钟字段时，表示</span><span style="font-size: 9pt">&#8220;</span><span style="font-size: 9pt; font-family: 宋体">每分钟</span><span style="font-size: 9pt">&#8221;</span><span style="font-size: 9pt; font-family: 宋体">；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt; font-family: 宋体">问号（</span><span style="font-size: 9pt">?</span><span style="font-size: 9pt; font-family: 宋体">）：该字符只在日期和星期字段中使用，它通常指定为</span><span style="font-size: 9pt">&#8220;</span><span style="font-size: 9pt; font-family: 宋体">无意义的值</span><span style="font-size: 9pt">&#8221;</span><span style="font-size: 9pt; font-family: 宋体">，相当于点位符；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt; font-family: 宋体">减号</span><span style="font-size: 9pt">(-)</span><span style="font-size: 9pt; font-family: 宋体">：表达一个范围，如在小时字段中使用</span><span style="font-size: 9pt">&#8220;10-12&#8221;</span><span style="font-size: 9pt; font-family: 宋体">，则表示从</span><span style="font-size: 9pt">10</span><span style="font-size: 9pt; font-family: 宋体">到</span><span style="font-size: 9pt">12</span><span style="font-size: 9pt; font-family: 宋体">点，即</span><span style="font-size: 9pt">10,11,12</span><span style="font-size: 9pt; font-family: 宋体">；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt; font-family: 宋体">逗号</span><span style="font-size: 9pt">(,)</span><span style="font-size: 9pt; font-family: 宋体">：表达一个列表值，如在星期字段中使用</span><span style="font-size: 9pt">&#8220;MON,WED,FRI&#8221;</span><span style="font-size: 9pt; font-family: 宋体">，则表示星期一，星期三和星期五；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt; font-family: 宋体">斜杠</span><span style="font-size: 9pt">(/)</span><span style="font-size: 9pt; font-family: 宋体">：</span><span style="font-size: 9pt">x/y</span><span style="font-size: 9pt; font-family: 宋体">表达一个等步长序列，</span><span style="font-size: 9pt">x</span><span style="font-size: 9pt; font-family: 宋体">为起始值，</span><span style="font-size: 9pt">y</span><span style="font-size: 9pt; font-family: 宋体">为增量步长值。如在分钟字段中使用</span><span style="font-size: 9pt">0/15</span><span style="font-size: 9pt; font-family: 宋体">，则表示为</span><span style="font-size: 9pt">0,15,30</span><span style="font-size: 9pt; font-family: 宋体">和</span><span style="font-size: 9pt">45</span><span style="font-size: 9pt; font-family: 宋体">秒，而</span><span style="font-size: 9pt">5/15</span><span style="font-size: 9pt; font-family: 宋体">在分钟字段中表示</span><span style="font-size: 9pt">5,20,35,50</span><span style="font-size: 9pt; font-family: 宋体">，你也可以使用</span><span style="font-size: 9pt">*/y</span><span style="font-size: 9pt; font-family: 宋体">，它等同于</span><span style="font-size: 9pt">0/y</span><span style="font-size: 9pt; font-family: 宋体">；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt">L</span><span style="font-size: 9pt; font-family: 宋体">：该字符只在日期和星期字段中使用，代表</span><span style="font-size: 9pt">&#8220;Last&#8221;</span><span style="font-size: 9pt; font-family: 宋体">的意思，但它在两个字段中意思不同。</span><span style="font-size: 9pt">L</span><span style="font-size: 9pt; font-family: 宋体">在日期字段中，表示这个月份的最后一天，如一月的</span><span style="font-size: 9pt">31</span><span style="font-size: 9pt; font-family: 宋体">号，非闰年二月的</span><span style="font-size: 9pt">28</span><span style="font-size: 9pt; font-family: 宋体">号；如果</span><span style="font-size: 9pt">L</span><span style="font-size: 9pt; font-family: 宋体">用在星期中，则表示星期六，等同于</span><span style="font-size: 9pt">7</span><span style="font-size: 9pt; font-family: 宋体">。但是，如果</span><span style="font-size: 9pt">L</span><span style="font-size: 9pt; font-family: 宋体">出现在星期字段里，而且在前面有一个数值</span><span style="font-size: 9pt">X</span><span style="font-size: 9pt; font-family: 宋体">，则表示</span><span style="font-size: 9pt">&#8220;</span><span style="font-size: 9pt; font-family: 宋体">这个月的最后</span><span style="font-size: 9pt">X</span><span style="font-size: 9pt; font-family: 宋体">天</span><span style="font-size: 9pt">&#8221;</span><span style="font-size: 9pt; font-family: 宋体">，例如，</span><span style="font-size: 9pt">6L</span><span style="font-size: 9pt; font-family: 宋体">表示该月的最后星期五；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt">W</span><span style="font-size: 9pt; font-family: 宋体">：该字符只能出现在日期字段里，是对前导日期的修饰，表示离该日期最近的工作日。例如</span><span style="font-size: 9pt">15W</span><span style="font-size: 9pt; font-family: 宋体">表示离该月</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">号最近的工作日，如果该月</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">号是星期六，则匹配</span><span style="font-size: 9pt">14</span><span style="font-size: 9pt; font-family: 宋体">号星期五；如果</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">日是星期日，则匹配</span><span style="font-size: 9pt">16</span><span style="font-size: 9pt; font-family: 宋体">号星期一；如果</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">号是星期二，那结果就是</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">号星期二。但必须注意关联的匹配日期不能够跨月，如你指定</span><span style="font-size: 9pt">1W</span><span style="font-size: 9pt; font-family: 宋体">，如果</span><span style="font-size: 9pt">1</span><span style="font-size: 9pt; font-family: 宋体">号是星期六，结果匹配的是</span><span style="font-size: 9pt">3</span><span style="font-size: 9pt; font-family: 宋体">号星期一，而非上个月最后的那天。</span><span style="font-size: 9pt">W</span><span style="font-size: 9pt; font-family: 宋体">字符串只能指定单一日期，而不能指定日期范围；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt">LW</span><span style="font-size: 9pt; font-family: 宋体">组合：在日期字段可以组合使用</span><span style="font-size: 9pt">LW</span><span style="font-size: 9pt; font-family: 宋体">，它的意思是当月的最后一个工作日；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt; font-family: 宋体">井号</span><span style="font-size: 9pt">(#)</span><span style="font-size: 9pt; font-family: 宋体">：该字符只能在星期字段中使用，表示当月某个工作日。如</span><span style="font-size: 9pt">6#3</span><span style="font-size: 9pt; font-family: 宋体">表示当月的第三个星期五</span><span style="font-size: 9pt">(6</span><span style="font-size: 9pt; font-family: 宋体">表示星期五，</span><span style="font-size: 9pt">#3</span><span style="font-size: 9pt; font-family: 宋体">表示当前的第三个</span><span style="font-size: 9pt">)</span><span style="font-size: 9pt; font-family: 宋体">，而</span><span style="font-size: 9pt">4#5</span><span style="font-size: 9pt; font-family: 宋体">表示当月的第五个星期三，假设当月没有第五个星期三，忽略不触发；</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 'Arial','sans-serif'">●</span><span style="font-size: 9pt"> C</span><span style="font-size: 9pt; font-family: 宋体">：该字符只在日期和星期字段中使用，代表</span><span style="font-size: 9pt">&#8220;Calendar&#8221;</span><span style="font-size: 9pt; font-family: 宋体">的意思。它的意思是计划所关联的日期，如果日期没有被关联，则相当于日历中所有日期。例如</span><span style="font-size: 9pt">5C</span><span style="font-size: 9pt; font-family: 宋体">在日期字段中就相当于日历</span><span style="font-size: 9pt">5</span><span style="font-size: 9pt; font-family: 宋体">日以后的第一天。</span><span style="font-size: 9pt">1C</span><span style="font-size: 9pt; font-family: 宋体">在星期字段中相当于星期日后的第一天。</span><span style="font-size: 9pt">Cron</span><span style="font-size: 9pt; font-family: 宋体">表达式对特殊字符的大小写不敏感，对代表星期的缩写英文大小写也不敏感。表</span><span style="font-size: 9pt">2</span><span style="font-size: 9pt; font-family: 宋体">下面给出一些完整的</span><span style="font-size: 9pt">Cron</span><span style="font-size: 9pt; font-family: 宋体">表示式的实例：</span></p>
<p style="margin-left: 13.5pt; text-indent: -13.5pt; text-align: center" align="center"><span style="font-size: 9pt; font-family: 宋体">表</span><span style="font-size: 9pt">2 Cron</span><span style="font-size: 9pt; font-family: 宋体">表示式示例</span></p>
<div align="center">
<table style="border-right: #cccccc 1pt outset; border-top: #cccccc 1pt outset; border-left: #cccccc 1pt outset; border-bottom: #cccccc 1pt outset" cellspacing="1" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">表示式</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">说明</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 0 12 * * ? "</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每天</span><span style="font-size: 9pt">12</span><span style="font-size: 9pt; font-family: 宋体">点运行</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 ? * *"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每天</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">运行</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 * * ?"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每天</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">运行</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 * * ? *"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每天</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">运行</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 * * ? 2008"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">在</span><span style="font-size: 9pt">2008</span><span style="font-size: 9pt; font-family: 宋体">年的每天</span><span style="font-size: 9pt">10</span><span style="font-size: 9pt; font-family: 宋体">：</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">运行</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 * 14 * * ?"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每天</span><span style="font-size: 9pt">14</span><span style="font-size: 9pt; font-family: 宋体">点到</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">点之间每分钟运行一次，开始于</span><span style="font-size: 9pt">14:00</span><span style="font-size: 9pt; font-family: 宋体">，结束于</span><span style="font-size: 9pt">14:59</span><span style="font-size: 9pt; font-family: 宋体">。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 0/5 14 * * ?"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每天</span><span style="font-size: 9pt">14</span><span style="font-size: 9pt; font-family: 宋体">点到</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">点每</span><span style="font-size: 9pt">5</span><span style="font-size: 9pt; font-family: 宋体">分钟运行一次，开始于</span><span style="font-size: 9pt">14:00</span><span style="font-size: 9pt; font-family: 宋体">，结束于</span><span style="font-size: 9pt">14:55</span><span style="font-size: 9pt; font-family: 宋体">。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 0/5 14,18 * * ?"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每天</span><span style="font-size: 9pt">14</span><span style="font-size: 9pt; font-family: 宋体">点到</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">点每</span><span style="font-size: 9pt">5</span><span style="font-size: 9pt; font-family: 宋体">分钟运行一次，此外每天</span><span style="font-size: 9pt">18</span><span style="font-size: 9pt; font-family: 宋体">点到</span><span style="font-size: 9pt">19</span><span style="font-size: 9pt; font-family: 宋体">点每</span><span style="font-size: 9pt">5</span><span style="font-size: 9pt; font-family: 宋体">钟也运行一次。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 0-5 14 * * ?"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每天</span><span style="font-size: 9pt">14:00</span><span style="font-size: 9pt; font-family: 宋体">点到</span><span style="font-size: 9pt">14:05</span><span style="font-size: 9pt; font-family: 宋体">，每分钟运行一次。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 10,44 14 ? 3 WED"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">3</span><span style="font-size: 9pt; font-family: 宋体">月每周三的</span><span style="font-size: 9pt">14:10</span><span style="font-size: 9pt; font-family: 宋体">分到</span><span style="font-size: 9pt">14:44</span><span style="font-size: 9pt; font-family: 宋体">，每分钟运行一次。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 ? * MON-FRI"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每周一，二，三，四，五的</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">分运行。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 15 * ?"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每月</span><span style="font-size: 9pt">15</span><span style="font-size: 9pt; font-family: 宋体">日</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">分运行。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 L * ?"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每月最后一天</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">分运行。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 ? * 6L"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每月最后一个星期五</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">分运行。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 ? * 6L 2007-2009"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">在</span><span style="font-size: 9pt">2007,2008,2009</span><span style="font-size: 9pt; font-family: 宋体">年每个月的最后一个星期五的</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">分运行。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 141pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="235">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt">"0 15 10 ? * 6#3"</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.6pt; border-top: #cccccc 1pt inset; padding-left: 0.6pt; padding-bottom: 0.6pt; border-left: #cccccc 1pt inset; width: 194.4pt; padding-top: 0.6pt; border-bottom: #cccccc 1pt inset" valign="top" width="324">
            <p style="margin-left: 13.5pt; text-indent: -13.5pt"><span style="font-size: 9pt; font-family: 宋体">每月第三个星期五的</span><span style="font-size: 9pt">10:15</span><span style="font-size: 9pt; font-family: 宋体">分运行。</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/58707.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-07-18 10:58 <a href="http://www.blogjava.net/wuxufeng8080/articles/58707.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Spring集成XFire</title><link>http://www.blogjava.net/wuxufeng8080/articles/56374.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Mon, 03 Jul 2006 08:42:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/56374.html</guid><description><![CDATA[
		<strong>
				<br />
				<!---->
				<br />
		</strong>
		<span class="tpc_content">XFire可以很好的集成到Spring中，Spring的代码已经做了这方面的集成。<br />首先，我们先创建我们的Web服务，采用接口和实现类的方式：<br /><br />接口MathService.java：<br /><br />package com.kuaff.xfire.samples; <br /><br /><br /><br />public interface MathService <br /><br />{ <br /><br />  public long add(int p1, int p2); <br /><br />} <br /><br /><br />实现类：<br /><br />package com.kuaff.xfire.samples; <br /><br /><br /><br />public class MathServiceImpl implements MathService <br /><br />{ <br /><br />  public long add(int p1, int p2) <br /><br />  { <br /><br />    return p1 + p2; <br /><br />  } <br /><br />} <br /><br /><br />META-INF/xfire/service.xml文件可以省略了，因为web服务的定义在xfire-servlet.xml中可以找到。<br />下面要做的工具就是配置了。<br />在WEB-INF文件夹下创建applicationContext.xml文件，这是Spring的配置文件，如果你使用其他的Spring配置文件，可以将下面的bean添加到那个配置文件中：<br /><br /><br /><br />&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br /><br />&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "<a href="http://www.springframework.org/dtd/spring-beans.dtd" target="_blank">http://www.springframework.org/dtd/spring-beans.dtd</a>"&gt; <br /><br />&lt;beans&gt; <br /><br />  &lt;bean id="mathBean" class="com.kuaff.xfire.samples.MathServiceImpl"/&gt; <br /><br />&lt;/beans&gt; <br /><br /><br />定义了mathBean，这个Bean就是我们的实现类，当然你也可以在这个文件中定义其他的需要Spring管理的bean。<br /><br />在WEB-INF文件夹下创建xfire-servlet.xml文件，根据Spring规范，这个文件名起做xfire-servlet.xml,其中xfire是web.xml配置的DispatcherServlet的名称:<br /><br /><br />&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br /><br />&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "<a href="http://www.springframework.org/dtd/spring-beans.dtd" target="_blank">http://www.springframework.org/dtd/spring-beans.dtd</a>"&gt; <br /><br />&lt;beans&gt; <br /><br />  &lt;bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&gt; <br /><br />    &lt;property name="urlMap"&gt; <br /><br />        &lt;map&gt; <br /><br />          &lt;entry key="/MathService"&gt; <br /><br />            &lt;ref bean="math"/&gt; <br /><br />          &lt;/entry&gt; <br /><br />        &lt;/map&gt; <br /><br />    &lt;/property&gt; <br /><br />  &lt;/bean&gt; <br /><br />  <br /><br />  &lt;bean id="math" class="org.codehaus.xfire.spring.remoting.XFireExporter"&gt; <br /><br />    &lt;property name="serviceFactory"&gt; <br /><br />        &lt;ref bean="xfire.serviceFactory"/&gt; <br /><br />    &lt;/property&gt; <br /><br />    &lt;property name="xfire"&gt; <br /><br />        &lt;ref bean="xfire"/&gt; <br /><br />    &lt;/property&gt; <br /><br />    &lt;property name="serviceBean"&gt; <br /><br />        &lt;ref bean="mathBean"/&gt; <br /><br />    &lt;/property&gt; <br /><br />    &lt;property name="serviceClass"&gt; <br /><br />        &lt;value&gt;com.kuaff.xfire.samples.MathService&lt;/value&gt; <br /><br />    &lt;/property&gt; <br /><br />  &lt;/bean&gt; <br /><br />&lt;/beans&gt; <br /><br /><br />这个文件的上半部分将MathService这个URL和math这个bean联系在一起。下半部分定义了Web服务的bean和服务接口。其中mathBean是我们在applicationContext.xml中配置的那个Bean。<br /><br />最后一步就是修改web.xml文件：<br /><br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt; <br /><br /><br /><br />&lt;!DOCTYPE web-app <br /><br />  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" <br /><br />  "<a href="http://java.sun.com/dtd/web-app_2_3.dtd" target="_blank">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt; <br /><br />&lt;web-app&gt; <br /><br />  &lt;context-param&gt; <br /><br />    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt; <br /><br />    &lt;param-value&gt;/WEB-INF/applicationContext.xml <br /><br />    classpath:org/codehaus/xfire/spring/xfire.xml&lt;/param-value&gt; <br /><br />  &lt;/context-param&gt; <br /><br /><br /><br />  &lt;context-param&gt; <br /><br />    &lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt; <br /><br />    &lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt; <br /><br />  &lt;/context-param&gt; <br /><br /><br /><br />  &lt;listener&gt; <br /><br />    &lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt; <br /><br />  &lt;/listener&gt; <br /><br /><br /><br />  &lt;listener&gt; <br /><br />    &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt; <br /><br />  &lt;/listener&gt; <br /><br /><br /><br />  &lt;servlet&gt; <br /><br />    &lt;servlet-name&gt;xfire&lt;/servlet-name&gt; <br /><br />    &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt; <br /><br />  &lt;/servlet&gt; <br /><br /><br /><br />  &lt;servlet-mapping&gt; <br /><br />    &lt;servlet-name&gt;xfire&lt;/servlet-name&gt; <br /><br />    &lt;url-pattern&gt;/*&lt;/url-pattern&gt; <br /><br />  &lt;/servlet-mapping&gt; <br /><br />&lt;/web-app&gt; <br /><br /><br />需要注意这个文件的三个部分：<br /><br /><br /><br />1．     在定义contextConfigLocation参数时一定要加上classpath:org/codehaus/xfire/spring/xfire.xml。<br /><br />2．     定义listener: org.springframework.web.context.ContextLoaderListener<br /><br />3．     定义DispatcherServlet: xfire<br /><br />这样，你就可以访问<a href="http://localhost:8080/xfire/MathService" target="_blank">http://localhost:8080/xfire/MathService</a>来调用这个Web服务，也可以通过网址<a href="http://localhost:8080/xfire/MathService?wsdl" target="_blank">http://localhost:8080/xfire/MathService?wsdl</a>来查看wsdl文档。</span>
		<br />
		<!---->
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/56374.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-07-03 16:42 <a href="http://www.blogjava.net/wuxufeng8080/articles/56374.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring Framework标记库初学者指南</title><link>http://www.blogjava.net/wuxufeng8080/articles/54210.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Wed, 21 Jun 2006 05:38:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/54210.html</guid><wfw:comment>http://www.blogjava.net/wuxufeng8080/comments/54210.html</wfw:comment><comments>http://www.blogjava.net/wuxufeng8080/articles/54210.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuxufeng8080/comments/commentRss/54210.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuxufeng8080/services/trackbacks/54210.html</trackback:ping><description><![CDATA[
		<h3>Spring架构简要介绍：</h3>
		<br />    Spring是一个服务于所有层面的application framework:提供了bean的配置基础，AOP的支持，JDBC的提取框架,抽象事务支持，等等。它有一个非常显著的特点：在某个层面上如果你不需要Spring的支持，你就可以不使用String的class，只使用它的某一部分的功能。从它的设计理念，你可以看到String帮助你实现了真正的逻辑层和web层的分离。<br />   相对于EJB来说，Spring是一个轻量级的J2EE应用开发框架。这里提到的轻量级指的是Spring框架本身，而不是说Spring只能适用于轻量级的应用开发。Spring的轻盈体现在其框架本身的基础结构以及对其他应用工具的支持和装配能力，与EJB这种庞然大物相比，Spring使我们把各个技术层次之间的风险降低。EJB的内聚性较强，比如数据持久层管理、事务管理、生命周期管理都全部交给了EJB容器中管理，内聚性的白盒特征使我们必须放弃一部分可控性而去信任容器能力。而Spring则是考虑如何“不造轮子”，如何更好的组装这些轮子，让他们更好的转动。比如数据持久层管理可以使用hibernate，日志管理可以使用jakartacommonlogging。一个比较恰当的比喻就是“我们要钉几个钉子，为了完成这个目的，锤子生产商生产了大大小小一系列的锤子，每个锤子都有一套复杂的使用方法，用来钉某种特别的钉子，结果令我们头疼不堪。解决锤子过多的问题，通过spring，我们可以使用几种锤子，但用起来象是只有一个锤子”。(注：这段话是在网上看见的，这里引用这个比喻，我个人觉得很生动)关于这个框架也有一些简单的总结：“Spring有几个主要的部分：Bean+ApplicationContext，以一种统一的、IoC的方式查找、管理、组装、使用系统的组件，取代一切工厂；持久化框架；web框架。“J2EE框架”是RodJohnson的愿景，他希望Spring为J2EE轻量级解决方案提供自底至顶的全面基础设施支持。” <br />   好了，上面是关于一个新的Framework的简单介绍，据说是未来J2EE发展的方向。以前在论坛上有关于J2EE最佳组合的讨论，听说这个JSTL+Struts(或webwork)+Spring+Hibernate的组合很被看好（观点不一，仅供参考，呵呵）,如果你感兴趣的话，可以到SpringFramework中文论坛上看看。下面转入本文的正题。<br /><br /><h3>Spring 标记库介绍及用法：</h3><br />    本文将重点介绍Spring 提供的标记库及其用法：<br />当你在项目中用Spring Framework的时候，表现层可以选择Spring Framework自带的标记库。当然，这不是你唯一的选择。你可以选择其它标记库或模板替换技术。Spring Framework 并没有为应用提供非常丰富的标记库。Spring Framework 提供的标记库仅仅是为了够用就行，它并不是无所不包的。呵呵，这点与Struts丰富的标记库不一样。其实这点符合RodJohnson的出发点，既“不造轮子”。当然，Spring Framework标记库有它自身的特点，可以说是个有益的补充吧。<br /><b>Spring 标记库分类如下：</b><br />1。spring:hasBindErrors <br />2。spring:bind <br />3。spring:transform <br />4。spring:message <br />5。spring:htmlEscape <br />6。spring:theme <br /><b>下面我们来具体介绍一下用法：</b><br />1。<b>spring:hasBindErrors </b><br />对应org.springframework.web.servlet.tags.BindErrorsTag标记库处理类。<br />这个标记提供用于绑定对象的errors，如果这个标记被用到的话，那么关于这个对象的错误将在页面上显示出来。使用这个标记的前提条件是要先使用&lt;spring:bind&gt;标记,并且&lt;spring:hasBindErrors&gt;这个标记不能用来表示对象的状态，它仅仅可以绑定对象本身和对象的属性。 具体用法如下：<br /><div class="codeStyle"><ol><li>&lt;spring:hasBindErrors name=<font color="#ff33ff">"priceIncrease"</font>&gt; 
</li><li>    &lt;b&gt;Please fix all errors!&lt;/b&gt; 
</li><li>  &lt;/spring:hasBindErrors&gt; </li></ol></div><br />  通过这个简单的例子，我来具体说一下这个标记的属性吧。<br />  name：是要被检查的Bean的名字。这个属性是必需要的。<br />  呵呵，这里是简单用法，所以就不介绍它包含的errors变量了。具体看英语文档。下同。<br />  <br />2。<b>spring:bind </b><br />对应org.springframework.web.servlet.tags.BindTag标记库处理类<br />这个标记用来为某个bean或bean 的属性赋值，通常和form一起用，相当于action的作用。它指明表单要提交到那个类或类的属性中去。<br />其中path属性是必须的，指明转到的类的路径。举例如下：<br /><div class="codeStyle"><ol><li>&lt;form method=<font color="#ff33ff">"post"</font>&gt; 
</li><li>  &lt;table width=<font color="#ff33ff">"95%"</font> bgcolor=<font color="#ff33ff">"f8f8ff"</font> border=<font color="#ff33ff">"0"</font> cellspacing=<font color="#ff33ff">"0"</font> cellpadding=<font color="#ff33ff">"5"</font>&gt; 
</li><li>    &lt;tr&gt; 
</li><li>      &lt;td alignment=<font color="#ff33ff">"right"</font> width=<font color="#ff33ff">"20%"</font>&gt;Increase (%):&lt;/td&gt; 
</li><li>      &lt;spring:bind path=<font color="#ff33ff">"priceIncrease.percentage"</font>&gt; 
</li><li>        &lt;td width=<font color="#ff33ff">"20%"</font>&gt; 
</li><li>          &lt;input type=<font color="#ff33ff">"text"</font> name=<font color="#ff33ff">"percentage"</font> value=<font color="#ff33ff">"&lt;c:out value="</font>${status.value}<font color="#ff33ff">"/&gt;"</font>&gt; 
</li><li>        &lt;/td&gt; 
</li><li>        &lt;td width=<font color="#ff33ff">"60%"</font>&gt; 
</li><li>          &lt;font color=<font color="#ff33ff">"red"</font>&gt;&lt;c:out value=<font color="#ff33ff">"${status.errorMessage}"</font>/&gt;&lt;/font&gt; 
</li><li>        &lt;/td&gt; 
</li><li>      &lt;/spring:bind&gt; 
</li><li>    &lt;/tr&gt; 
</li><li>  &lt;/table&gt; 
</li><li>  &lt;br&gt; 
</li><li> ……………………省略 
</li><li>&lt;/form&gt; </li></ol></div><br />3。<b>spring:transform </b><br />对应org.springframework.web.servlet.tags.TransformTag标记库处理类,这个标记用来转换表单中不与bean中的属性一一对应的那些属性，通常和&lt;spring:bind&gt;一起使用。&lt;spring:transform&gt;标记为&lt;spring:bind&gt;使用提供了更好的支持。<br />属性如下：<br />value：必需要的。和当前&lt;spring:bind&gt;标记指向的bean类相同。就是你要转换的实体类名。<br />var：不是必需的。这个字符串被用来绑定输出结果到page，request, session或application scope.默认情况输出到jsp中。<br />scope：不是必需的。前提条件var必须设置的情况下。它的值可以是page，request, session或application。<br /><br />4。<b>spring:message </b>对应org.springframework.web.servlet.tags.MessageTag标记库处理类<br />这个标记用来帮助springframework支持国际化。和JSTL的fmt:message标记类似。当然这个标记可以很好的工作的本地的springframework框架下。<br />属性如下：<br />code：不是必需的。用来查找message,如果没有被使用的话，text将被使用。<br />text：不是必需的。假如code不存在的话，默认是text输出。当code和text都没有设置的话，标记将输出为null.<br />var：不是必需的。这个字符串被用来绑定输出结果到page，request, session或application scope.默认情况输出到jsp中。<br />scope：不是必需的。前提条件var必须设置的情况下。它的值可以是page，request, session或application。<br /><br />5。<b>spring:htmlEscape </b><br />对应org.springframework.web.servlet.tags.HtmlEscapeTag标记库处理类<br />不常用，这里省略<br />6。<b>spring:theme </b><br />对应org.springframework.web.servlet.tags.ThemeTag标记库处理类<br />不常用，这里省略<br />哈哈，学习完这些用法后，让我们来看个<b>具体的例子</b>吧。<br />配置步骤如下：<br /><b>目录结构图：</b><br />-spirngapp <br />  -WEB-INF <br />      -classes <br />      -lib <br />  -src <br />  -war<br /><b>1。</b>将spring.tld拷贝到WEB-INF目录。<br /><b>2。</b>将spring.jar拷贝到WEB-INF\lib包下<br />举例如下：<br />在web.xml中配置好taglib属性，代码如下：<br /><div class="codeStyle"><ol><li>&lt;?xml version=<font color="#ff33ff">"1.0"</font> encoding=<font color="#ff33ff">"UTF-8"</font>?&gt; 
</li><li>&lt;!DOCTYPE web-app PUBLIC '-<i><font color="#339900">//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'&gt;</font></i></li><li></li><li>&lt;web-app&gt; 
</li><li></li><li>  &lt;servlet&gt; 
</li><li>    &lt;servlet-name&gt;springapp&lt;/servlet-name&gt; 
</li><li>    &lt;servlet-<b><font color="#0000ff">class</font></b>&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-<b><font color="#0000ff">class</font></b>&gt; 
</li><li>    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt; 
</li><li>  &lt;/servlet&gt; 
</li><li></li><li>  &lt;servlet-mapping&gt; 
</li><li>    &lt;servlet-name&gt;springapp&lt;/servlet-name&gt; 
</li><li>    &lt;url-pattern&gt;*.htm&lt;/url-pattern&gt; 
</li><li>  &lt;/servlet-mapping&gt; 
</li><li></li><li>  &lt;welcome-file-list&gt; 
</li><li>    &lt;welcome-file&gt; 
</li><li>      index.jsp 
</li><li>    &lt;/welcome-file&gt; 
</li><li>  &lt;/welcome-file-list&gt; 
</li><li></li><li>  &lt;taglib&gt; 
</li><li>    &lt;taglib-uri&gt;/spring&lt;/taglib-uri&gt; 
</li><li>    &lt;taglib-location&gt;/WEB-INFspring.tld&lt;/taglib-location&gt; 
</li><li>  &lt;/taglib&gt; 
</li><li></li><li>&lt;/web-app&gt; </li></ol></div><br />jsp页面代码如下：<br /><div class="codeStyle"><ol><li>&lt;%@ include file=<font color="#ff33ff">"/WEB-INF/jsp/include.jsp"</font> %&gt; 
</li><li>&lt;%@ taglib prefix=<font color="#ff33ff">"spring"</font> uri=<font color="#ff33ff">"/spring"</font> %&gt; 
</li><li></li><li>&lt;html&gt; 
</li><li>&lt;head&gt;&lt;title&gt;&lt;fmt:message key=<font color="#ff33ff">"title"</font>/&gt;&lt;/title&gt;&lt;/head&gt; 
</li><li>&lt;body&gt; 
</li><li>&lt;h1&gt;&lt;fmt:message key=<font color="#ff33ff">"priceincrease.heading"</font>/&gt;&lt;/h1&gt; 
</li><li>&lt;form method=<font color="#ff33ff">"post"</font>&gt; 
</li><li>  &lt;table width=<font color="#ff33ff">"95%"</font> bgcolor=<font color="#ff33ff">"f8f8ff"</font> border=<font color="#ff33ff">"0"</font> cellspacing=<font color="#ff33ff">"0"</font> cellpadding=<font color="#ff33ff">"5"</font>&gt; 
</li><li>    &lt;tr&gt; 
</li><li>      &lt;td alignment=<font color="#ff33ff">"right"</font> width=<font color="#ff33ff">"20%"</font>&gt;Increase (%):&lt;/td&gt; 
</li><li>      &lt;spring:bind path=<font color="#ff33ff">"priceIncrease.percentage"</font>&gt; 
</li><li>        &lt;td width=<font color="#ff33ff">"20%"</font>&gt; 
</li><li>          &lt;input type=<font color="#ff33ff">"text"</font> name=<font color="#ff33ff">"percentage"</font> value=<font color="#ff33ff">"&lt;c:out value="</font>${status.value}<font color="#ff33ff">"/&gt;"</font>&gt; 
</li><li>        &lt;/td&gt; 
</li><li>        &lt;td width=<font color="#ff33ff">"60%"</font>&gt; 
</li><li>          &lt;font color=<font color="#ff33ff">"red"</font>&gt;&lt;c:out value=<font color="#ff33ff">"${status.errorMessage}"</font>/&gt;&lt;/font&gt; 
</li><li>        &lt;/td&gt; 
</li><li>      &lt;/spring:bind&gt; 
</li><li>    &lt;/tr&gt; 
</li><li>  &lt;/table&gt; 
</li><li>  &lt;br&gt; 
</li><li>  &lt;spring:hasBindErrors name=<font color="#ff33ff">"priceIncrease"</font>&gt; 
</li><li>    &lt;b&gt;Please fix all errors!&lt;/b&gt; 
</li><li>  &lt;/spring:hasBindErrors&gt; 
</li><li>  &lt;br&gt;&lt;br&gt; 
</li><li>  &lt;input type=<font color="#ff33ff">"submit"</font> alignment=<font color="#ff33ff">"center"</font> value=<font color="#ff33ff">"Execute"</font>&gt; 
</li><li>&lt;/form&gt; 
</li><li>&lt;a href=<font color="#ff33ff">"&lt;c:url value="</font>hello.htm<font color="#ff33ff">"/&gt;"</font>&gt;Home&lt;/a&gt; 
</li><li>&lt;/body&gt; 
</li><li>&lt;/html&gt; </li></ol></div><br />&lt;spring:bind&gt;标记经常用来绑定&lt;input&gt;表单元素以便提交给PriceIncrease.java,其实PriceIncrease.java中就是包含一些getter和setter的方法的类。当用户按下按钮提交的时候，其表单中的值实际上就被framework放到了PriceIncrease.java中。&lt;spring:bind&gt;经常和form一起使用.这个${status.errorMessage}和${status.value}是一个framework定义的特殊变量，它们被用来显示错误信息和当前表单中的数据。呵呵，今天就到此为止吧，关于Spring Framework标记库的详细用法，请参考其文档。<br />参考资料：<br />http://www.springframework.org/<br />Spring Framework英文文档<br />Spring Framework中文论坛 <br /><img src ="http://www.blogjava.net/wuxufeng8080/aggbug/54210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-06-21 13:38 <a href="http://www.blogjava.net/wuxufeng8080/articles/54210.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring入门编程问题集锦</title><link>http://www.blogjava.net/wuxufeng8080/articles/54182.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Wed, 21 Jun 2006 04:42:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/54182.html</guid><wfw:comment>http://www.blogjava.net/wuxufeng8080/comments/54182.html</wfw:comment><comments>http://www.blogjava.net/wuxufeng8080/articles/54182.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuxufeng8080/comments/commentRss/54182.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuxufeng8080/services/trackbacks/54182.html</trackback:ping><description><![CDATA[1、如何学习Spring？ <br />你可以通过下列途径学习spring： <br />(1) spring下载包中doc目录下的MVC-step-by-step和sample目录下的例子都是比较好的spring开发的例子。 <br /><br />(2) AppFuse集成了目前最流行的几个开源轻量级框架或者工具Ant,XDoclet,Spring,Hibernate(iBATIS),JUnit,Cactus,StrutsTestCase,Canoo's WebTest,Struts Menu,Display Tag Library,OSCache,JSTL,Struts 。 <br />你可以通过AppFuse源代码来学习spring。 <br />AppFuse网站：http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse <br /><br />(3)Spring 开发指南(夏昕)（http://www.xiaxin.net/Spring_Dev_Guide.rar） <br />一本spring的入门书籍,里面介绍了反转控制和依赖注射的概念，以及spring的bean管理，spring的MVC，spring和hibernte，iBatis的结合。 <br /><br />(4) spring学习的中文论坛 <br />SpringFramework中文论坛(http://spring.jactiongroup.net) <br />Java视线论坛(http://forum.javaeye.com)的spring栏目 <br /><br />2、利用Spring框架编程，console打印出log4j:WARN Please initialize the log4j system properly？ <br />说明你的log4j.properties没有配置。请把log4j.properties放到工程的classpath中，eclipse的classpath为bin目录，由于编译后src目录下的文件会拷贝到bin目录下，所以你可以把log4j.properties放到src目录下。 <br />这里给出一个log4j.properties的例子： <br /><br />log4j.rootLogger=DEBUG,stdout <br />log4j.appender.stdout=org.apache.log4j.ConsoleAppender <br />log4j.appender.stdout.layout=org.apache.log4j.PatternLayout <br />log4j.appender.stdout.layout.ConversionPattern=%d %5p (%F:%L) - %m%n <br /><br /><br />3、出现 java.lang.NoClassDefFoundError? <br />一般情况下是由于你没有把必要的jar包放到lib中。 <br /><br />比如你要采用spring和hibernate（带事务支持的话），你除了spring.jar外还需要hibernat.jar、aopalliance.jar、cglig.jar、jakarta-commons下的几个jar包。 <br /><br /><a href="http://www.springframework.org/download.html下载spring开发包，提供两种zip包" target="_blank"><font color="#002c99">http://www.springframework.org/download.html下载spring开发包，提供两种zip包</font></a><br />spring-framework-1.1.3-with-dependencies.zip和spring-framework-1.1.3.zip，我建议你下载spring-framework-1.1.3-with-dependencies.zip。这个zip解压缩后比后者多一个lib目录，其中有hibernate、j2ee、dom4j、aopalliance、jakarta-commons等常用包。 <br /><br /><br />4、java.io.FileNotFoundException: Could not open class path resource [....hbm.xml],提示找不到xml文件？ <br />原因一般有两个： <br />(1)该xml文件没有在classpath中。 <br />(2)applicationContext-hibernate.xml中的xml名字没有带包名。比如： <br />&lt;bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"&gt; <br />&lt;property name="dataSource"&gt;&lt;ref bean="dataSource"/&gt;&lt;/property&gt; <br />&lt;property name="mappingResources"&gt; <br />&lt;list&gt; <br />&lt;value&gt;User.hbm.xml&lt;/value&gt; 错，改为： &lt;value&gt;com/yz/spring/domain/User.hbm.xml&lt;/value&gt; <br />&lt;/list&gt; <br />&lt;/property&gt; <br />&lt;property name="hibernateProperties"&gt; <br />&lt;props&gt; <br />&lt;prop key="hibernate.dialect"&gt; net.sf.hibernate.dialect.MySQLDialect &lt;/prop&gt; <br />&lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt; <br />&lt;/props&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br /><br /><br />5、org.springframework.beans.NotWritablePropertyException: Invalid property 'postDao' of bean class？ <br />出现异常的原因是在application-xxx.xml中property name的错误。 <br />&lt;property name="...."&gt; 中name的名字是与bean的set方法相关的，而且要注意大小写。 <br />比如 <br />public class PostManageImpl extends BaseManage implements PostManage { <br />private PostDAO dao = null; <br />public void setPostDAO(PostDAO postDAO){ <br />this.dao = postDAO; <br />} <br />} <br />那么xml的定义应该是： <br />&lt;bean id="postManage" parent="txProxyTemplate"&gt; <br />&lt;property name="target"&gt; <br />&lt;bean class="com.yz.spring.service.implement.PostManageImpl"&gt; <br />&lt;property name="postDAO"&gt;&lt;ref bean="postDAO"/&gt;&lt;/property&gt; 对 <br />&lt;property name="dao"&gt;&lt;ref bean="postDAO"/&gt;&lt;/property&gt; 错 <br />&lt;/bean&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br /><br /><br />6、Spring中如何实现事务管理？ <br />首先，如果使用mysql，确定mysql为InnoDB类型。 <br />事务管理的控制应该放到商业逻辑层。你可以写个处理商业逻辑的JavaBean，在该JavaBean中调用DAO，然后把该Bean的方法纳入spring的事务管理。 <br /><br />比如：xml文件定义如下： <br />&lt;bean id="txProxyTemplate" abstract="true" <br />class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt; <br />&lt;property name="transactionManager"&gt;&lt;ref bean="transactionManager"/&gt;&lt;/property&gt; <br />&lt;property name="transactionAttributes"&gt; <br />&lt;props&gt; <br />&lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt; <br />&lt;prop key="remove*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt; <br />&lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt; <br />&lt;/props&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="userManage" parent="txProxyTemplate"&gt; <br />&lt;property name="target"&gt; <br />&lt;bean class="com.yz.spring.service.implement.UserManageImpl"&gt; <br />&lt;property name="userDAO"&gt;&lt;ref bean="userDAO"/&gt;&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br /><br />com.yz.spring.service.implement.UserManageImpl就是我们的实现商业逻辑的JavaBean。我们通过parent元素声明其事务支持。 <br /><br /><br />7、如何管理Spring框架下更多的JavaBean？ <br />JavaBean越多，spring配置文件就越大，这样不易维护。为了使配置清晰，我们可以将JavaBean分类管理，放在不同的配置文件中。 应用启动时将所有的xml同时加载。 <br />比如： <br />DAO层的JavaBean放到applicationContext-hibernate.xml中，商业逻辑层的JavaBean放到applicationContext-service.xml中。然后启动类中调用以下代码载入所有的ApplicationContext。 <br /><br />String[] paths = {"com/yz/spring/dao/hibernate/applicationContext-hibernate.xml", <br />"com/yz/spring/service/applicationContext-service.xml"}; <br />ctx = new ClassPathXmlApplicationContext(paths); <br /><br /><br />8、web应用中如何加载ApplicationContext？ <br />可以通过定义web.xml，由web容器自动加载。 <br /><br />&lt;servlet&gt; <br />&lt;servlet-name&gt;context&lt;/servlet-name&gt; <br />&lt;servlet-class&gt;org.springframework.web.context.ContextLoaderServlet&lt;/servlet-class&gt; <br />&lt;load-on-startup&gt;1&lt;/load-on-startup&gt; <br />&lt;/servlet&gt; <br /><br />&lt;context-param&gt; <br />&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt; <br />&lt;param-value&gt;/WEB-INF/applicationContext-hibernate.xml&lt;/param-value&gt; <br />&lt;param-value&gt;/WEB-INF/applicationContext-service.xml&lt;/param-value&gt; <br />&lt;/context-param&gt; <br /><br />9、在spring中如何配置的log4j? <br />在web.xml中加入以下代码即可。 <br />&lt;context-param&gt; <br />&lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt; <br />&lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt; <br />&lt;/context-param&gt; <br /><br /><br />10、Spring框架入门的编程问题解决了，我该如何更深地领会Spring框架呢？ <br />这两本书你该去看看。这两本书是由Spring的作者Rod Johnson编写的。 <br />Expert One on one J2EE Design and Development <br />Expert One on one J2EE Development Without EJB <br />你也该看看martinfowler的Inversion of Control Containers and the Dependency Injection pattern。 <br /><a href="http://www.martinfowler.com/articles/injection.html" target="_blank"><font color="#002c99">http://www.martinfowler.com/articles/injection.html</font></a><br /><br />再好好研读一下spring的文档。 <br /><a href="http://www.jactiongroup.net/reference/html/index.html（中文版，未全部翻译）" target="_blank"><font color="#002c99">http://www.jactiongroup.net/reference/html/index.html（中文版，未全部翻译）</font></a><br /><br />还有就是多实践吧。<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/54182.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-06-21 12:42 <a href="http://www.blogjava.net/wuxufeng8080/articles/54182.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用spring-mock进行dao集成测试</title><link>http://www.blogjava.net/wuxufeng8080/articles/54181.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Wed, 21 Jun 2006 04:41:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/54181.html</guid><wfw:comment>http://www.blogjava.net/wuxufeng8080/comments/54181.html</wfw:comment><comments>http://www.blogjava.net/wuxufeng8080/articles/54181.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuxufeng8080/comments/commentRss/54181.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuxufeng8080/services/trackbacks/54181.html</trackback:ping><description><![CDATA[
		<span class="postbody">在进行dao的集成测试时候，数据清理，察看数据都是比较麻烦的事情，使用Spring-mock.jar可以帮助我们简化着一个过程。我举一个简单的例子，说明一下如何使用spring-mock。 <br /><br />首先是po, hbm.xml, dao, daoimpl没什么好说的： <br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="FONT-FAMILY: 'Courier New', Courier, monospace">
												<br />
												<br />Customer.<span style="COLOR: #000000">java</span> : <br /><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">package</span> rst.<span style="COLOR: #000000">spring</span>.<span style="COLOR: #000000">mock</span>; <br /><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">import</span> java.<span style="COLOR: #000000">io</span>.<span style="COLOR: #000000">Serializable</span>; <br /><br /><span style="COLOR: #6666ff">/** @author Hibernate CodeGenerator */</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span> Customer <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">implements</span><span style="COLOR: #aaaadd" ?="">Serializable</span><span style="COLOR: #000000">{</span><br /><br />    <span style="COLOR: #6666ff">/** identifier field */</span><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">private</span><span style="COLOR: #aaaadd" ?="">Long</span> id; <br /><br />    <span style="COLOR: #6666ff">/** nullable persistent field */</span><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">private</span><span style="COLOR: #aaaadd" ?="">String</span> name; <br /><br />    <span style="COLOR: #6666ff">/** full constructor */</span><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span> Customer<span style="COLOR: #000000">(</span><span style="COLOR: #aaaadd" ?="">String</span> name<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />        this.<span style="COLOR: #000000">name</span> = name; <br />    <span style="COLOR: #000000">}</span><br /><br />    <span style="COLOR: #6666ff">/** default constructor */</span><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span> Customer<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />    <span style="COLOR: #000000">}</span><br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="COLOR: #aaaadd" ?="">Long</span> getId<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />        <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">return</span> this.<span style="COLOR: #000000">id</span>; <br />    <span style="COLOR: #000000">}</span><br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> setId<span style="COLOR: #000000">(</span><span style="COLOR: #aaaadd" ?="">Long</span> id<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />        this.<span style="COLOR: #000000">id</span> = id; <br />    <span style="COLOR: #000000">}</span><br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="COLOR: #aaaadd" ?="">String</span> getName<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />        <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">return</span> this.<span style="COLOR: #000000">name</span>; <br />    <span style="COLOR: #000000">}</span><br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> setName<span style="COLOR: #000000">(</span><span style="COLOR: #aaaadd" ?="">String</span> name<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />        this.<span style="COLOR: #000000">name</span> = name; <br />    <span style="COLOR: #000000">}</span><br /><br /><span style="COLOR: #000000">}</span><br /><br />Customer.<span style="COLOR: #000000">hbm</span>.<span style="COLOR: #000000">xml</span> : <br /><br />&lt;?xml version="<span style="COLOR: #000000" ?="">1</span>.<span style="COLOR: #000000" ?="">0</span>" encoding="UTF-<span style="COLOR: #000000" ?="">8</span>"?&gt; <br />&lt;!DOCTYPE hibernate-mapping <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">PUBLIC</span><br />        "-<span style="COLOR: #6666ff">//Hibernate/Hibernate Mapping DTD//EN"</span><br />        "http:<span style="COLOR: #6666ff">//hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"&gt;</span><br />&lt;hibernate-mapping <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">package</span>="rst.<span style="COLOR: #000000">spring</span>.<span style="COLOR: #000000">mock</span>"&gt; <br />        &lt;<span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span> name="Customer" table="customer"&gt; <br />                &lt;id name="id" column="id" type="long" unsaved-value="<span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">null</span>"&gt; <br />                        &lt;generator <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="identity"/&gt; <br />                &lt;/id&gt; <br />                &lt;property name="name" column="name" type="string"/&gt; <br />        &lt;/<span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>&gt; <br /><br />&lt;/hibernate-mapping&gt; <br /><br />CustomerDAO : <br /><span style="COLOR: #6666ff">/* <br />* Created on 2005-3-25 <br />*/</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">package</span> rst.<span style="COLOR: #000000">spring</span>.<span style="COLOR: #000000">mock</span>; <br /><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">import</span> org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">dao</span>.<span style="COLOR: #000000">DataAccessException</span>; <br /><br /><span style="COLOR: #6666ff">/** <br />* @author rst <br />* <br />*/</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">interface</span> CustomerDAO <span style="COLOR: #000000">{</span><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> add<span style="COLOR: #000000">(</span>Customer customer<span style="COLOR: #000000">)</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">throws</span> DataAccessException; <br /><span style="COLOR: #000000">}</span><br /><br />CustomerDAOImpl : <br /><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">package</span> rst.<span style="COLOR: #000000">spring</span>.<span style="COLOR: #000000">mock</span>; <br /><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">import</span> org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">dao</span>.<span style="COLOR: #000000">DataAccessException</span>; <br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">import</span> org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">orm</span>.<span style="COLOR: #000000">hibernate</span>.<span style="COLOR: #000000">support</span>.<span style="COLOR: #000000">HibernateDaoSupport</span>; <br /><br /><span style="COLOR: #6666ff">/** <br />* Class description. <br />* <br />* @author rst <br />*/</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span> CustomerDAOHibernateImpl <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">extends</span> HibernateDaoSupport <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">implements</span> CustomerDAO<span style="COLOR: #000000">{</span><br />    <br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> add<span style="COLOR: #000000">(</span>Customer customer<span style="COLOR: #000000">)</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">throws</span> DataAccessException<span style="COLOR: #000000">{</span><br />        this.<span style="COLOR: #000000">getHibernateTemplate</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span>.<span style="COLOR: #000000">save</span><span style="COLOR: #000000">(</span>customer<span style="COLOR: #000000">)</span>; <br />    <span style="COLOR: #000000">}</span><br /><span style="COLOR: #000000">}</span><br /><br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />然后测试的基类SpringDAOTestCase继承自AbstractTransactionalDataSourceSpringContextTests，目前只有一个指定测试用xml文件位置的逻辑。 <br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="FONT-FAMILY: 'Courier New', Courier, monospace">
												<br />
												<br />
												<span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">package</span> rst.<span style="COLOR: #000000">spring</span>.<span style="COLOR: #000000">mock</span>; <br /><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">import</span> org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">test</span>.<span style="COLOR: #000000">AbstractTransactionalDataSourceSpringContextTests</span>; <br /><br /><span style="COLOR: #6666ff">/** <br />* Class description. <br />* <br />* @author rst <br />*/</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">abstract</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span> SpringDAOTestCase <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">extends</span> AbstractTransactionalDataSourceSpringContextTests <span style="COLOR: #000000">{</span><br /><br />  <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">protected</span><span style="COLOR: #aaaadd" ?="">String</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">]</span> getConfigLocations<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">return</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">new</span><span style="COLOR: #aaaadd" ?="">String</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">{</span> "test.<span style="COLOR: #000000">xml</span>" <span style="COLOR: #000000">}</span>; <br />  <span style="COLOR: #000000">}</span><br /><br /><span style="COLOR: #000000">}</span><br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />接着是我们真正测试的类CustomerDAOTest.java： <br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="FONT-FAMILY: 'Courier New', Courier, monospace">
												<br />
												<br />
												<span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">package</span> rst.<span style="COLOR: #000000">spring</span>.<span style="COLOR: #000000">mock</span>; <br /><br /><span style="COLOR: #6666ff">/** <br />* Class description. <br />* <br />* @author rst <br />*/</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span> CustomerDaoTest <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">extends</span> SpringDAOTestCase <span style="COLOR: #000000">{</span><br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">private</span> CustomerDAOHibernateImpl customerDAO; <br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">protected</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> onSetUpInTransaction<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">throws</span><span style="COLOR: #aaaadd" ?="">Exception</span><span style="COLOR: #000000">{</span><br />        super.<span style="COLOR: #000000">onSetUpInTransaction</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span>; <br />        <span style="COLOR: #6666ff">//this.setPopulateProtectedVariables(true);</span><br />        customerDAO = <span style="COLOR: #000000">(</span>CustomerDAOHibernateImpl<span style="COLOR: #000000">)</span> this.<span style="COLOR: #000000">applicationContext</span>.<span style="COLOR: #000000">getBean</span><span style="COLOR: #000000">(</span>"customerDAO"<span style="COLOR: #000000">)</span>; <br />    <span style="COLOR: #000000">}</span><br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">protected</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> onTearDownInTransaction<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />        customerDAO = <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">null</span>; <br />    <span style="COLOR: #000000">}</span><br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> testInsert<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />        Customer customer = <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">new</span> Customer<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span>; <br />        customer.<span style="COLOR: #000000">setName</span><span style="COLOR: #000000">(</span>"javaeye"<span style="COLOR: #000000">)</span>; <br />        customerDAO.<span style="COLOR: #000000">add</span><span style="COLOR: #000000">(</span>customer<span style="COLOR: #000000">)</span>; <br />        <span style="COLOR: #aaaadd" ?="">String</span> name = <span style="COLOR: #000000">(</span><span style="COLOR: #aaaadd" ?="">String</span><span style="COLOR: #000000">)</span> jdbcTemplate.<span style="COLOR: #000000">queryForObject</span><span style="COLOR: #000000">(</span>"select name from customer where id=?", <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">new</span><span style="COLOR: #aaaadd" ?="">Object</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">{</span>customer.<span style="COLOR: #000000">getId</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">}</span>, <span style="COLOR: #aaaadd" ?="">String</span>.<span style="COLOR: #000000">class</span><span style="COLOR: #000000">)</span>; <br />        <br />        assertEquals<span style="COLOR: #000000">(</span>customer.<span style="COLOR: #000000">getName</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span>, name<span style="COLOR: #000000">)</span>; <br />    <span style="COLOR: #000000">}</span><br /><br /><span style="COLOR: #000000">}</span><br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />最后看看配置文件test.xml： <br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="FONT-FAMILY: 'Courier New', Courier, monospace">
												<br />
												<br />&lt;?xml version="<span style="COLOR: #000000" ?="">1</span>.<span style="COLOR: #000000" ?="">0</span>" encoding="UTF-<span style="COLOR: #000000" ?="">8</span>"?&gt; <br />&lt;!DOCTYPE beans <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">PUBLIC</span> "-<span style="COLOR: #6666ff">//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;</span><br /><br />&lt;!-- <br />  - Application context definition <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">for</span> Petclinic on Hibernate. <br />        --&gt; <br />&lt;beans&gt; <br /><br />        &lt;!-- ========================= RESOURCE DEFINITIONS ========================= --&gt; <br />  <br />        &lt;!-- Configurer that replaces $<span style="COLOR: #000000">{</span>...<span style="COLOR: #000000">}</span> placeholders with values from a properties file --&gt; <br />        &lt;!-- <span style="COLOR: #000000">(</span>in this <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">case</span>, JDBC-related settings <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">for</span> the dataSource definition below<span style="COLOR: #000000">)</span> --&gt; <br />        &lt;bean id="propertyConfigurer" <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">beans</span>.<span style="COLOR: #000000">factory</span>.<span style="COLOR: #000000">config</span>.<span style="COLOR: #000000">PropertyPlaceholderConfigurer</span>"&gt; <br />                &lt;property name="location"&gt;&lt;value&gt;classpath:jdbc.<span style="COLOR: #000000">properties</span>&lt;/value&gt;&lt;/property&gt; <br />        &lt;/bean&gt; <br /><br />        &lt;!-- Local DataSource that works in any environment --&gt; <br />        &lt;bean id="dataSource" <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">jdbc</span>.<span style="COLOR: #000000">datasource</span>.<span style="COLOR: #000000">DriverManagerDataSource</span>"&gt; <br />                &lt;property name="driverClassName"&gt;&lt;value&gt;$<span style="COLOR: #000000">{</span>jdbc.<span style="COLOR: #000000">driverClassName</span><span style="COLOR: #000000">}</span>&lt;/value&gt;&lt;/property&gt; <br />                &lt;property name="url"&gt;&lt;value&gt;$<span style="COLOR: #000000">{</span>jdbc.<span style="COLOR: #000000">url</span><span style="COLOR: #000000">}</span>&lt;/value&gt;&lt;/property&gt; <br />                &lt;property name="username"&gt;&lt;value&gt;$<span style="COLOR: #000000">{</span>jdbc.<span style="COLOR: #000000">username</span><span style="COLOR: #000000">}</span>&lt;/value&gt;&lt;/property&gt; <br />                &lt;property name="password"&gt;&lt;value&gt;$<span style="COLOR: #000000">{</span>jdbc.<span style="COLOR: #000000">password</span><span style="COLOR: #000000">}</span>&lt;/value&gt;&lt;/property&gt; <br />        &lt;/bean&gt; <br /><br />        &lt;!-- Hibernate SessionFactory --&gt; <br />        &lt;bean id="sessionFactory" <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">orm</span>.<span style="COLOR: #000000">hibernate</span>.<span style="COLOR: #000000">LocalSessionFactoryBean</span>"&gt; <br />                &lt;property name="dataSource"&gt;&lt;ref local="dataSource"/&gt;&lt;/property&gt; <br />                &lt;property name="mappingResources"&gt; <br />                        &lt;value&gt;rst/spring/mock/Customer.<span style="COLOR: #000000">hbm</span>.<span style="COLOR: #000000">xml</span>&lt;/value&gt; <br />                &lt;/property&gt; <br />                &lt;property name="hibernateProperties"&gt; <br />                        &lt;props&gt; <br />                                &lt;prop key="hibernate.<span style="COLOR: #000000">dialect</span>"&gt;$<span style="COLOR: #000000">{</span>hibernate.<span style="COLOR: #000000">dialect</span><span style="COLOR: #000000">}</span>&lt;/prop&gt; <br />                                &lt;prop key="hibernate.<span style="COLOR: #000000">show_sql</span>"&gt;<span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">true</span>&lt;/prop&gt; <br />                        &lt;/props&gt; <br />                &lt;/property&gt; <br />        &lt;/bean&gt; <br /><br />        &lt;!-- Transaction manager <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">for</span> a single Hibernate SessionFactory <span style="COLOR: #000000">(</span>alternative to JTA<span style="COLOR: #000000">)</span> --&gt; <br />        &lt;bean id="transactionManager" <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">orm</span>.<span style="COLOR: #000000">hibernate</span>.<span style="COLOR: #000000">HibernateTransactionManager</span>"&gt; <br />                &lt;property name="sessionFactory"&gt;&lt;ref local="sessionFactory"/&gt;&lt;/property&gt; <br />        &lt;/bean&gt; <br />        <br />        &lt;bean id="hibernateTemplate" <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="org.<span style="COLOR: #000000">springframework</span>.<span style="COLOR: #000000">orm</span>.<span style="COLOR: #000000">hibernate</span>.<span style="COLOR: #000000">HibernateTemplate</span>"&gt; <br />                &lt;property name="sessionFactory"&gt;&lt;ref local="sessionFactory"/&gt;&lt;/property&gt; <br />        &lt;/bean&gt; <br /><br />        &lt;bean id="customerDAO" <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="rst.<span style="COLOR: #000000">spring</span>.<span style="COLOR: #000000">mock</span>.<span style="COLOR: #000000">CustomerDAOHibernateImpl</span>"&gt; <br />                &lt;property name="hibernateTemplate"&gt;&lt;ref local="hibernateTemplate"/&gt;&lt;/property&gt; <br />        &lt;/bean&gt; <br />&lt;/beans&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />这个文件很简单，不要忘记transactionManager的配置，Test类会自动装配的。 <br /><br />运行之后，就可以看到应有的结果，并且数据库中不会有数据污染。这个过程主要是开始一个transaction，然后开始你的test方法，执行dao操作，执行sql查询验证结果，最后无论成功失败rollback transaction。</span>
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/54181.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-06-21 12:41 <a href="http://www.blogjava.net/wuxufeng8080/articles/54181.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring MVC framework深入分析之一--总体分析</title><link>http://www.blogjava.net/wuxufeng8080/articles/54180.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Wed, 21 Jun 2006 04:36:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/54180.html</guid><wfw:comment>http://www.blogjava.net/wuxufeng8080/comments/54180.html</wfw:comment><comments>http://www.blogjava.net/wuxufeng8080/articles/54180.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuxufeng8080/comments/commentRss/54180.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuxufeng8080/services/trackbacks/54180.html</trackback:ping><description><![CDATA[
		<span class="postbody">在当今的MVC framework里，似乎Webwork2逐渐成为主流， Webwork2+SpringFramework的组合变得越来越流行。这似乎意味着Spring自带的MVC framework远比Webwork2差，所以大家纷纷用Webwork2来代替。确实，Spring的MVC framework不算是整个Spring的核心部件，但它的威力却超过了很多人的想象。很多人包括xiecc认为Spring的MVC framework是非常优秀的，甚至比Webwork2更优秀。 <br />下面列举一下Spring的MVC framework在设计时做出的一些重要的决定，并将之和相关的MVC framework如Webwork2或struts进行对比： <br />一、 Spring的整个MVC配置是基于IOC容器的 <br />与struts或webwork2相比，这是一个ms有点奇怪的决定，看一下Spring MVC的配置文件，最先看到的不是action或者form，而是一些有着特定名字的bean，Bean下面的配置是一些简单或有点复杂的属性。我们看到的是机器更容易的数据结构，而不是人更容易理解的元素。 <br />但是这恰恰是Spring的MVC强大的根源！因为它的配置就是Spring的核心IOC容器的配置，这意味着所有IOC容器的威力都可以在这里展现，我们可以为所欲为地对Spring MVC进行扩展和增强，我们可以完成在其它MVC framwork中很多难以想象的任务。想扩展新的URL映射方式吗？要换一个themeResolver或LocalReolver的实现吗?想在页面中显示新类型的View（比如说RDF，呵呵，一个小秘密：xiecc是研究语义网的，虽然成天不务正业，不写论文，只写八卦）？甚至想直接在Controller里定义AOP吗？这些对Spring的MVC来说都是小菜一碟。 <br />我没有仔细研究过Webwork2的扩展机制，我知道通过Webwork2的interceptor机制，可以进行很多的扩展，甚至有一个简单简单的IOC容器。但不管它有多强大，提供了多少扩展点。它的威力都很难和真正的IOC容器相比。而struts的plugin功能则是出名的滥，虽然它也提供了plugin机制。 <br />Spring采用IOC配置的另一个原因是使Spring的MVC与Spring的IOC容器的整合变得非常的容易。Spring提供了与struts与webwork2的整合，但是这样整合都需要在进行间接的包装，感觉总不是很自然。而且还会导致一个概念多个配置，webwork2就需要在Spring里配置bean，再配置自己的xwork文件。想象一下吧，我们的bean直接就是一个controller,直接可以完成MVC的所有任务,这是多少爽的感觉。 <br />Rod Johnson采用IOC容器来实现的另一个原因是这会减少好多开发工作量。看一下urlMapping吧，它提供的property本身就是一个HashMap，只有配置完成，我们的bean里的数据就自然存在了，哈哈，好爽吧。不用象struts那样解析XML，再把它的内容一项一项地读到HashMap里。 <br />虽然这样的配置会有点怪异，但假如我们对Spring的IOC容器非常熟悉的话，会发现它非常的亲切，也非常的简单。 <br />最后是一个简单的小秘密，Spring怎么知道某个bean的配置就是urlMapping？另一个bean的配置就是viewResolver？其实很简单，把所有的bean全部读到内存里，然后通过bean的名字或类型去找就行了。通过名字去找就是简单的getBean方法，通过类型去找则使用了BeanFactoryUtils.beansOfTypeIncludingAncestors的静态方法。</span>
		<span class="postbody">
		</span>
		<span class="gensmall">
				<br />
				<br />
				<span class="postbody">二、 Spring提供了明确的Model, View概念和相应的数据结构 <br />在Spring里有一个有趣的数据类型叫做ModelAndView，它只是简单地把要显示的数据和显示的结果封装在一个类里。但是它却提供了明确的MVC概念，尤其是model概念的强化，使程序的逻辑变得更清晰了。 <br />记得以前在Struts里写程序里的时候，为了显示数据经常自己把东西放到HttpSession或HttpServletRequest里（或set到form里，虽然不太有用），这造成了model概念的模糊，而且也导致了struts与JSP页面的紧耦合。假如我们要替换成Veloctiy,就得另外加一个plugin,因为在velocity里数据是不需要不放到request里的。 <br />Webwork2里强调的是与Web framework解耦和它的command模式的简单性，因此在它的action里只有简单的get或set方法，假如返回数据，也只是简单地返回一个String。当然这样的实现有它的好处，但是它淡化了model和view的概念。Rod Johnson认为Webwork2里的Action同时包含了Action和Model的职责，这样一个类的职责太多，不是一个很好的设计。当然Jason Carreira不太认同这种观点，因为Action里的model对象完成可以delege给其它对象。但不管怎样，这种争论的根源在于Webwork2里淡化了model, view甚至web的概念。仁者见仁，智者见智，最后的结果还是看个人喜欢好吧。 <br /><br />三、 Spring的Controller是Singleton的，或者是线程不安全的 <br />和Struts一样，Spring的Controller是Singleton的，这意味着每个request过来，系统都会用原有的instance去处理，这样导致了两个结果：我们不用每次创建Controller，减少了对象创建和垃圾收集的时间；由于只有一个Controller的instance，当多个线程调用它的时候，它里面的instance变量不是线程安全的。 <br />这也是Webwork2吹嘘的地方，它的每个Action都是线程安全的。因为每过来一个request，它就创建一个Action对象。由于现代JDK垃圾收集功能的效率已经不成问题，所以这种创建完一个对象就扔掉的模式也得到了好多人的认可。Rod Johnson甚至以此为例证明J2EE提供的object pool功能是没多大价值的。 <br />但是当人们在吹嘘线程安全怎么怎么重要的时候，我想请问有多少人在多少情况下需要考虑线程安全？Rod Johnson在分析EJB的时候也提出过其它问题，并不是没有了EJB的线程安全魔法，世界就会灭亡的，大多数情况下，我们根本不需要考虑线程安全的问题，也不考虑object pool。因为我们大多数情况下不需要保持instance状态。 <br />至少我写了那么多的struts Action，写了那么多的Spring Controller，几乎没有碰到需要在instance变量保持状态的问题。当然也许是我写的代码不够多，Struts的设计者Craig R. McClanahan曾经说当时他设计struts时有两个条件不成熟：当时没有测试驱动开发的概念；当时JVM的垃圾收集性能太次。假如现在重新设计的话，他也会采用每个request生成一个新对象的设计方法，这样可以解决掉线程安全的问题了。<br /><br /><span class="postbody">四、 Spring不象Webwork2或tapestry那样去隐藏Servlet相关的元素如HttpServletRequest或HttpServletResponse <br />这又是一个重要的设计决定。在Webwork2里我们没有HttpServletRequest或者HttpServletResponse，只有getter, setter或ActionContext里数据，这样的结果导致一个干净的Action，一个与Web完全无关的Action，一个可以在任何环境下独立运行的bean。那么Webwork2的这样一个基于Command模式的Action究竟给我们带来了什么?我想主要有两点： <br />1、 它使我们的Action可以非常容易地被测试。 <br />2、 用户可以在Action里添加业务逻辑，并被其它类重用。 <br />然而仔细跟Spring比较一下，我们就会发现这两点功能所带来的好处其实并不象我们想象的那么显著。Spring的Controller类也可以非常轻松被测试，看一下spring-mock下面的包吧，它提供的MockHttpServletRequest, MockHttpServletResponse还有其它一些类让测试Controller变得异常轻松。再看一下Action里的业务逻辑吧，Jason Carreira曾经说我们可以尽情地在Webwork2的Action里加业务逻辑，因为Action是不依赖于Web的。但是有多少人真正往Action里加业务逻辑的？大多数人都会业务逻辑delegate给另一个Service类或Manager类。因为我们很清楚，往Action里加业务逻辑会使整个体系的分层架构变得不清晰，不管怎样，Web层就是Web层，业务层就是业务层，两者的逻辑混在一起总会带来问题的。而且往Action里加业务逻辑会使用这个Action类变得庞大，Webwork2的Action是每个request都创建实例的，尽管带来的性能影响不太大，但并不表示每次都要把业务逻辑再new出来，业务逻辑在大多数的情况下应该是单例的。 <br />不把request和response展现给用户当然还会带来功能上的损失，也许一般的场合，用用webwork2提供的接口已经足够了，但有时我们必须要知道request和response才能发挥出更大的威力。比如我以前的一个项目里有一个通过递归动态生成的树状结构的页面，在jsp页面上显示递归是痛苦或不可能的，因此我用response直接write出页面，这在spring里很easy，但在webwork里可能比较难了（偶不敢肯定，偶研究得不够深，也许高手是有办法的）。<br /><br /><span class="postbody">五、 Spring提供了不错但不够充分的interceptor机制 <br />回头看一下struts，它在架构里甚至没有给我们提供hook point的机会，我们没有任何机会加入自己的interceptor。我们只能通过重载struts的RequestProcessor类来进行一点有限的扩展。 <br />到了Webwork2，似乎interceptor一下子成了整个Framework的核心，除了Action的核心部件，其它所有的东西都是interceptor。它的超强的interceptor功能使们扩展整个架构变得非常方便。有人称这种interceptor为AOP，Jason Carreira则自豪地宣称这个叫做pragamtic AOP。我不认同这是AOP，它只是简单的interceptor机制。但不管如何，它的interceptor确实有强大的功能。 <br />Spring也提供了它的interceptor机制，它的HandlerInterceptor三个interceptor方法：peHandle, postHandle, afterCompletion。分别对应Controller执行前，Controller执行后和page render之后。虽然大多数情况下已经够用，但是从功能上来说显然它没有Webwork2强大。从AOP的角度来看，它没有提供around interceptor，而只有before与after interceptor。这意味着我们无法在interceptor前后保持状态，最简单的情况假如我们要计算一个Controller的执行时间，我们必须在执行完before后把begintime这个状态保持住，再在after里把它调出来，但是显然这个状态保持会是个问题，我们不能把它放到instance变量里，因为interceptor不是线程安全的。也许通过ThreadLocal可以解决这个问题，但是如此简单的功能要用到这样的方法来处理，显然这个Interceptor本身设计上还是有点问题的。 <br />六、 Spring提供了MultiActionController，使它可以在一个类里包含多个Action <br />这个设计和struts的DispatchAction有点类似，只不过提供了更灵活的机制。当我们的项目变大的时候，把功能类似的方法放到同一个Action里完全值得的！Webwork2缺少这样的机制。假如看一下Spring的源代码，会发现其实实现MultiActionController的工作量相当的少，只不过是用反射机制把解析出来的方法名执行一下就完事了。其实Webwork2也完全可以提供这样的机制。虽然从设计上来说确实不是很优雅，但是它确实很有用。<br /><br /><span class="postbody">七、 Spring提供了更多的选择方式 <br />看看Spring里提供的Controller吧，它提供了好多不同的Controller类。要生成Wizard吗？要专门用于提交form的Controller吗?要执多个方法的类吗?Spring提供了丰富的子类来扩展这些选择。当然我们还可以很轻松地自己扩展这些功能。 <br />再看看Spring的ViewResolver吧， 它提供了无数不同类型的ViewResolver。更重要的是我们自定义我们的页面映射方式。看看strtus，看看webwork2，都会存在页面与forward name的一层间接转换，我们必须在配置文件里配置好某个字符串（典型的是success）对应的是那个页面。但是Spring里我们有了更大的自由度，我们可以采用webwork2的策略，也可以采用更简单的策略，如将JSP文件名去掉扩展名的映射方法。也许有人认为这种映射方式很幼稚，但是我觉得它是非常有用的方式，即使在大项目里。 <br />还有新的扩展吗？看看Spring Web Flow吧，它是SpringFramework的子项目。它为一长串的基于页面流的Wizard页面提供了可配置的实现方式。在Spring 1.3里，它将是SpringFramework的一部分。 <br /><br />八、 Spring的tag <br />尽管Spring的tag数量上少得可怜，但它却是精心设计的。它的目标很简单：让美工可以轻松地编辑页面。因为在Spring的页面里Text仍然是Text，checkbox仍然是CheckBox，而不象在struts或webwork2中的Tag。它只是用Springbind对输入内容进行了一下包装。所以尽管页面显示代码上会比Webwork2多，但这绝对是有价值的。 <br /><br />在接下来的几章里，我会分析一下Spring是如何让我们的Web应用不需要知道ApplicationContext就能够访问IOC容器的，然后会对Spring的设计和执行过程进行简单的源码分析，然后给出几个扩展Spring MVC的方法。 <br /><br /></span></span></span></span>
		</span>
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/54180.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-06-21 12:36 <a href="http://www.blogjava.net/wuxufeng8080/articles/54180.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>心得：Spring AOP和Decorator模式</title><link>http://www.blogjava.net/wuxufeng8080/articles/54001.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Tue, 20 Jun 2006 07:44:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/54001.html</guid><wfw:comment>http://www.blogjava.net/wuxufeng8080/comments/54001.html</wfw:comment><comments>http://www.blogjava.net/wuxufeng8080/articles/54001.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuxufeng8080/comments/commentRss/54001.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuxufeng8080/services/trackbacks/54001.html</trackback:ping><description><![CDATA[
		<p align="center">
				<a title="xuesenlin" href="http://www.jdon.com/jive/profile.jsp?user=11119">
						<b>xuesenlin</b>
				</a> http://www.jdon.com Oct 27, 2004 11:05 PM <a href="http://www.jdon.com/jive/post.jsp?forum=91&amp;thread=17341&amp;message=8668553&amp;reply=true"><img height="17" alt="回复此消息" hspace="3" src="http://www.jdon.com/jive/images/reply.gif" width="17" border="0" /></a><font size="+0"><a title="回复此消息" href="http://www.jdon.com/jive/post.jsp?forum=91&amp;thread=17341&amp;message=8668553&amp;reply=true">回复</a></font></p>
		<p class="article">最近这个段时间都是忙于学习 SpringFramework，那东东好样的，只是刚刚学完Struts，Hibernate，有来了这个，呵呵，，感觉挺累的。<br />“你怎么把这两个不相干的东西撤到一起？” ，确实是这样！ 无论从他们的设计，<br />实现，使用等方面他们是风马牛不相及， 但本人认为从理解的方面看他们有点类似。况且学习要从对比中学呀！这对初学者会有帮助于理解。<br />重要声明：本人都是用自己的语言写的，有专业术语不对还请大家指出。: - ) <br />就说设计模式 <b>Decorator</b>,也就是装饰模式，这还不好理解？ 在原有的东西上进行装饰一下便是装饰了。既然是装饰，你要有主体呀（被修饰的东西），还要有装饰品。但是不管你装饰来装饰去，他的本质是不变的。 就象人带上了面具，但他还是人。墙上打上了油漆，但它还是墙呀。你也许觉得这是废话。 但理解这点很重要(这是跟策略模式Strategy的区别)，本人觉得这个是理解好 Decorator 模式很重要的一点。在开发中你经常要增强一个类的功能，或者是撤销一个类的某些功能，但是一个类给众多的功能进行装饰了以后，也许原来的类已经面目全非了，你往往会感到茫然，其实，你主要抓住他的主体，脑子里面时刻要知道你现在所作的工作就是为这个主体进行打扮的工作。<br />研究过Jive的都知道， 里面的 Filter 就是用了Decorator 设计模式，那么在这个设计里面，它的主体是什么？ ForumMessage ，无疑是 ForumMessage 。装饰品当然是Filter 了，所以我们在作这件事情的时候始终是以ForumMessage为核心的，Filter 进行装饰的时候，你千万不要忘记你现在是为ForumMessage而工作！有关于jive研究的文章，网上一大堆，现在看看一个比较简单的 Decorator:<br /><br /><br /><br /><font color="#0000aa">//比如有一个抽象构件：</font><font color="black"><br /><b>public</b><b>interface</b> Component {<br /><b>void</b> operation();<br />}<br /></font><font color="#0000aa">//一个具体构件：</font><font color="black"><br /><b>public</b><b>class</b> ConcreteComponent implements Component {<br /><b>public</b><b>void</b> operation() {<br /></font><font color="#0000aa">//Write your code here</font><font color="black"><br />}<br />}<br /></font><font color="#0000aa">//一个抽象装饰：</font><font color="black"><br /><b>public</b><b>class</b> Decorator implements Component {<br /><b>private</b> Component component; </font><font color="#0000aa">//引用</font><font color="black"><br />… …. …. …<br /></font><font color="#0000aa">//商业方法，委派给构件</font><font color="black"><br /><b>public</b><b>void</b> operation() {<br />component.operation();<br />}<br />}<br /></font><font color="#0000aa">//一个具体装饰：</font><font color="black"><br /><b>public</b><b>class</b> ConcreteDecorator <b>extends</b> Decorator {<br /></font><font color="#0000aa">/**<br />* 商业方法<br />*/</font><font color="black"><br /><b>public</b><b>void</b> operation(){<br /></font><font color="#0000aa">//一些具体的装饰的代码</font><font color="black"><br />......<br /><b>super</b>.operation(); </font><font color="#0000aa">// 主体</font><font color="black"><br /></font><font color="#0000aa">//一些具体的装饰的代码</font><font color="black"><br />.......<br />}<br />}<br /><pre></pre><br />......<br />我们主要看看，在ConcreteDecorator 中的operation() 方法，他的父类是委托到component组建来完成的，其实它就是主体， 一些装饰代码都会在这个方法（主体）执行前进行“预处理”或是执行后进行“收尾”。<br />可不是，从上面很容易就看出了，抽象装饰中的operation() 方法没有在具体的装饰类中进行“全盘”覆盖，因为他用了super.operation(); 这样的语句。可见装饰模式中不管怎么样， 你都要找到类似这个的方法。说明他的主体还在。(这是跟策略模式Strategy的区别)<br />说了怎么多，不知道大家有没有感觉到ConcreteDecorator类中的operation()方法跟Spring AOP 中的 InvocationHandler 接口的invoke()方法有点相类是呢？<br />我们来看看要实现 InvocationHandler 时候要重写的invoke()方法：<br /><br /><br /><br /><b>public</b> Object invoke(Object proxy, Method method, Object[] args)<br />throws Throwable {<br />…………………….<br />result = method.invoke(originalObject, args);<br />……………………………..<br /><b>return</b> result;<br />}<br /><pre></pre><br /><br />InvocationHandler.invoke 方法将在被代理类的方法被调用之前触发。通过这个方法中，我们可以在被代理类方法调用的前后进行一些处理，如上面代码中所示，InvocationHandler.invoke方法的参数中传递了当前被调用的方法（Method），以及被调用方法的参数。同时，我们可以通过Method.invoke方法调用被代理类的原始方法实现。这样，我们就可以在被代理类的方法调用前后大做文章。（说明：引用了Spring 开发指南中的一段）<br />在回到装饰模式，其方法operation() 在执行前和执行后，也可以对它大做文章。如此看来， Spring AOP 和 Decorator，从理解层面上来看，确实有点相象，注意：只是理解层面， 而他们的实现完全两马事！<br />其实主要是大家怎么看待这个问题，按照本人的理解，Spring AOP 也可以说是一种广义的装饰，但它又不是装饰模式。它同样也是对某个方法加上了限制，比如insert() 的时候，你要对它做执行前开启事务和执行后提交或回滚这样的“装饰”。 又比如你也可以对某个人操作资源后做log这样的装饰工作。等等，，<br />他们的相同之处就这么点。<br />AOP 也不是什么新的东西，当然如果你的AOP是容器(Jboss 4.0)实现的话， 那么按照上面说的，你的一些方法就会被容器所“装饰”。 <br />如此看来，更多的时候可以理解为 Spring AOP 和一些AOP 容器是在系统级的，容器级的“装饰”。 而装饰模式则是业务级的装饰。 这点其实从客户端也很容易理解。<br />如果是AOP ，程序员可以放心的写你的代码（即使有点笨也不怕，有AOP护着呢）。 因为系统将在系统运行时候对这段代码进行“装饰”。也就是说，这些装饰不会出现在客户端的代码中，，，而，Decorator模式呢？呵呵，这个时候程序员要有点头脑了，他们要自己组装一些装饰类，按照某一种机制对主体进行装饰。也就是说，这些修饰类要出现在客户端的代码中。看代码就知道了 :--)<br /><br /><br />InputStreamReader input = <b>new</b> InputStreamReader(System.in);<br />BufferedReader br = <b>new</b> BufferedReader(input)；<br />....</font><font color="#0000aa">//主体是System.in</font><font color="black"><br /><pre></pre><br />哦 ， 够经典的例子！</font></p>
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/54001.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-06-20 15:44 <a href="http://www.blogjava.net/wuxufeng8080/articles/54001.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SOP入门---第一個Spring AOP程式 </title><link>http://www.blogjava.net/wuxufeng8080/articles/53999.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Tue, 20 Jun 2006 07:42:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/53999.html</guid><wfw:comment>http://www.blogjava.net/wuxufeng8080/comments/53999.html</wfw:comment><comments>http://www.blogjava.net/wuxufeng8080/articles/53999.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuxufeng8080/comments/commentRss/53999.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuxufeng8080/services/trackbacks/53999.html</trackback:ping><description><![CDATA[
		<p>　　來使用Spring的AOP框架來重新撰寫之前「從代理機制初探AOP」主題中的程式，首先，Spring AOP預設使用動態代理來實作AOP，動態代理必須宣告被代理物件的介面： </p>
		<p>　代碼: </p>
		<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
				<div class="codeHeader" style="BORDER-BOTTOM-STYLE: solid">
						<b>IHello.java</b>
				</div>
				<div class="codeContent">
						<pre class="code-java">
								<span class="code-keyword">package</span> onlyfun.caterpillar; 

<span class="code-keyword">public</span><span class="code-keyword">interface</span> IHello { 
    <span class="code-keyword">public</span> void hello(<span class="code-object">String</span> name); 
    <span class="code-keyword">public</span> void morning(<span class="code-object">String</span> name); 
}</pre>
				</div>
		</div>
		<p>　　實作IHello介面的HelloSpeaker則如下： </p>
		<p>　代碼: </p>
		<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
				<div class="codeHeader" style="BORDER-BOTTOM-STYLE: solid">
						<b>HelloSpeaker.java</b>
				</div>
				<div class="codeContent">
						<pre class="code-java">
								<span class="code-keyword">package</span> onlyfun.caterpillar; 

<span class="code-keyword">public</span> class HelloSpeaker <span class="code-keyword">implements</span> IHello { 
    <span class="code-keyword">public</span> void hello(<span class="code-object">String</span> name) { 
        <span class="code-object">System</span>.out.println(<span class="code-quote">"Hello, "</span> + name); 
    } 

    <span class="code-keyword">public</span> void morning(<span class="code-object">String</span> name) { 
        <span class="code-object">System</span>.out.println(<span class="code-quote">"Morning, "</span> + name); 
    } 
}</pre>
				</div>
		</div>
		<p>　　我們希望在方法執行前後進行記錄的動作，在AOP中這需要Around類型的Advice，通常的，實作Around類型的策略是使用Interceptor。 </p>
		<p>　　Interceptor的一個例子是Servlet中的Filter機制，在Filter機制下，當請求來臨時，會被Filter先攔截並進行處理，之後傳給下一個Filter，最後才是真正處理請求的Servlet。實作AOP時所使用的Interceptor策略與Filter類似，所不同的是Filter被綁定於Servlet API，且只適用於請求階段。 </p>
		<p>　　您可以將一連串的Interceptor想成是堆疊結構，在Spring中，在真正執行某個方法前，會先插入Interceptor，每個Interceptor會執行自己的處理，然後再執行proceed，這將執行流程轉給下一個Interceptor，如果沒有下一個Interceptor了，就執行真正呼叫的方法，方法執行過後，再一層一層返回Interceptor堆疊，最後離開堆疊，如下圖，流程先是紅色，方法執行後的流程是藍色： </p>
		<p>　代碼: </p>
		<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
				<div class="codeContent">
						<pre class="code-java">&lt;-- --&gt; interceptor1 &lt;-- --&gt; interceptor2 &lt;-- --&gt; ..... &lt;-- --&gt; Invoked method</pre>
				</div>
		</div>
		<p>　　Spring在實作Interceptor時，是實作org.aopalliance.intercept.MethodInterceptor，AOP Alliance（<span class="nobr"><a title="Visit page outside Confluence" href="http://www.sourceforge.net/projects/aopalliance" rel="nofollow">http://www.sourceforge.net/projects/aopalliance<sup><img class="rendericon" height="7" alt="" src="http://www.javaworld.com.tw/confluence/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a></span>）的目標是制定AOP功能的標準介面，目前只提供一部份的子集合，子集包括了Interceptor，Spring實作MethodInterceptor，以求將來Interceptor的可移植性。 </p>
		<p>　　我們實作LogInterceptor如下： </p>
		<p>　代碼: </p>
		<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
				<div class="codeHeader" style="BORDER-BOTTOM-STYLE: solid">
						<b>LogInterceptor.java</b>
				</div>
				<div class="codeContent">
						<pre class="code-java">
								<span class="code-keyword">package</span> onlyfun.caterpillar; 

<span class="code-keyword">import</span> org.aopalliance.intercept.MethodInterceptor; 
<span class="code-keyword">import</span> org.aopalliance.intercept.MethodInvocation; 
<span class="code-keyword">import</span> java.util.logging.*; 

<span class="code-keyword">public</span> class LogInterceptor <span class="code-keyword">implements</span> MethodInterceptor { 
    <span class="code-keyword">private</span> Logger logger = Logger.getLogger(<span class="code-keyword">this</span>.getClass().getName()); 
    
   <span class="code-keyword">public</span><span class="code-object">Object</span> invoke(MethodInvocation methodInvocation) <span class="code-keyword">throws</span> Throwable { 
        logger.log(Level.INFO, <span class="code-quote">"method starts..."</span> + methodInvocation.getMethod()); 
        <span class="code-keyword">try</span> { 
          <span class="code-object">Object</span> result = methodInvocation.proceed(); 
          <span class="code-keyword">return</span> result; 
        } 
        <span class="code-keyword">finally</span> { 
            logger.log(Level.INFO, <span class="code-quote">"method ends..."</span> + methodInvocation.getMethod() + <span class="code-quote">"\n"</span>); 
        }        
   } 
}</pre>
				</div>
		</div>
		<p>　　invoke()中的MethodInvocation參數包括了下一個Interceptor的資訊、被執行的方法、以及方法所需的參數，其返回值是被呼叫方法的返回值。 </p>
		<p>　　我們還需要一個代理物件，這可以使用org.springframework.aop.framework.ProxyFactoryBean，它需要知道代理的介面與物件，以及所要介入的Interceptor，如下： </p>
		<p>　代碼: </p>
		<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
				<div class="codeContent">
						<pre class="code-java">&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?&gt; 
&lt;!DOCTYPE beans PUBLIC <span class="code-quote">"-<span class="code-comment">//SPRING/DTD BEAN/EN"</span><span class="code-quote">"http://www.springframework.org/dtd/spring-beans.dtd"</span>&gt; 
</span>&lt;beans&gt; 
    &lt;bean id=<span class="code-quote">"logInterceptor"</span> class=<span class="code-quote">"onlyfun.caterpillar.LogInterceptor"</span>/&gt; 

    &lt;bean id=<span class="code-quote">"helloSpeaker"</span> class=<span class="code-quote">"onlyfun.caterpillar.HelloSpeaker"</span>/&gt; 
    
    &lt;bean id=<span class="code-quote">"helloProxy"</span> class=<span class="code-quote">"org.springframework.aop.framework.ProxyFactoryBean"</span>&gt; 
        &lt;property name=<span class="code-quote">"proxyInterfaces"</span>&gt; 
            &lt;value&gt;onlyfun.caterpillar.IHello&lt;/value&gt; 
        &lt;/property&gt; 
        &lt;property name=<span class="code-quote">"target"</span>&gt; 
            &lt;ref bean=<span class="code-quote">"helloSpeaker"</span>/&gt; 
        &lt;/property&gt; 
        &lt;property name=<span class="code-quote">"interceptorNames"</span>&gt; 
            &lt;list&gt; 
                &lt;value&gt;logInterceptor&lt;/value&gt; 
            &lt;/list&gt; 
        &lt;/property&gt; 
    &lt;/bean&gt; 
&lt;/beans&gt;</pre>
				</div>
		</div>
		<p>　　Interceptor執行的順序是interceptorNames中設定的順序，最後是target目標物件，使用下面的程式來測試一下： </p>
		<p>　代碼: </p>
		<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
				<div class="codeHeader" style="BORDER-BOTTOM-STYLE: solid">
						<b>SpringTest.java</b>
				</div>
				<div class="codeContent">
						<pre class="code-java">
								<span class="code-keyword">package</span> onlyfun.caterpillar; 

<span class="code-keyword">import</span> org.springframework.context.*; 
<span class="code-keyword">import</span> org.springframework.context.support.*; 

<span class="code-keyword">public</span> class SpringTest { 
   <span class="code-keyword">public</span><span class="code-keyword">static</span> void main(<span class="code-object">String</span>[] args) { 
        ApplicationContext context = <span class="code-keyword">new</span> FileSystemXmlApplicationContext(<span class="code-quote">"bean.xml"</span>); 
        IHello helloProxy = (IHello) context.getBean(<span class="code-quote">"helloProxy"</span>); 
        helloProxy.hello(<span class="code-quote">"Justin"</span>); 
        helloProxy.morning(<span class="code-quote">"momor"</span>); 
    } 
}</pre>
				</div>
		</div>
		<p>　　執行結果如下： </p>
		<p>　代碼: </p>
		<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
				<div class="codeContent">
						<pre class="code-java">2004/11/26 上午 11:59:09 onlyfun.caterpillar.LogInterceptor invoke 
資訊: method starts...<span class="code-keyword">public</span><span class="code-keyword">abstract</span> void onlyfun.caterpillar.IHello.hello(java.lang.<span class="code-object">String</span>) 
Hello, Justin 
2004/11/26 上午 11:59:09 onlyfun.caterpillar.LogInterceptor invoke 
資訊: method ends...<span class="code-keyword">public</span><span class="code-keyword">abstract</span> void onlyfun.caterpillar.IHello.hello(java.lang.<span class="code-object">String</span>) 

2004/11/26 上午 11:59:09 onlyfun.caterpillar.LogInterceptor invoke 
資訊: method starts...<span class="code-keyword">public</span><span class="code-keyword">abstract</span> void onlyfun.caterpillar.IHello.morning(java.lang.<span class="code-object">String</span>) 
Morning, momor 
2004/11/26 上午 11:59:09 onlyfun.caterpillar.LogInterceptor invoke 
資訊: method ends...<span class="code-keyword">public</span><span class="code-keyword">abstract</span> void onlyfun.caterpillar.IHello.morning(java.lang.<span class="code-object">String</span>)</pre>
				</div>
		</div>
		<p>　　完成了第一個Spring AOP程式了，不過這當中還有許多細節可以說明，下一個主題再繼續。</p>
		<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
    rdf:about="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2427"
    dc:identifier="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2427"
    dc:title="入門 41 - 第一個Spring AOP程式"
    trackback:ping="http://www.javaworld.com.tw/confluence/rpc/trackback/2427"/>
</rdf:RDF>
-->
		<!--
    Root decorator: all decisions about how a page is to be decorated via the
                    inline decoration begins here.
-->
		<!--
    Switch based upon the context. However, for now, just delegate to a decorator
    identified directly by the context.
-->
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/53999.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-06-20 15:42 <a href="http://www.blogjava.net/wuxufeng8080/articles/53999.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>