﻿<?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/freeman1984/category/42533.html</link><description>         
        STANDING ON THE SHOULDERS OF GIANTS</description><language>zh-cn</language><lastBuildDate>Fri, 12 Apr 2013 01:41:59 GMT</lastBuildDate><pubDate>Fri, 12 Apr 2013 01:41:59 GMT</pubDate><ttl>60</ttl><item><title>Spring和 jms </title><link>http://www.blogjava.net/freeman1984/archive/2013/04/11/397697.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Thu, 11 Apr 2013 03:30:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2013/04/11/397697.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/397697.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2013/04/11/397697.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/397697.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/397697.html</trackback:ping><description><![CDATA[<p><span style="font-family: 宋体">主要的几个类说明</span>:</p>
<p><span style="font-family: 'Courier New';background: silver; color: black">1 </span><span style="font-family: 'Courier New';background: silver; color: black">JmsTemplate</span> <span style="font-family: 宋体;background: silver; color: black">用于发送和接受消息。需要消息工厂参数。</span></p>
<p><span style="font-family: 宋体;background: silver; color: black">基于监听：</span></p>
<p><span style="font-family: 'Courier New';background: silver; color: black">2 </span><span style="font-family: 'Courier New';background: silver; color: black">DefaultMessageListenerContainer</span><span style="font-family: 宋体;background: silver; color: black">，</span><span style="font-family: 'Courier New';background: silver; color: black">SimpleMessageListenerContainer</span><span style="font-family: 宋体;background: silver; color: black">这两个容器可以创建多个</span><span style="font-family: 'Courier New';background: silver; color: black">session</span><span style="font-family: 宋体;background: silver; color: black">和消费者来对每个队列进行消息处理并条用消息监听类的方法进行处理。并通过多线程进行处理。每个线程通过轮训的方式</span><span style="font-family: 'Courier New';background: silver; color: black">(while(true))</span><span style="font-family: 宋体;background: silver; color: black">去进行消息接收处理。</span></p>
<p><span style="font-family: 'Courier New';background: silver; color: black">3 </span><span style="font-family: 'Courier New';background: white; color: black">MessageListenerAdapter</span> <span style="font-family: 宋体;background: white; color: black">它相当于一个特殊的自定义监听器，里面可以调用一些消息格式的装换工具。例如</span><span style="font-family: 'Courier New';background: white; color: black">json</span><span style="font-family: 宋体;background: white; color: black">，</span><span style="font-family: 'Courier New';background: white; color: black">xml</span><span style="font-family: 宋体;background: white; color: black">，</span><span style="font-family: 'Courier New';background: white; color: black">string</span><span style="font-family: 宋体;background: white; color: black">到</span><span style="font-family: 'Courier New';background: white; color: black">bean</span><span style="font-family: 宋体;background: white; color: black">的转换等等。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体;background: silver; color: black">其中</span><span style="font-family: 'Courier New';background: silver; color: black">DefaultMessageListenerContainer</span><span style="font-family: 宋体;background: silver; color: black">接受动态添加</span><span style="font-family: 'Courier New';background: silver; color: black">session</span><span style="font-family: 宋体;background: silver; color: black">。而后者不支持。</span></p>
<p><span style="font-family: 'Courier New';background: silver; color: black">----</span></p>
<p><span style="font-family: 宋体;background: silver; color: black">具体消息监听处理源码过程如下：以</span><span style="font-family: 'Courier New';background: silver; color: black">DefaultMessageListenerContainer</span><span style="font-family: 宋体;background: silver; color: black">为例：</span></p>
<p><span style="font-family: 'Courier New';background: silver; color: black">----</span></p>
<p><strong><em><span style="font-family: 'Courier New';background: silver; color: black">1 </span></em></strong><strong><em><span style="font-family: 宋体;background: silver; color: black">初始化建立消费者线程：</span></em></strong><strong><em></em></strong></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf; font-size: 9pt">/**</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;* Creates the specified number of concurrent consumers,</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;* in the form of a JMS Session plus associated MessageConsumer.</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;* </span><strong><span style="font-family: 'Courier New'; color: #7f9fbf; font-size: 9pt">@see</span></strong><span style="font-family: 'Courier New'; color: #3f5fbf; font-size: 9pt"> #createListenerConsumer</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;*/</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">protected</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">void</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> doInitialize() </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">throws</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> JMSException {</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; establishSharedConnection();</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="background: silver">initializeConsumers</span>();</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">protected</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">void</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> <span style="background: silver">initializeConsumers</span>() </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">throws</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> JMSException {</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Courier New'; color: #3f7f5f; font-size: 9pt">// Register Sessions and MessageConsumers.</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">synchronized</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (</span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">consumersMonitor</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">) {</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">if</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (</span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">consumers</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> == </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">null</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">) {</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">sessions</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> = </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">new</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> HashSet&lt;Session&gt;(</span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">concurrentConsumers</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">);</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">consumers</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> = </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">new</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> HashSet&lt;MessageConsumer&gt;(</span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">concurrentConsumers</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">);</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Connection con = getSharedConnection();</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">for</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (</span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">int</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> i = 0; i &lt; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">concurrentConsumers</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">; i++) {</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <strong>Session session = createSession(con);</strong></span><strong></strong></p>
<p align="left"><strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MessageConsumer consumer = createListenerConsumer(session);</span></strong><strong></strong></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">sessions</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.add(session);</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">consumers</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.add(consumer);</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; }</span></p>
<p><strong><em><span style="font-family: 'Courier New';background: silver; color: black">2 </span></em></strong><strong><em><span style="font-family: 宋体;background: silver; color: black">启动消费者线程</span></em></strong><strong><em></em></strong></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">/**</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;* Start the shared Connection, if any, and notify all invoker tasks.</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;* </span><strong><span style="font-family: 'Courier New'; color: #7f9fbf">@throws</span></strong><span style="font-family: 'Courier New'; color: #3f5fbf"> JMSException if thrown by JMS API methods</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;* </span><strong><span style="font-family: 'Courier New'; color: #7f9fbf">@see</span></strong><span style="font-family: 'Courier New'; color: #3f5fbf"> #startSharedConnection</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;*/</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">protected</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055">void</span></strong><span style="font-family: 'Courier New'; color: black"> <span style="background: silver">doStart</span>() </span><strong><span style="font-family: 'Courier New'; color: #7f0055">throws</span></strong><span style="font-family: 'Courier New'; color: black"> JMSException {</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Courier New'; color: #3f7f5f">// Lazily establish a shared Connection, if necessary.</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">if</span></strong><span style="font-family: 'Courier New'; color: black"> (sharedConnectionEnabled()) {</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; establishSharedConnection();</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Courier New'; color: #3f7f5f">// Reschedule paused tasks, if any.</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">synchronized</span></strong><span style="font-family: 'Courier New'; color: black"> (</span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">.</span><span style="font-family: 'Courier New'; color: #0000c0">lifecycleMonitor</span><span style="font-family: 'Courier New'; color: black">) {</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">.</span><span style="font-family: 'Courier New'; color: #0000c0">running</span><span style="font-family: 'Courier New'; color: black"> = </span><strong><span style="font-family: 'Courier New'; color: #7f0055">true</span></strong><span style="font-family: 'Courier New'; color: black">;</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">.</span><span style="font-family: 'Courier New'; color: #0000c0">lifecycleMonitor</span><span style="font-family: 'Courier New'; color: black">.notifyAll();</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <strong>resumePausedTasks();</strong></span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Courier New'; color: #3f7f5f">// Start the shared Connection, if any.</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">if</span></strong><span style="font-family: 'Courier New'; color: black"> (sharedConnectionEnabled()) {</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; startSharedConnection();</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; }</span></p>
<p><strong><em><span style="font-family: 'Courier New';background: silver; color: black">3</span></em></strong><strong><em><span style="font-family: 宋体;background: silver; color: black">消息消费</span></em></strong><strong><em></em></strong></p>
<p><span style="font-family: 'Courier New'; color: black">其中的<span style="background: silver">resumePausedTasks</span></span><span style="font-family: 宋体;background: silver; color: black">方法会进行轮训处理：</span></p>
<p><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">protected</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">void</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> <span style="background: silver">resumePausedTasks</span>() {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">synchronized</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (</span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">lifecycleMonitor</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">) {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">if</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (!</span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">pausedTasks</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.isEmpty()) {</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">//</span><span style="font-family: 宋体; color: black; font-size: 9pt">所有的线程一开始会被置为暂停</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">for</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (Iterator&lt;?&gt; it = </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">pausedTasks</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.iterator(); it.hasNext();) {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Object task = it.next();</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">try</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; doRescheduleTask(task);</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; it.remove();</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">if</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">logger</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.isDebugEnabled()) {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 9pt">logger</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">.debug(</span><span style="font-family: 'Courier New'; color: #2a00ff; font-size: 9pt">"Resumed paused task: "</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> + task);</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">catch</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (RuntimeException ex) {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logRejectedTask(task, ex);</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Courier New'; color: #3f7f5f; font-size: 9pt">// Keep the task in paused mode...</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 宋体; color: black; font-size: 9pt">每个线程是一个</span> <span style="font-family: 'Courier New';background: silver; color: black">AsyncMessageListenerInvoker</span><span style="font-family: 宋体;background: silver; color: black">，通过它的</span><span style="font-family: 'Courier New';background: silver; color: black">run</span><span style="font-family: 宋体;background: silver; color: black">方法来进行消息处理：</span></p>
<p><span style="font-family: 宋体;background: silver; color: black">先执行：</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">private</span></strong> <strong><span style="font-family: 'Courier New';background: silver; color: #7f0055">boolean</span></strong><span style="font-family: 'Courier New'; color: black"> invokeListener() </span><strong><span style="font-family: 'Courier New'; color: #7f0055">throws</span></strong><span style="font-family: 'Courier New'; color: black"> JMSException {</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="background: silver">initResourcesIfNecessary</span>();</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">boolean</span></strong><span style="font-family: 'Courier New'; color: black"> messageReceived = <span style="background: silver">receiveAndExecute</span>(</span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">, </span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">.</span><span style="font-family: 'Courier New'; color: #0000c0">session</span><span style="font-family: 'Courier New'; color: black">, </span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">.</span><span style="font-family: 'Courier New'; color: #0000c0">consumer</span><span style="font-family: 'Courier New'; color: black">);</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">.</span><span style="font-family: 'Courier New'; color: #0000c0">lastMessageSucceeded</span><span style="font-family: 'Courier New'; color: black"> = </span><strong><span style="font-family: 'Courier New'; color: #7f0055">true</span></strong><span style="font-family: 'Courier New'; color: black">;</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New';background: silver; color: #7f0055">return</span></strong><span style="font-family: 'Courier New';background: silver; color: black"> messageReceived;</span></p>
<p align="left"><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><span style="font-family: 宋体;background: silver; color: black">接着：</span></p>
<p><span style="font-family: 'Courier New';background: white; color: black">Message message = receiveMessage(</span><span style="font-family: 'Courier New';background: silver; color: black">consumerToUse</span><span style="font-family: 'Courier New';background: white; color: black">);</span></p>
<p>&nbsp;</p>
<p><strong><em><span style="font-family: 宋体;background: white; color: black">这就是最终的阻塞方法去获取消息</span></em></strong><span style="font-family: 宋体;background: white; color: black">：</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">/**</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;* Receive a message from the given consumer.</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;* </span><strong><span style="font-family: 'Courier New'; color: #7f9fbf">@param</span></strong><span style="font-family: 'Courier New'; color: #3f5fbf"> consumer the MessageConsumer to use</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;* </span><strong><span style="font-family: 'Courier New'; color: #7f9fbf">@return</span></strong><span style="font-family: 'Courier New'; color: #3f5fbf"> the Message, or </span><span style="font-family: 'Courier New'; color: #7f7f9f">&lt;code&gt;</span><span style="font-family: 'Courier New'; color: #3f5fbf">null</span><span style="font-family: 'Courier New'; color: #7f7f9f">&lt;/code&gt;</span><span style="font-family: 'Courier New'; color: #3f5fbf"> if none</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;* </span><strong><span style="font-family: 'Courier New'; color: #7f9fbf">@throws</span></strong><span style="font-family: 'Courier New'; color: #3f5fbf"> JMSException if thrown by JMS methods</span></p>
<p><span style="font-family: 'Courier New'; color: #3f5fbf">&nbsp;&nbsp;&nbsp; &nbsp;*/</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">protected</span></strong><span style="font-family: 'Courier New'; color: black"> Message <span style="background: silver">receiveMessage</span>(MessageConsumer consumer) </span><strong><span style="font-family: 'Courier New'; color: #7f0055">throws</span></strong><span style="font-family: 'Courier New'; color: black"> JMSException {</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055">return</span></strong><span style="font-family: 'Courier New'; color: black"> (</span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">.</span><span style="font-family: 'Courier New'; color: #0000c0">receiveTimeout</span><span style="font-family: 'Courier New'; color: black"> &lt; 0 ? consumer.receive() : consumer.receive(</span><strong><span style="font-family: 'Courier New'; color: #7f0055">this</span></strong><span style="font-family: 'Courier New'; color: black">.</span><span style="font-family: 'Courier New'; color: #0000c0">receiveTimeout</span><span style="font-family: 'Courier New'; color: black">));</span></p>
<p><span style="font-family: 'Courier New'; color: black">&nbsp;&nbsp;&nbsp; }</span></p>
<p><strong><em><span style="font-family: 'Courier New'; color: black">4</span></em></strong><strong><em><span style="font-family: 宋体; color: black">调用我们自定义的监听器：</span></em></strong><strong><em></em></strong></p>
<p><strong><em><span style="font-family: 宋体; color: black">其中监听器可以实现</span></em></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">SessionAwareMessageListener</span><span style="font-family: 宋体; color: black; font-size: 9pt">和</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">MessageListener</span><span style="font-family: 宋体; color: black; font-size: 9pt">接口，不一样的地方在于前者会把</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">session</span><span style="font-family: 宋体; color: black; font-size: 9pt">，</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">message</span><span style="font-family: 宋体; color: black; font-size: 9pt">参数给你，你可以进行一个回调操作。后者只有消息内容</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">message</span><span style="font-family: 宋体; color: black; font-size: 9pt">参数。</span><strong><em></em></strong></p>
<p><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">protected</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">void</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> <span style="background: silver">invokeListener</span>(Session session, Message message) </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">throws</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> JMSException {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Object listener = getMessageListener();</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">if</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (listener </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">instanceof</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> <strong>SessionAwareMessageListener</strong>) {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; doInvokeListener((SessionAwareMessageListener) listener, session, message);</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">else</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">if</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (listener </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">instanceof</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> <strong>MessageListener</strong>) {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; doInvokeListener((MessageListener) listener, message);</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">else</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">if</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> (listener != </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">null</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt">) {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">throw</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">new</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> IllegalArgumentException(</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Courier New'; color: #2a00ff; font-size: 9pt">"Only MessageListener and SessionAwareMessageListener supported: "</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> + listener);</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">else</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> {</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">throw</span></strong> <strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 9pt">new</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 9pt"> IllegalStateException(</span><span style="font-family: 'Courier New'; color: #2a00ff; font-size: 9pt">"No message listener specified - see property 'messageListener'"</span><span style="font-family: 'Courier New'; color: black; font-size: 9pt">);</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: 'Courier New'; color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp; }</span></p><img src ="http://www.blogjava.net/freeman1984/aggbug/397697.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2013-04-11 11:30 <a href="http://www.blogjava.net/freeman1984/archive/2013/04/11/397697.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring jdbc(java类型和oracle类型的转换)</title><link>http://www.blogjava.net/freeman1984/archive/2013/01/06/393854.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Sun, 06 Jan 2013 03:09:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2013/01/06/393854.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/393854.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2013/01/06/393854.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/393854.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/393854.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; spring在执行sql语句时，会根据用户提供的类型参数来进行sql参数的绑定，例如：Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public&nbsp;int&nbsp;update(String&nbsp;sql,&nbsp;...&nbsp;&nbsp;<a href='http://www.blogjava.net/freeman1984/archive/2013/01/06/393854.html'>阅读全文</a><img src ="http://www.blogjava.net/freeman1984/aggbug/393854.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2013-01-06 11:09 <a href="http://www.blogjava.net/freeman1984/archive/2013/01/06/393854.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring :硬编码注入bean实例</title><link>http://www.blogjava.net/freeman1984/archive/2012/11/16/391469.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Fri, 16 Nov 2012 09:12:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2012/11/16/391469.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/391469.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2012/11/16/391469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/391469.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/391469.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: spring :硬编码注入bean实例&nbsp;&nbsp;<a href='http://www.blogjava.net/freeman1984/archive/2012/11/16/391469.html'>阅读全文</a><img src ="http://www.blogjava.net/freeman1984/aggbug/391469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2012-11-16 17:12 <a href="http://www.blogjava.net/freeman1984/archive/2012/11/16/391469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Quartz+Spring的集群配置(转)</title><link>http://www.blogjava.net/freeman1984/archive/2012/05/11/377882.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Fri, 11 May 2012 03:02:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2012/05/11/377882.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/377882.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2012/05/11/377882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/377882.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/377882.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 原来配置的Quartz是通过spring配置文件生效的，发现在非集群式的服务器上运行良好，但是将工程部署到水平集群服务器上去后改定时功能不能正常运行，没有任何错误日志，于是从jar包、JDK版本、cronExpression到服务器类型，甚至查到了服务器操作系统的类型，都没能找到解决的办法，后来才知道是集群惹的祸！ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb...&nbsp;&nbsp;<a href='http://www.blogjava.net/freeman1984/archive/2012/05/11/377882.html'>阅读全文</a><img src ="http://www.blogjava.net/freeman1984/aggbug/377882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2012-05-11 11:02 <a href="http://www.blogjava.net/freeman1984/archive/2012/05/11/377882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring rss 实例</title><link>http://www.blogjava.net/freeman1984/archive/2012/05/09/377665.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 09 May 2012 02:01:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2012/05/09/377665.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/377665.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2012/05/09/377665.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/377665.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/377665.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Spring rss 实例demo&nbsp;&nbsp;<a href='http://www.blogjava.net/freeman1984/archive/2012/05/09/377665.html'>阅读全文</a><img src ="http://www.blogjava.net/freeman1984/aggbug/377665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2012-05-09 10:01 <a href="http://www.blogjava.net/freeman1984/archive/2012/05/09/377665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate，spring管理事务中(transaction，JDBC connection，Hibernate Session的使用研究)（一）</title><link>http://www.blogjava.net/freeman1984/archive/2011/11/18/363984.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Fri, 18 Nov 2011 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/11/18/363984.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/363984.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/11/18/363984.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/363984.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/363984.html</trackback:ping><description><![CDATA[如果单独使用hibernate可参考上一篇文章<a href="http://www.blogjava.net/freeman1984/archive/2011/08/04/355808.html">http://www.blogjava.net/freeman1984/archive/2011/08/04/355808.html</a><br /><br /><strong>首先hibernate的Connection release mode有以下几种：<br /></strong>1 after_statement 2 after_transaction 3 on_close 其中after_statement 用在jta中 ，<span style="color: red"><strong>on_close 是3.1之前遗留的（也许是为spring留的-_-），也就是3.1之前默认是on_close ，但3.1之后默认如果单独使用hibernate是after_transaction，</strong></span>如果有第三方事务管理，就用第三方提供的默认值，spring就是默认使用了on_close。<br /><strong>在spring管理事务中我们看看系统启动后默认使用的配置：<br /></strong>1,ransaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory使用spring事务策略<br />2，hibernate内部 Automatic session close at end of transaction: disabled 因为已经交给spring了<br />3&nbsp;&nbsp; Connection release mode: auto 默认，也就是没有配置hibernate.connection.release_mode的时候，但是这里有地方需要注意：也就是前面提到的使用第三方策略时的问题：看一下代码： 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><span style="color: #000000">String&nbsp;releaseModeName&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;PropertiesHelper.getString(&nbsp;Environment.RELEASE_CONNECTIONS,&nbsp;properties,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">auto</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;);<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.info(&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">Connection&nbsp;release&nbsp;mode:&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;releaseModeName&nbsp;);<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ConnectionReleaseMode&nbsp;releaseMode;<br /><img id="Codehighlighter1_246_311_Open_Image" onclick="this.style.display='none'; Codehighlighter1_246_311_Open_Text.style.display='none'; Codehighlighter1_246_311_Closed_Image.style.display='inline'; Codehighlighter1_246_311_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_246_311_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_246_311_Closed_Text.style.display='none'; Codehighlighter1_246_311_Open_Image.style.display='inline'; Codehighlighter1_246_311_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">auto</span><span style="color: #000000">"</span><span style="color: #000000">.equals(releaseModeName)&nbsp;)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_246_311_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_246_311_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: red">releaseMode&nbsp;</span><span style="color: red">=</span><span style="color: red">&nbsp;transactionFactory.getDefaultReleaseMode();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" /></span></span><span style="color: #000000"><br /><img id="Codehighlighter1_320_663_Open_Image" onclick="this.style.display='none'; Codehighlighter1_320_663_Open_Text.style.display='none'; Codehighlighter1_320_663_Closed_Image.style.display='inline'; Codehighlighter1_320_663_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_320_663_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_320_663_Closed_Text.style.display='none'; Codehighlighter1_320_663_Open_Image.style.display='inline'; Codehighlighter1_320_663_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_320_663_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_320_663_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;releaseMode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ConnectionReleaseMode.parse(&nbsp;releaseModeName&nbsp;);<br /><img id="Codehighlighter1_494_659_Open_Image" onclick="this.style.display='none'; Codehighlighter1_494_659_Open_Text.style.display='none'; Codehighlighter1_494_659_Closed_Image.style.display='inline'; Codehighlighter1_494_659_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_494_659_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_494_659_Closed_Text.style.display='none'; Codehighlighter1_494_659_Open_Image.style.display='inline'; Codehighlighter1_494_659_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;releaseMode&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;ConnectionReleaseMode.AFTER_STATEMENT&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">!</span><span style="color: #000000">connections.supportsAggressiveRelease()&nbsp;)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_494_659_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_494_659_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.warn(&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">Overriding&nbsp;release&nbsp;mode&nbsp;as&nbsp;connection&nbsp;provider&nbsp;does&nbsp;not&nbsp;support&nbsp;'after_statement'</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;);<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;releaseMode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ConnectionReleaseMode.AFTER_TRANSACTION;<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>其中红色部分就是调用了spring提供的默认值，而spring的默认值：在jta和cmt中都默认使用的是after_statement<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img id="Codehighlighter1_0_328_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_328_Open_Text.style.display='none'; Codehighlighter1_0_328_Closed_Image.style.display='inline'; Codehighlighter1_0_328_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_0_328_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_0_328_Closed_Text.style.display='none'; Codehighlighter1_0_328_Open_Image.style.display='inline'; Codehighlighter1_0_328_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif"><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_0_328_Closed_Text">/**&nbsp;*/</span><span id="Codehighlighter1_0_328_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;connection&nbsp;release&nbsp;mode&nbsp;"on_close"&nbsp;as&nbsp;default.<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;p&gt;This&nbsp;was&nbsp;the&nbsp;case&nbsp;for&nbsp;Hibernate&nbsp;3.0;&nbsp;Hibernate&nbsp;3.1&nbsp;changed<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;it&nbsp;to&nbsp;"auto"&nbsp;(i.e.&nbsp;"after_statement"&nbsp;or&nbsp;"after_transaction").<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;However,&nbsp;for&nbsp;Spring's&nbsp;resource&nbsp;management&nbsp;(in&nbsp;particular&nbsp;for<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;HibernateTransactionManager),&nbsp;"on_close"&nbsp;is&nbsp;the&nbsp;better&nbsp;default.<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br /><img id="Codehighlighter1_384_428_Open_Image" onclick="this.style.display='none'; Codehighlighter1_384_428_Open_Text.style.display='none'; Codehighlighter1_384_428_Closed_Image.style.display='inline'; Codehighlighter1_384_428_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_384_428_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_384_428_Closed_Text.style.display='none'; Codehighlighter1_384_428_Open_Image.style.display='inline'; Codehighlighter1_384_428_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;ConnectionReleaseMode&nbsp;getDefaultReleaseMode()&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_384_428_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_384_428_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;ConnectionReleaseMode.ON_CLOSE;<br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span></div><br />而spring为什么要使用on_close ，而不是用after_transaction ,我们想想opensessioninview的原理也许能明白，session在view成还要使用，所以不能再transactio<span>n使用完后关闭JDBC connection，必须要在session之后，所以要使用on<strong>_close</strong></span><strong><span>（</span><span>也就是在on session(flush.auto，或者flush.Eagerly) 关闭）。这种情况hibernate内部还会在spring关闭JDBC connection后提示(费解，因为after transaction之后session没有关闭，但是&nbsp;Connection release mode配置的是on_close,session的关闭和&nbsp;Connection 的关闭都由spring来管理，hibernate就不知道了)，所以hibernate有好的提示如下(其实session，已经关闭。当然随着session的关闭jdbc链接释放回连接池)：</span><br /><span style="color: red">transaction completed on session with on_close connection release mode; be sure to cl</span></strong>ose the session to release JDBC resources!，<br /><br />。当然我们也可以使用after_transaction ，这种情况对使用编程式事务非常适用。<br />&nbsp;&nbsp;&nbsp;&nbsp;   <img src ="http://www.blogjava.net/freeman1984/aggbug/363984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-11-18 11:25 <a href="http://www.blogjava.net/freeman1984/archive/2011/11/18/363984.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring JdbcTemplate的queryForObject为空返回异常情况的一个处理</title><link>http://www.blogjava.net/freeman1984/archive/2011/10/25/361976.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Tue, 25 Oct 2011 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/10/25/361976.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/361976.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/10/25/361976.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/361976.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/361976.html</trackback:ping><description><![CDATA[看spring的queryForObject(如果查询结果条数为0或者大于1)都会返回异常，我们希望没查到返回null，这样我们就可以给用户提示没有找到，要不我们的每个queryforObject，queryForInt...等等方法都需要手动拦截这个异常来判断为空，才能做出判断。<br />先看下spring的这段源码： 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img id="Codehighlighter1_106_252_Open_Image" onclick="this.style.display='none'; Codehighlighter1_106_252_Open_Text.style.display='none'; Codehighlighter1_106_252_Closed_Image.style.display='inline'; Codehighlighter1_106_252_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_106_252_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_106_252_Closed_Text.style.display='none'; Codehighlighter1_106_252_Open_Image.style.display='inline'; Codehighlighter1_106_252_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif"><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;T&nbsp;queryForObject(String&nbsp;sql,&nbsp;Object[]&nbsp;args,&nbsp;RowMapper</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;rowMapper)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;DataAccessException&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_106_252_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_106_252_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;List</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;results&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;query(sql,&nbsp;args,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;RowMapperResultSetExtractor</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">(rowMapper,&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">));<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;DataAccessUtils.requiredSingleResult(results);<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span><span style="color: #000000"><br /><img id="Codehighlighter1_364_686_Open_Image" onclick="this.style.display='none'; Codehighlighter1_364_686_Open_Text.style.display='none'; Codehighlighter1_364_686_Closed_Image.style.display='inline'; Codehighlighter1_364_686_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_364_686_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_364_686_Closed_Text.style.display='none'; Codehighlighter1_364_686_Open_Image.style.display='inline'; Codehighlighter1_364_686_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif"></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;T&nbsp;requiredSingleResult(Collection</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;results)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;IncorrectResultSizeDataAccessException&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_364_686_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_364_686_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(results&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;results.size()&nbsp;:&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">);<br /><img id="Codehighlighter1_436_544_Open_Image" onclick="this.style.display='none'; Codehighlighter1_436_544_Open_Text.style.display='none'; Codehighlighter1_436_544_Closed_Image.style.display='inline'; Codehighlighter1_436_544_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_436_544_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_436_544_Closed_Text.style.display='none'; Codehighlighter1_436_544_Open_Image.style.display='inline'; Codehighlighter1_436_544_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(size&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_436_544_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_436_544_Open_Text"><span style="color: #000000">{</span><span style="color: #008000">//</span><span style="color: #008000">记录为o返回异常</span><span style="color: #008000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;EmptyResultDataAccessException(</span><span style="color: #000000">1</span><span style="color: #000000">);</span><span style="color: #008000">//</span><span style="color: #008000">此异常继承自IncorrectResultSizeDataAccessException</span><span style="color: #008000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img id="Codehighlighter1_572_647_Open_Image" onclick="this.style.display='none'; Codehighlighter1_572_647_Open_Text.style.display='none'; Codehighlighter1_572_647_Closed_Image.style.display='inline'; Codehighlighter1_572_647_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_572_647_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_572_647_Closed_Text.style.display='none'; Codehighlighter1_572_647_Open_Image.style.display='inline'; Codehighlighter1_572_647_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(results.size()&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_572_647_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_572_647_Open_Text"><span style="color: #000000">{有多条记录返回异常<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;IncorrectResultSizeDataAccessException(</span><span style="color: #000000">1</span><span style="color: #000000">,&nbsp;size);<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;results.iterator().next();<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />&nbsp;}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif"  alt="" /></span></div><br /><br />下面是我的一个方法，其他的方法请大家补充：<br />写一个接口定义规则： 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img id="Codehighlighter1_41_89_Open_Image" onclick="this.style.display='none'; Codehighlighter1_41_89_Open_Text.style.display='none'; Codehighlighter1_41_89_Closed_Image.style.display='inline'; Codehighlighter1_41_89_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_41_89_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_41_89_Closed_Text.style.display='none'; Codehighlighter1_41_89_Open_Image.style.display='inline'; Codehighlighter1_41_89_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif"><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;JdbcTemplateCallBack</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_41_89_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_41_89_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;&nbsp;T&nbsp;querys(JdbcTemplate&nbsp;jdbcTemplate);<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div>然后是BaseDao的通用的方法：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img id="Codehighlighter1_0_174_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_174_Open_Text.style.display='none'; Codehighlighter1_0_174_Closed_Image.style.display='inline'; Codehighlighter1_0_174_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_0_174_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_0_174_Closed_Text.style.display='none'; Codehighlighter1_0_174_Open_Image.style.display='inline'; Codehighlighter1_0_174_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif"><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_0_174_Closed_Text">/**&nbsp;*/</span><span id="Codehighlighter1_0_174_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;可以用于处理查询queryfor&nbsp;为空或者多条的时候返回异常的情况，现在返回null,主要是拦截IncorrectResultSizeDataAccessException异常,以及子类<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080">@param</span><span style="color: #008000">&nbsp;jdbcTemplateCallBack<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080">@return</span><span style="color: #008000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080">@throws</span><span style="color: #008000">&nbsp;DaoException<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br /><img id="Codehighlighter1_270_565_Open_Image" onclick="this.style.display='none'; Codehighlighter1_270_565_Open_Text.style.display='none'; Codehighlighter1_270_565_Closed_Image.style.display='inline'; Codehighlighter1_270_565_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_270_565_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_270_565_Closed_Text.style.display='none'; Codehighlighter1_270_565_Open_Image.style.display='inline'; Codehighlighter1_270_565_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;T&nbsp;queryNullAble(JdbcTemplateCallBack</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;jdbcTemplateCallBack)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;DaoException&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_270_565_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_270_565_Open_Text"><span style="color: #000000">{<br /><img id="Codehighlighter1_278_340_Open_Image" onclick="this.style.display='none'; Codehighlighter1_278_340_Open_Text.style.display='none'; Codehighlighter1_278_340_Closed_Image.style.display='inline'; Codehighlighter1_278_340_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_278_340_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_278_340_Closed_Text.style.display='none'; Codehighlighter1_278_340_Open_Image.style.display='inline'; Codehighlighter1_278_340_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_278_340_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_278_340_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;jdbcTemplateCallBack.querys(getJdbcTemplate());<br /><img id="Codehighlighter1_362_562_Open_Image" onclick="this.style.display='none'; Codehighlighter1_362_562_Open_Text.style.display='none'; Codehighlighter1_362_562_Closed_Image.style.display='inline'; Codehighlighter1_362_562_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_362_562_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_362_562_Closed_Text.style.display='none'; Codehighlighter1_362_562_Open_Image.style.display='inline'; Codehighlighter1_362_562_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Exception&nbsp;e)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_362_562_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_362_562_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">((e&nbsp;</span><span style="color: #0000ff">instanceof</span><span style="color: #000000">&nbsp;IncorrectResultSizeDataAccessException)<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">((IncorrectResultSizeDataAccessException)e).getActualSize()</span><span style="color: #000000">==</span><span style="color: #000000">0</span><span style="color: #000000">)<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">其他的异常正常抛出</span><span style="color: #008000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;DaoException(e);<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div><br />最后是调用实例（根据id查用户）：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img id="Codehighlighter1_94_352_Open_Image" onclick="this.style.display='none'; Codehighlighter1_94_352_Open_Text.style.display='none'; Codehighlighter1_94_352_Closed_Image.style.display='inline'; Codehighlighter1_94_352_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_94_352_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_94_352_Closed_Text.style.display='none'; Codehighlighter1_94_352_Open_Image.style.display='inline'; Codehighlighter1_94_352_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif"><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SUser&nbsp;getUserByColunm(</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;String&nbsp;columnName,&nbsp;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;Object&nbsp;value)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;DaoException&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_94_352_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_94_352_Open_Text"><span style="color: #000000">{<br /><img id="Codehighlighter1_153_347_Open_Image" onclick="this.style.display='none'; Codehighlighter1_153_347_Open_Text.style.display='none'; Codehighlighter1_153_347_Closed_Image.style.display='inline'; Codehighlighter1_153_347_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_153_347_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_153_347_Closed_Text.style.display='none'; Codehighlighter1_153_347_Open_Image.style.display='inline'; Codehighlighter1_153_347_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;queryNullAble(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;JdbcTemplateCallBack</span><span style="color: #000000">&lt;</span><span style="color: #000000">SUser</span><span style="color: #000000">&gt;</span><span style="color: #000000">()&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_153_347_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_153_347_Open_Text"><span style="color: #000000">{<br /><img id="Codehighlighter1_205_343_Open_Image" onclick="this.style.display='none'; Codehighlighter1_205_343_Open_Text.style.display='none'; Codehighlighter1_205_343_Closed_Image.style.display='inline'; Codehighlighter1_205_343_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_205_343_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_205_343_Closed_Text.style.display='none'; Codehighlighter1_205_343_Open_Image.style.display='inline'; Codehighlighter1_205_343_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SUser&nbsp;querys(JdbcTemplate&nbsp;jdbcTemplate)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_205_343_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_205_343_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;jdbcTemplate.queryForObject(</span><span style="color: #000000">"</span><span style="color: #000000">select&nbsp;*&nbsp;&nbsp;from&nbsp;suser&nbsp;where&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">columnName</span><span style="color: #000000">+</span><span style="color: #000000">"</span><span style="color: #000000">=?</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;BeanPropertyRowMapper(SUser.</span><span style="color: #0000ff">class</span><span style="color: #000000">),value);<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">);<br /><img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div><br />具体的工程可以在<a href="http://www.blogjava.net/freeman1984/archive/2011/10/24/361899.html">http://www.blogjava.net/freeman1984/archive/2011/10/24/361899.html</a>里面下载。<br /><br /> <img src ="http://www.blogjava.net/freeman1984/aggbug/361976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-10-25 10:59 <a href="http://www.blogjava.net/freeman1984/archive/2011/10/25/361976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring3.1 mvc+spring jdbc实例以及源码下载</title><link>http://www.blogjava.net/freeman1984/archive/2011/10/24/361899.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Mon, 24 Oct 2011 07:54:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/10/24/361899.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/361899.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/10/24/361899.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/361899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/361899.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: spring3.1 mvc+spring jdbc实例&nbsp;&nbsp;<a href='http://www.blogjava.net/freeman1984/archive/2011/10/24/361899.html'>阅读全文</a><img src ="http://www.blogjava.net/freeman1984/aggbug/361899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-10-24 15:54 <a href="http://www.blogjava.net/freeman1984/archive/2011/10/24/361899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Introspector 缓存清除监听器</title><link>http://www.blogjava.net/freeman1984/archive/2011/07/19/354651.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Tue, 19 Jul 2011 09:08:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/07/19/354651.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/354651.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/07/19/354651.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/354651.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/354651.html</trackback:ping><description><![CDATA[<p>Spring 提供了一个名为 org.springframework.web.util.IntrospectorCleanupListener 的监听器。它主要负责处理由 JavaBean Introspector 功能而引起的缓存泄露。IntrospectorCleanupListener 监听器在 Web 应用关闭的时会负责清除 JavaBean Introspector 的缓存，在 web.xml 中注册这个监听器可以保证在 Web 应用关闭的时候释放与其相关的 ClassLoader 的缓存和类引用。如果您使用了 JavaBean Introspector 分析应用中的类，Introspector 缓存会保留这些类的引用，结果在应用关闭的时候，这些类以及 Web 应用相关的 ClassLoader 不能被垃圾回收。不幸的是，清除 Introspector 的唯一方式是刷新整个缓存，这是因为没法准确判断哪些是属于本 Web 应用的引用对象，哪些是属于其它 Web 应用的引用对象。所以删除被缓存的 Introspection 会导致将整个 JVM 所有应用的 Introspection 都删掉。需要注意的是，Spring 托管的 Bean 不需要使用这个监听器，因为 Spring 的 Introspection 所使用的缓存在分析完一个类之后会马上从 javaBean Introspector 缓存中清除掉，并将缓存保存在应用程序特定的 ClassLoader 中，所以它们一般不会导致内存资源泄露。但是一些类库和框架往往会产生这个问题。例如 Struts 和 Quartz 的 Introspector 的内存泄漏会导致整个的 Web 应用的 ClassLoader 不能进行垃圾回收。在 Web 应用关闭之后，您还会看到此应用的所有静态类引用，这个错误当然不是由这个类自身引起的。解决这个问题的方法很简单，您仅需在 web.xml 中配置 IntrospectorCleanupListener 监听器就可以了：</p>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td class="code-outline"><pre class="displaycode"> &lt;listener&gt; 
    &lt;listener-class&gt; 
    org.springframework.web.util.IntrospectorCleanupListener 
    &lt;/listener-class&gt; 
 &lt;/listener&gt; 
</pre></td></tr></tbody></table><br /><img src ="http://www.blogjava.net/freeman1984/aggbug/354651.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-07-19 17:08 <a href="http://www.blogjava.net/freeman1984/archive/2011/07/19/354651.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring jmx 简单例子 使用jconsole查看</title><link>http://www.blogjava.net/freeman1984/archive/2011/02/15/344370.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Tue, 15 Feb 2011 08:59:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/02/15/344370.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/344370.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/02/15/344370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/344370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/344370.html</trackback:ping><description><![CDATA[将JmxTestBean发布成jmx：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><br />
<br />
<img id="Codehighlighter1_25_464_Open_Image" onclick="this.style.display='none'; Codehighlighter1_25_464_Open_Text.style.display='none'; Codehighlighter1_25_464_Closed_Image.style.display='inline'; Codehighlighter1_25_464_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"  alt="" /><img style="display: none" id="Codehighlighter1_25_464_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_25_464_Closed_Text.style.display='none'; Codehighlighter1_25_464_Open_Image.style.display='inline'; Codehighlighter1_25_464_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif"  alt="" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;JmxTestBean&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_25_464_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_25_464_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;String&nbsp;name;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;age;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /><br />
<img id="Codehighlighter1_95_121_Open_Image" onclick="this.style.display='none'; Codehighlighter1_95_121_Open_Text.style.display='none'; Codehighlighter1_95_121_Closed_Image.style.display='inline'; Codehighlighter1_95_121_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"  alt="" /><img style="display: none" id="Codehighlighter1_95_121_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_95_121_Closed_Text.style.display='none'; Codehighlighter1_95_121_Open_Image.style.display='inline'; Codehighlighter1_95_121_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;getAge()&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_95_121_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_95_121_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;age;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /><br />
<img id="Codehighlighter1_156_186_Open_Image" onclick="this.style.display='none'; Codehighlighter1_156_186_Open_Text.style.display='none'; Codehighlighter1_156_186_Closed_Image.style.display='inline'; Codehighlighter1_156_186_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"  alt="" /><img style="display: none" id="Codehighlighter1_156_186_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_156_186_Closed_Text.style.display='none'; Codehighlighter1_156_186_Open_Image.style.display='inline'; Codehighlighter1_156_186_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setAge(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;age)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_156_186_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_156_186_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.age&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;age;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img id="Codehighlighter1_230_262_Open_Image" onclick="this.style.display='none'; Codehighlighter1_230_262_Open_Text.style.display='none'; Codehighlighter1_230_262_Closed_Image.style.display='inline'; Codehighlighter1_230_262_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"  alt="" /><img style="display: none" id="Codehighlighter1_230_262_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_230_262_Closed_Text.style.display='none'; Codehighlighter1_230_262_Open_Image.style.display='inline'; Codehighlighter1_230_262_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setName(String&nbsp;name)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_230_262_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_230_262_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.name&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;name;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /><br />
<img id="Codehighlighter1_293_320_Open_Image" onclick="this.style.display='none'; Codehighlighter1_293_320_Open_Text.style.display='none'; Codehighlighter1_293_320_Closed_Image.style.display='inline'; Codehighlighter1_293_320_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"  alt="" /><img style="display: none" id="Codehighlighter1_293_320_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_293_320_Closed_Text.style.display='none'; Codehighlighter1_293_320_Open_Image.style.display='inline'; Codehighlighter1_293_320_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;getName()&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_293_320_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_293_320_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;name;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /><br />
<img id="Codehighlighter1_356_384_Open_Image" onclick="this.style.display='none'; Codehighlighter1_356_384_Open_Text.style.display='none'; Codehighlighter1_356_384_Closed_Image.style.display='inline'; Codehighlighter1_356_384_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"  alt="" /><img style="display: none" id="Codehighlighter1_356_384_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_356_384_Closed_Text.style.display='none'; Codehighlighter1_356_384_Open_Image.style.display='inline'; Codehighlighter1_356_384_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;add(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;y)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_356_384_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_356_384_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;x&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;y;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /><br />
<img id="Codehighlighter1_418_462_Open_Image" onclick="this.style.display='none'; Codehighlighter1_418_462_Open_Text.style.display='none'; Codehighlighter1_418_462_Closed_Image.style.display='inline'; Codehighlighter1_418_462_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif"  alt="" /><img style="display: none" id="Codehighlighter1_418_462_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_418_462_Closed_Text.style.display='none'; Codehighlighter1_418_462_Open_Image.style.display='inline'; Codehighlighter1_418_462_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;dontExposeMe()&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_418_462_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_418_462_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;RuntimeException();<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div>
<br />
spring配置：<br />
<p>&nbsp;&lt;bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;property name="beans"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;map&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;entry key="bean:name=testBean1" value-ref="testBean"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/map&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp; &lt;/bean&gt;</p>
<p>&nbsp; &lt;bean id="testBean" class="com.joe.spring.jmx.JmxTestBean"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;property name="name" value="TEST"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;property name="age" value="100"/&gt;<br />
&nbsp; &lt;/bean&gt;</p>
在tomcat启动参数添加-Dcom.sun.management.jmxremote 然后打开jconsole可以查看<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/freeman1984/jmx.jpg" />
<img src ="http://www.blogjava.net/freeman1984/aggbug/344370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-02-15 16:59 <a href="http://www.blogjava.net/freeman1984/archive/2011/02/15/344370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring 声明式事务</title><link>http://www.blogjava.net/freeman1984/archive/2011/01/08/342605.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Sat, 08 Jan 2011 13:52:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/01/08/342605.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/342605.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/01/08/342605.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/342605.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/342605.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 此文只是记录一下，如有问题给我留言。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">TransactionTemplate&nbsp;template&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;TransactionTemplate(transactionManager);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);<br />
<img id="Codehighlighter1_219_362_Open_Image" onclick="this.style.display='none'; Codehighlighter1_219_362_Open_Text.style.display='none'; Codehighlighter1_219_362_Closed_Image.style.display='inline'; Codehighlighter1_219_362_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_219_362_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_219_362_Closed_Text.style.display='none'; Codehighlighter1_219_362_Open_Image.style.display='inline'; Codehighlighter1_219_362_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template.execute(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;TransactionCallbackWithoutResult()&nbsp;</span><span id="Codehighlighter1_219_362_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_219_362_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
<img id="Codehighlighter1_309_352_Open_Image" onclick="this.style.display='none'; Codehighlighter1_309_352_Open_Text.style.display='none'; Codehighlighter1_309_352_Closed_Image.style.display='inline'; Codehighlighter1_309_352_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_309_352_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_309_352_Closed_Text.style.display='none'; Codehighlighter1_309_352_Open_Image.style.display='inline'; Codehighlighter1_309_352_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;doInTransactionWithoutResult(TransactionStatus&nbsp;status)&nbsp;</span><span id="Codehighlighter1_309_352_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_309_352_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;testDao.save(obj);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">);</span></div>
<p>&nbsp;异常需要在外层catch 因为提交时在transaction而不是save炒作。<br />
&nbsp; <br />
声明式事务主要用于：<br />
&nbsp; 1：相对于配置式<br />
&nbsp;2：要将长事务分成小事务，在此期间其他事务将挂起（Suspend ）直到当前事务提交完成</p>
<p>&nbsp;</p>
<p>---------</p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/342605.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-01-08 21:52 <a href="http://www.blogjava.net/freeman1984/archive/2011/01/08/342605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>事务策略: 了解事务陷阱</title><link>http://www.blogjava.net/freeman1984/archive/2010/10/11/334484.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Mon, 11 Oct 2010 15:06:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/10/11/334484.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/334484.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/10/11/334484.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/334484.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/334484.html</trackback:ping><description><![CDATA[<p>前沿（笔者加）：事务（Transaction）是每一个与数据库有关的系统开发与设计人员都会接触到的东西，在Java中，传统的直接使用JDBC的事务开始、提交、回滚的方式已经随着各种应用开发框架（尤其是Spring）的出现变得对开发人员更加简单，开发人员直接将事务的处理交由spring处理，只关心具体业务，但是实际上Spring对事务的控制有自己的一套体系（笔者在Spring配置中transactionAttributes的意义一文中，曾介绍spring关于事务的部分配置及说明），如果开发设计人员对其没有深入了解，很容易出现事务没有正常提交，甚至出现事务不提交的情况，今天发现本文对于事务及其在Spring、EJB中的应用，详细介绍了如何正确使用事务，希望可以对读者有帮助。</p>
<p>事务策略: 了解事务陷阱<br />
在 Java 平台中实现事务时要注意的常见错误</p>
<p>级别： 中级</p>
<p>Mark Richards, 主管和高级技术架构师, Collaborative Consulting, LLC</p>
<p>2009 年 3 月 06 日</p>
<p>事务处理的目标应该是实现数据的高度完整性和一致性。本文是为 Java 平台开发有效事务策略 系列文章 的第一篇，介绍了一些妨碍您实现此目标的常见事务陷阱。本系列作者 Mark Richards 通过使用 Spring Framework 和企业 JavaBeans（Enterprise JavaBeans，EJB）3.0 规范中的代码示例解释了这些极其常见的错误。<br />
在应用程序中使用事务常常是为了维护高度的数据完整性和一致性。如果不关心数据的质量，就不必使用事务。毕竟，Java 平台中的事务支持会降低性能，引发锁定问题和数据库并发性问题，而且会增加应用程序的复杂性。</p>
<p>但是不关心事务的开发人员就会遇到麻烦。几乎所有与业务相关的应用程序都需要高度的数据质量。金融投资行业在失败的交易上浪费数百亿美元，不好的数据是导致这种结果的第二大因素（请参阅 参考资料）。尽然缺少事务支持只是导致坏数据的一个因素（但是是主要的因素），但是完全可以这样认为，在金融投资行业浪费掉数十亿美元是由于缺少事务支持或事务支持不充分。</p>
<p>忽略事务支持是导致问题的另一个原因。我常常听到 &#8220;我们的应用程序中不需要事务支持，因为这些应用程序从来不会失败&#8221; 之类的说法。是的，我知道有些应用程序极少或从来不会抛出异常。这些应用程序基于编写良好的代码、编写良好的验证例程，并经过了充分的测试，有代码覆盖支持，可以避免性能损耗和与事务处理有关的复杂性。这种类型的应用程序只需考虑事务支持的一个特性：原子性。原子性确保所有更新被当作一个单独的单元，要么全部提交，要么回滚。但是回滚或同时更新不是事务支持的惟一方面。另一方面，隔离性 将确保某一工作单元独立于其他工作单元。没有适当的事务隔离性，其他工作单元就可以访问某一活动工作单元所做的更新，即使该工作单元还未完成。这样，就会基于部分数据作出业务决策，而这会导致失败的交易或产生其他负面（或代价昂贵的）结果。</p>
<p>因此，考虑到坏数据的高成本和负面影响，以及事务的重要性（和必须性）这些基本常识，您需要使用事务处理并学习如何处理可能出现的问题。您在应用程序中添加事务支持后常常会出现很多问题。事务在 Java 平台中并不总是如预想的那样工作。本文会探讨其中的原因。我将借助代码示例，介绍一些我在该领域中不断看到的和经历的常见事务陷阱，大部分是在生产环境中。</p>
<p>虽然本文中的大多数代码示例使用的是 Spring Framework（version 2.5），但事务概念与 EJB 3.0 规范中的是相同的。在大多数情况下，用 EJB 3.0 规范中的 _cnnew1@TransactionAttribute 注释替换 Spring Framework @Transactional 注释即可。如果这两种框架使用了不同的概念和技术，我将同时给出 Spring Framework 和 EJB 3.0 源代码示例。</p>
<p>本地事务陷阱</p>
<p>最好先从最简单的场景开始，即使用本地事务，一般也称为数据库事务。在数据库持久性的早期（例如 JDBC），我们一般会将事务处理委派给数据库。毕竟这是数据库应该做的。本地事务很适合执行单一插入、更新或删除语句的逻辑工作单元（LUW）。例如，考虑清单 1 中的简单 JDBC 代码，它向 TRADE 表插入一份股票交易订单：</p>
<p><br />
清单 1. 使用 JDBC 的简单数据库插入</p>
<p>view plaincopy to clipboardprint?<br />
@Stateless&nbsp; <br />
public class TradingServiceImpl implements TradingService {&nbsp;&nbsp; <br />
&nbsp;&nbsp; @Resource SessionContext ctx;&nbsp;&nbsp; <br />
&nbsp;&nbsp; @Resource(mappedName="java:jdbc/tradingDS") DataSource ds;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp; public long insertTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Connection dbConnection = ds.getConnection();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Statement sql = dbConnection.createStatement();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String stmt =&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "INSERT INTO TRADE (ACCT_ID, SIDE, SYMBOL, SHARES, PRICE, STATE)"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "VALUES ("&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getAcct() + "','"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getAction() + "','"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getSymbol() + "',"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getShares() + ","&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getPrice() + ",'"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getState() + "')";&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sql.executeUpdate(stmt, Statement.RETURN_GENERATED_KEYS);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSet rs = sql.getGeneratedKeys();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rs.next()) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rs.getBigDecimal(1).longValue();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("Trade Order Insert Failed");&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dbConnection != null) dbConnection.close();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
@Stateless<br />
public class TradingServiceImpl implements TradingService {<br />
&nbsp;&nbsp; @Resource SessionContext ctx;<br />
&nbsp;&nbsp; @Resource(mappedName="java:jdbc/tradingDS") DataSource ds;</p>
<p>&nbsp;&nbsp; public long insertTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Connection dbConnection = ds.getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Statement sql = dbConnection.createStatement();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String stmt =<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "INSERT INTO TRADE (ACCT_ID, SIDE, SYMBOL, SHARES, PRICE, STATE)"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "VALUES ("<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getAcct() + "','"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getAction() + "','"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getSymbol() + "',"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getShares() + ","<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getPrice() + ",'"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + trade.getState() + "')";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sql.executeUpdate(stmt, Statement.RETURN_GENERATED_KEYS);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSet rs = sql.getGeneratedKeys();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rs.next()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rs.getBigDecimal(1).longValue();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("Trade Order Insert Failed");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dbConnection != null) dbConnection.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
} </p>
<p>清单 1 中的 JDBC 代码没有包含任何事务逻辑，它只是在数据库中保存 TRADE 表中的交易订单。在本例中，数据库处理事务逻辑。</p>
<p>在 LUW 中，这是一个不错的单个数据库维护操作。但是如果需要在向数据库插入交易订单的同时更新帐户余款呢？如清单 2 所示：</p>
<p><br />
清单 2. 在同一方法中执行多次表更新</p>
<p>view plaincopy to clipboardprint?<br />
public TradeData placeTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; try {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertTrade(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateAcct(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade;&nbsp;&nbsp; <br />
&nbsp;&nbsp; } catch (Exception up) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log the error&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw up;&nbsp;&nbsp; <br />
&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
public TradeData placeTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertTrade(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateAcct(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade;<br />
&nbsp;&nbsp; } catch (Exception up) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log the error<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw up;<br />
&nbsp;&nbsp; }<br />
} </p>
<p>在本例中，insertTrade() 和 updateAcct() 方法使用不带事务的标准 JDBC 代码。insertTrade() 方法结束后，数据库保存（并提交了）交易订单。如果 updateAcct() 方法由于任意原因失败，交易订单仍然会在 placeTrade() 方法结束时保存在 TRADE 表内，这会导致数据库出现不一致的数据。如果 placeTrade() 方法使用了事务，这两个活动都会包含在一个 LUW 中，如果帐户更新失败，交易订单就会回滚。</p>
<p>随着 Java 持久性框架的不断普及，如 Hibernate、TopLink 和 Java 持久性 API（Java Persistence API，JPA），我们很少再会去编写简单的 JDBC 代码。更常见的情况是，我们使用更新的对象关系映射（ORM）框架来减轻工作，即用几个简单的方法调用替换所有麻烦的 JDBC 代码。例如，要插入 清单 1 中 JDBC 代码示例的交易订单，使用带有 JPA 的 Spring Framework，就可以将 TradeData 对象映射到 TRADE 表，并用清单 3 中的 JPA 代码替换所有 JDBC 代码：</p>
<p><br />
清单 3. 使用 JPA 的简单插入</p>
<p>view plaincopy to clipboardprint?<br />
public class TradingServiceImpl {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; @PersistenceContext(unitName="trading") EntityManager em;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public long insertTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; em.persist(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade.getTradeId();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
public class TradingServiceImpl {<br />
&nbsp;&nbsp;&nbsp; @PersistenceContext(unitName="trading") EntityManager em;</p>
<p>&nbsp;&nbsp;&nbsp; public long insertTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; em.persist(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade.getTradeId();<br />
&nbsp;&nbsp;&nbsp; }<br />
} </p>
<p>注意，清单 3 在 EntityManager 上调用了 persist() 方法来插入交易订单。很简单，是吧？其实不然。这段代码不会像预期那样向 TRADE 表插入交易订单，也不会抛出异常。它只是返回一个值 0 作为交易订单的键，而不会更改数据库。这是事务处理的主要陷阱之一：基于 ORM 的框架需要一个事务来触发对象缓存与数据库之间的同步。这通过一个事务提交完成，其中会生成 SQL 代码，数据库会执行需要的操作（即插入、更新、删除）。没有事务，就不会触发 ORM 去生成 SQL 代码和保存更改，因此只会终止方法 — 没有异常，没有更新。如果使用基于 ORM 的框架，就必须利用事务。您不再依赖数据库来管理连接和提交工作。</p>
<p>这些简单的示例应该清楚地说明，为了维护数据完整性和一致性，必须使用事务。不过对于在 Java 平台中实现事务的复杂性和陷阱而言，这些示例只是涉及了冰山一角。</p>
<p>Spring Framework @Transactional 注释陷阱</p>
<p>您将测试 清单 3 中的代码，发现 persist() 方法在没有事务的情况下不能工作。因此，您通过简单的网络搜索查看几个链接，发现如果使用 Spring Framework，就需要使用 @Transactional 注释。于是您在代码中添加该注释，如清单 4 所示：</p>
<p><br />
清单 4. 使用 @Transactional 注释</p>
<p>view plaincopy to clipboardprint?<br />
public class TradingServiceImpl {&nbsp;&nbsp; <br />
&nbsp;&nbsp; @PersistenceContext(unitName="trading") EntityManager em;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp; @Transactional&nbsp; <br />
&nbsp;&nbsp; public long insertTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; em.persist(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade.getTradeId();&nbsp;&nbsp; <br />
&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
public class TradingServiceImpl {<br />
&nbsp;&nbsp; @PersistenceContext(unitName="trading") EntityManager em;</p>
<p>&nbsp;&nbsp; @Transactional<br />
&nbsp;&nbsp; public long insertTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; em.persist(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade.getTradeId();<br />
&nbsp;&nbsp; }<br />
} </p>
<p>现在重新测试代码，您发现上述方法仍然不能工作。问题在于您必须告诉 Spring Framework，您正在对事务管理应用注释。除非您进行充分的单元测试，否则有时候很难发现这个陷阱。这通常只会导致开发人员在 Spring 配置文件中简单地添加事务逻辑，而不会使用注释。</p>
<p>要在 Spring 中使用 @Transactional 注释，必须在 Spring 配置文件中添加以下代码行：</p>
<p>view plaincopy to clipboardprint?<br />
&lt;tx:annotation-driven transaction-manager="transactionManager"/&gt;&nbsp; <br />
&lt;tx:annotation-driven transaction-manager="transactionManager"/&gt; </p>
<p>transaction-manager 属性保存一个对在 Spring 配置文件中定义的事务管理器 bean 的引用。这段代码告诉 Spring 在应用事务拦截器时使用 @Transaction 注释。如果没有它，就会忽略 @Transactional 注释，导致代码不会使用任何事务。</p>
<p>让基本的 @Transactional 注释在 清单 4 的代码中工作仅仅是开始。注意，清单 4 使用 @Transactional 注释时没有指定任何额外的注释参数。我发现许多开发人员在使用 @Transactional 注释时并没有花时间理解它的作用。例如，像我一样在清单 4 中单独使用 @Transactional 注释时，事务传播模式被设置成什么呢？只读标志被设置成什么呢？事务隔离级别的设置是怎样的？更重要的是，事务应何时回滚工作？理解如何使用这个注释对于确保在应用程序中获得合适的事务支持级别非常重要。回答我刚才提出的问题：在单独使用不带任何参数的 @Transactional 注释时，传播模式要设置为 REQUIRED，只读标志设置为 false，事务隔离级别设置为 READ_COMMITTED，而且事务不会针对受控异常（checked exception）回滚。</p>
<p>@Transactional 只读标志陷阱</p>
<p>我在工作中经常碰到的一个常见陷阱是 Spring @Transactional 注释中的只读标志没有得到恰当使用。这里有一个快速测试方法：在使用标准 JDBC 代码获得 Java 持久性时，如果只读标志设置为 true，传播模式设置为 SUPPORTS，清单 5 中的 @Transactional 注释的作用是什么呢？</p>
<p><br />
清单 5. 将只读标志与 SUPPORTS 传播模式结合使用 — JDBC</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)&nbsp;&nbsp; <br />
public long insertTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; //JDBC Code...&nbsp;&nbsp; <br />
}&nbsp; <br />
@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)<br />
public long insertTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp; //JDBC Code...<br />
} </p>
<p>当执行清单 5 中的 insertTrade() 方法时，猜一猜会得到下面哪一种结果：</p>
<p>抛出一个只读连接异常 <br />
正确插入交易订单并提交数据 <br />
什么也不做，因为传播级别被设置为 SUPPORTS <br />
是哪一个呢？正确答案是 B。交易订单会被正确地插入到数据库中，即使只读标志被设置为 true，且事务传播模式被设置为 SUPPORTS。但这是如何做到的呢？由于传播模式被设置为 SUPPORTS，所以不会启动任何事物，因此该方法有效地利用了一个本地（数据库）事务。只读标志只在事务启动时应用。在本例中，因为没有启动任何事务，所以只读标志被忽略。</p>
<p>如果是这样的话，清单 6 中的 @Transactional 注释在设置了只读标志且传播模式被设置为 REQUIRED 时，它的作用是什么呢？</p>
<p><br />
清单 6. 将只读标志与 REQUIRED 传播模式结合使用 — JDBC</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(readOnly = true, propagation=Propagation.REQUIRED)&nbsp;&nbsp; <br />
public long insertTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; //JDBC code...&nbsp;&nbsp; <br />
}&nbsp; <br />
@Transactional(readOnly = true, propagation=Propagation.REQUIRED)<br />
public long insertTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp; //JDBC code...<br />
}</p>
<p>执行清单 6 中的 insertTrade() 方法会得到下面哪一种结果呢：</p>
<p>抛出一个只读连接异常 <br />
正确插入交易订单并提交数据 <br />
什么也不做，因为只读标志被设置为 true <br />
根据前面的解释，这个问题应该很好回答。正确的答案是 A。会抛出一个异常，表示您正在试图对一个只读连接执行更新。因为启动了一个事务（REQUIRED），所以连接被设置为只读。毫无疑问，在试图执行 SQL 语句时，您会得到一个异常，告诉您该连接是一个只读连接。</p>
<p>关于只读标志很奇怪的一点是：要使用它，必须启动一个事务。如果只是读取数据，需要事务吗？答案是根本不需要。启动一个事务来执行只读操作会增加处理线程的开销，并会导致数据库发生共享读取锁定（具体取决于使用的数据库类型和设置的隔离级别）。总的来说，在获取基于 JDBC 的 Java 持久性时，使用只读标志有点毫无意义，并会启动不必要的事务而增加额外的开销。</p>
<p>使用基于 ORM 的框架会怎样呢？按照上面的测试，如果在结合使用 JPA 和 Hibernate 时调用 insertTrade() 方法，清单 7 中的 @Transactional 注释会得到什么结果？</p>
<p><br />
清单 7. 将只读标志与 REQUIRED 传播模式结合使用 — JPA</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(readOnly = true, propagation=Propagation.REQUIRED)&nbsp;&nbsp; <br />
public long insertTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; em.persist(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp; return trade.getTradeId();&nbsp;&nbsp; <br />
}&nbsp; <br />
@Transactional(readOnly = true, propagation=Propagation.REQUIRED)<br />
public long insertTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp; em.persist(trade);<br />
&nbsp;&nbsp; return trade.getTradeId();<br />
} </p>
<p>清单 7 中的 insertTrade() 方法会得到下面哪一种结果：</p>
<p>抛出一个只读连接异常 <br />
正确插入交易订单并提交数据 <br />
什么也不做，因为 readOnly 标志被设置为 true <br />
正确的答案是 B。交易订单会被准确无误地插入数据库中。请注意，上一示例表明，在使用 REQUIRED 传播模式时，会抛出一个只读连接异常。使用 JDBC 时是这样。使用基于 ORM 的框架时，只读标志只是对数据库的一个提示，并且一条基于 ORM 框架的指令（本例中是 Hibernate）将对象缓存的 flush 模式设置为 NEVER，表示在这个工作单元中，该对象缓存不应与数据库同步。不过，REQUIRED 传播模式会覆盖所有这些内容，允许事务启动并工作，就好像没有设置只读标志一样。</p>
<p>这令我想到了另一个我经常碰到的主要陷阱。阅读了前面的所有内容后，您认为如果只对 @Transactional 注释设置只读标志，清单 8 中的代码会得到什么结果呢？</p>
<p><br />
清单 8. 使用只读标志 — JPA</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(readOnly = true)&nbsp;&nbsp; <br />
public TradeData getTrade(long tradeId) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; return em.find(TradeData.class, tradeId);&nbsp;&nbsp; <br />
}&nbsp; <br />
@Transactional(readOnly = true)<br />
public TradeData getTrade(long tradeId) throws Exception {<br />
&nbsp;&nbsp; return em.find(TradeData.class, tradeId);<br />
} </p>
<p>清单 8 中的 getTrade() 方法会执行以下哪一种操作？</p>
<p>启动一个事务，获取交易订单，然后提交事务 <br />
获取交易订单，但不启动事务 <br />
正确的答案是 A。一个事务会被启动并提交。不要忘了，@Transactional 注释的默认传播模式是 REQUIRED。这意味着事务会在不必要的情况下启动。根据使用的数据库，这会引起不必要的共享锁，可能会使数据库中出现死锁的情况。此外，启动和停止事务将消耗不必要的处理时间和资源。总的来说，在使用基于 ORM 的框架时，只读标志基本上毫无用处，在大多数情况下会被忽略。但如果您坚持使用它，请记得将传播模式设置为 SUPPORTS（如清单 9 所示），这样就不会启动事务：</p>
<p><br />
清单 9. 使用只读标志和 SUPPORTS 传播模式进行选择操作</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)&nbsp;&nbsp; <br />
public TradeData getTrade(long tradeId) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; return em.find(TradeData.class, tradeId);&nbsp;&nbsp; <br />
}&nbsp; <br />
@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)<br />
public TradeData getTrade(long tradeId) throws Exception {<br />
&nbsp;&nbsp; return em.find(TradeData.class, tradeId);<br />
} </p>
<p>另外，在执行读取操作时，避免使用 @Transactional 注释，如清单 10 所示：</p>
<p>清单 10. 删除 @Transactional 注释进行选择操作</p>
<p>view plaincopy to clipboardprint?<br />
public TradeData getTrade(long tradeId) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; return em.find(TradeData.class, tradeId);&nbsp;&nbsp; <br />
}&nbsp; <br />
public TradeData getTrade(long tradeId) throws Exception {<br />
&nbsp;&nbsp; return em.find(TradeData.class, tradeId);<br />
} </p>
<p>REQUIRES_NEW 事务属性陷阱</p>
<p>不管是使用 Spring Framework，还是使用 EJB，使用 REQUIRES_NEW 事务属性都会得到不好的结果并导致数据损坏和不一致。REQUIRES_NEW 事务属性总是会在启动方法时启动一个新的事务。许多开发人员都错误地使用 REQUIRES_NEW 属性，认为它是确保事务启动的正确方法。考虑清单 11 中的两个方法：</p>
<p><br />
清单 11. 使用 REQUIRES_NEW 事务属性</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(propagation=Propagation.REQUIRES_NEW)&nbsp;&nbsp; <br />
public long insertTrade(TradeData trade) throws Exception {...}&nbsp;&nbsp; <br />
&nbsp; <br />
@Transactional(propagation=Propagation.REQUIRES_NEW)&nbsp;&nbsp; <br />
public void updateAcct(TradeData trade) throws Exception {...}&nbsp; <br />
@Transactional(propagation=Propagation.REQUIRES_NEW)<br />
public long insertTrade(TradeData trade) throws Exception {...}</p>
<p>@Transactional(propagation=Propagation.REQUIRES_NEW)<br />
public void updateAcct(TradeData trade) throws Exception {...} </p>
<p>注意，清单 11 中的两个方法都是公共方法，这意味着它们可以单独调用。当使用 REQUIRES_NEW 属性的几个方法通过服务间通信或编排在同一逻辑工作单元内调用时，该属性就会出现问题。例如，假设在清单 11 中，您可以独立于一些用例中的任何其他方法来调用 updateAcct() 方法，但也有在 insertTrade() 方法中调用 updateAcct() 方法的情况。现在如果调用 updateAcct() 方法后抛出异常，交易订单就会回滚，但帐户更新将会提交给数据库，如清单 12 所示：</p>
<p><br />
清单 12. 使用 REQUIRES_NEW 事务属性的多次更新</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(propagation=Propagation.REQUIRES_NEW)&nbsp;&nbsp; <br />
public long insertTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; em.persist(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp; updateAcct(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp; //exception occurs here! Trade rolled back but account update is not!&nbsp;&nbsp; <br />
&nbsp;&nbsp; ...&nbsp;&nbsp; <br />
}&nbsp; <br />
@Transactional(propagation=Propagation.REQUIRES_NEW)<br />
public long insertTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp; em.persist(trade);<br />
&nbsp;&nbsp; updateAcct(trade);<br />
&nbsp;&nbsp; //exception occurs here! Trade rolled back but account update is not!<br />
&nbsp;&nbsp; ...<br />
} </p>
<p>之所以会发生这种情况是因为 updateAcct() 方法中启动了一个新事务，所以在 updateAcct() 方法结束后，事务将被提交。使用 REQUIRES_NEW 事务属性时，如果存在现有事务上下文，当前的事务会被挂起并启动一个新事务。方法结束后，新的事务被提交，原来的事务继续执行。</p>
<p>由于这种行为，只有在被调用方法中的数据库操作需要保存到数据库中，而不管覆盖事务的结果如何时，才应该使用 REQUIRES_NEW 事务属性。比如，假设尝试的所有股票交易都必须被记录在一个审计数据库中。出于验证错误、资金不足或其他原因，不管交易是否失败，这条信息都需要被持久化。如果没有对审计方法使用 REQUIRES_NEW 属性，审计记录就会连同尝试执行的交易一起回滚。使用 REQUIRES_NEW 属性可以确保不管初始事务的结果如何，审计数据都会被保存。这里要注意的一点是，要始终使用 MANDATORY 或 REQUIRED 属性，而不是 REQUIRES_NEW，除非您有足够的理由来使用它，类似审计示例中的那些理由。</p>
<p>事务回滚陷阱</p>
<p>我将最常见的事务陷阱留到最后来讲。遗憾的是，我在生产代码中多次遇到这个错误。我首先从 Spring Framework 开始，然后介绍 EJB 3。</p>
<p>到目前为止，您研究的代码类似清单 13 所示：</p>
<p><br />
清单 13. 没有回滚支持</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(propagation=Propagation.REQUIRED)&nbsp;&nbsp; <br />
public TradeData placeTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; try {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertTrade(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateAcct(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade;&nbsp;&nbsp; <br />
&nbsp;&nbsp; } catch (Exception up) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log the error&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw up;&nbsp;&nbsp; <br />
&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
@Transactional(propagation=Propagation.REQUIRED)<br />
public TradeData placeTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertTrade(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateAcct(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade;<br />
&nbsp;&nbsp; } catch (Exception up) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log the error<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw up;<br />
&nbsp;&nbsp; }<br />
} </p>
<p>假设帐户中没有足够的资金来购买需要的股票，或者还没有准备购买或出售股票，并抛出了一个受控异常（例如 FundsNotAvailableException），那么交易订单会保存在数据库中吗？还是整个逻辑工作单元将执行回滚？答案出乎意料：根据受控异常（不管是在 Spring Framework 中还是在 EJB 中），事务会提交它还未提交的所有工作。使用清单 13，这意味着，如果在执行 updateAcct() 方法期间抛出受控异常，就会保存交易订单，但不会更新帐户来反映交易情况。</p>
<p>这可能是在使用事务时出现的主要数据完整性和一致性问题了。运行时异常（即非受控异常）自动强制执行整个逻辑工作单元的回滚，但受控异常不会。因此，清单 13 中的代码从事务角度来说毫无用处；尽管看上去它使用事务来维护原子性和一致性，但事实上并没有。</p>
<p>尽管这种行为看起来很奇怪，但这样做自有它的道理。首先，不是所有受控异常都是不好的；它们可用于事件通知或根据某些条件重定向处理。但更重要的是，应用程序代码会对某些类型的受控异常采取纠正操作，从而使事务全部完成。例如，考虑下面一种场景：您正在为在线书籍零售商编写代码。要完成图书的订单，您需要将电子邮件形式的确认函作为订单处理的一部分发送。如果电子邮件服务器关闭，您将发送某种形式的 SMTP 受控异常，表示邮件无法发送。如果受控异常引起自动回滚，整个图书订单就会由于电子邮件服务器的关闭全部回滚。通过禁止自动回滚受控异常，您可以捕获该异常并执行某种纠正操作（如向挂起队列发送消息），然后提交剩余的订单。</p>
<p>使用 Declarative 事务模式（本系列的第 2 部分将进行更加详细的描述）时，必须指定容器或框架应该如何处理受控异常。在 Spring Framework 中，通过 @Transactional 注释中的 rollbackFor 参数进行指定，如清单 14 所示：</p>
<p><br />
清单 14. 添加事务回滚支持 — Spring</p>
<p>view plaincopy to clipboardprint?<br />
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)&nbsp;&nbsp; <br />
public TradeData placeTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; try {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertTrade(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateAcct(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade;&nbsp;&nbsp; <br />
&nbsp;&nbsp; } catch (Exception up) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log the error&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw up;&nbsp;&nbsp; <br />
&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)<br />
public TradeData placeTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertTrade(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateAcct(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade;<br />
&nbsp;&nbsp; } catch (Exception up) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log the error<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw up;<br />
&nbsp;&nbsp; }<br />
} </p>
<p>注意，@Transactional 注释中使用了 rollbackFor 参数。这个参数接受一个单一异常类或一组异常类，您也可以使用 rollbackForClassName 参数将异常的名称指定为 Java String 类型。还可以使用此属性的相反形式（noRollbackFor）指定除某些异常以外的所有异常应该强制回滚。通常大多数开发人员指定 Exception.class 作为值，表示该方法中的所有异常应该强制回滚。</p>
<p>在回滚事务这一点上，EJB 的工作方式与 Spring Framework 稍微有点不同。EJB 3.0 规范中的 @TransactionAttribute 注释不包含指定回滚行为的指令。必须使用 SessionContext.setRollbackOnly() 方法将事务标记为执行回滚，如清单 15 所示：</p>
<p><br />
清单 15. 添加事务回滚支持 — EJB</p>
<p>view plaincopy to clipboardprint?<br />
@TransactionAttribute(TransactionAttributeType.REQUIRED)&nbsp;&nbsp; <br />
public TradeData placeTrade(TradeData trade) throws Exception {&nbsp;&nbsp; <br />
&nbsp;&nbsp; try {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertTrade(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateAcct(trade);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade;&nbsp;&nbsp; <br />
&nbsp;&nbsp; } catch (Exception up) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log the error&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sessionCtx.setRollbackOnly();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw up;&nbsp;&nbsp; <br />
&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
@TransactionAttribute(TransactionAttributeType.REQUIRED)<br />
public TradeData placeTrade(TradeData trade) throws Exception {<br />
&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertTrade(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateAcct(trade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return trade;<br />
&nbsp;&nbsp; } catch (Exception up) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log the error<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sessionCtx.setRollbackOnly();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw up;<br />
&nbsp;&nbsp; }<br />
} </p>
<p>调用 setRollbackOnly() 方法后，就不能改变主意了；惟一可能的结果是在启动事务的方法完成后回滚事务。本系列后续文章中描述的事务策略将介绍何时、何处使用回滚指令，以及何时使用 REQUIRED 与 MANDATORY 事务属性。</p>
<p>结束语</p>
<p>用于在 Java 平台中实现事务的代码不是太复杂；但是，如何使用以及如何配置它就有一些复杂了。在 Java 平台中实现事务支持有许多陷阱（包括一些我未在本文中讨论的、不是很常见的陷阱）。大多数陷阱最大的问题是，不会有任何编译器警告或运行时错误告诉您事务实现是不正确的。而且，与本文开头的 &#8220;迟做总比不做好&#8221; 部分的内容相反，实现事务支持不仅仅是一个编码工作。开发一个完整的事务策略涉及大量的设计工作。事务策略 系列的其余部分将指导您如何设计针对从简单应用程序到高性能事务处理用例的有效事务策略。</p>
<p>参考资料 </p>
<p>学习</p>
<p>您可以参阅本文在 developerWorks 全球网站上的 英文原文。 <br />
Straight Through Processing for Financial Service Firms （Hal McIntyre，Summit Group 出版社，2004）：了解在金融服务事务处理中，更多有关造成坏数据的原因及其成本的信息。 <br />
Java Transaction Design Strategies （Mark Richards，C4Media 出版，2006）：本书深入讨论了 Java 平台中的事务。 <br />
Java Transaction Processing （Mark Little，Prentice Hall，2004）：本书是另一本比较好的关于事务的参考书。 <br />
第 9 章. 事务管理：在 Spring Framework 2.5 文档的这部分中，可以找到更多有关 Spring 事务处理的信息。 <br />
Enterprise JavaBeans 3.0 资源站点：在此可以找到有关 EJB 3.0 规范的文档。 <br />
浏览 技术书店，查阅有关本文所述主题及其他技术主题的图书。 <br />
developerWorks Java 技术专区：提供了几百篇有关 Java 编程的各个方面的文章。 <br />
本文出处：http://www.ibm.com/developerworks/cn/java/j-ts1.html</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/334484.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-10-11 23:06 <a href="http://www.blogjava.net/freeman1984/archive/2010/10/11/334484.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>详解异常：struts使用中的StrutsPrepareAndExecuteFilter</title><link>http://www.blogjava.net/freeman1984/archive/2010/09/08/331413.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 08 Sep 2010 09:15:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/09/08/331413.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/331413.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/09/08/331413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/331413.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/331413.html</trackback:ping><description><![CDATA[在不使用spring。单独使用struts是报错：<br />
严重: Exception starting filter struts2<br />
java.lang.NullPointerException<br />
<span style="color: red">at com.opensymphony.xwork2.spring.SpringObjectFactory.getClassInstance</span>(SpringObjectFactory.java:190)<br />
。。。<br />
原因是多了一个struts2-spring-plugin-X.jar包,<br />
此包是struts的spring的插件：<br />
打开struts2-spring-plugin-X.jar看一下struts-plugin.xml内容：<br />
<p>&lt;struts&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
<strong>&nbsp;&nbsp;&nbsp; </strong><span style="color: red"><strong>&lt;!--&nbsp; Make the Spring object factory the automatic default --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;constant name="struts.objectFactory" value="spring" /&gt;</strong></span>&nbsp;&nbsp;&nbsp; <br />
&lt;package name="spring-default"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;interceptors&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/interceptors&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/package&gt;&nbsp;&nbsp;&nbsp; <br />
&lt;/struts&gt;</p>
请大家关注红色部分：<br />
&nbsp;<span style="color: red"><strong>&lt;!--&nbsp; Make the Spring object factory the automatic default --&gt;意思是：会将Spring object factory&nbsp;设置为默认。也就是说我们不配置struts.objectFactory=spring 但是只要这个包在classpath下就等于设置了struts.objectFactory=spring&nbsp;。<br />
</strong></span><br />
&nbsp;<br />
解决办法，去掉此包即可.<br />
 <img src ="http://www.blogjava.net/freeman1984/aggbug/331413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-09-08 17:15 <a href="http://www.blogjava.net/freeman1984/archive/2010/09/08/331413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring aop</title><link>http://www.blogjava.net/freeman1984/archive/2010/09/07/331350.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Tue, 07 Sep 2010 14:03:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/09/07/331350.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/331350.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/09/07/331350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/331350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/331350.html</trackback:ping><description><![CDATA[<h3 class="title pre fs1"><span class="tcnt">AOP的术语 </span></h3>
<p class="tdep clearfix nbw-act fc06" style="line-height: 20px">z</p>
<div class="bct fc05 fc11 nbw-blog ztag js-fs2">
<p><font color="#ff0000">切面（aspect）</font><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 切面是你要实现的交叉功能。<strong>就是通知和切入点的结合</strong>。通知和切入点共同定义了关于切面的全部内容：它的功能、在何时和何地完成功能。<br />
<br />
<font color="#ff0000">通知（Advice）</font><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通知定义了切面是什么以及何时使用。除了描述切面要完成的工作，通知还解决了何时执行这个工作的问题。应该在一个方法被调用之前？之后？或者抛出异常时。<br />
<br />
<font color="#ff0000">切入点（pointcut）</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果说通知定义了切面的"什么"和"何时"，<strong>那么切入点就定义了"何地</strong>"。</p>
<p><br />
<font color="#ff0000">连接点（joinpoint）</font><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 连接点是应用程序执行过程中能够插入切面的地点。这些点可以是方法被调用时、异常抛出时、甚至字段被编辑时。<br />
<br />
<font color="#ff0000">引入（Intrduction）</font><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 引入允许你为已经存在的类<strong>添加新方法和属性</strong>。比如一个Auditable通知类，记录对象在最后一次被修改时的状态。只需要一个setLastModified(Date)方法，和一个实例变量来保存这个状态。这个新方法和实例变量就可以被引入到现有的类，从而在不修改它们的情况下，让他们具有新的行为和状态。<br />
<br />
<font color="#ff0000">目标对象（Target）<br />
</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目标对象是被通知的对象。<br />
<br />
<font color="#ff0000">代理（Proxy）</font><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 代理是将通知应用到目标对后创建的对象。<br />
<br />
<font color="#ff0000">织入（weaving）</font><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 织入是将切面应用到目标对象从而创建一个新的代理对象的过程。 在目标对象的生命周期里有多个机会发生<font color="#000000">织入过程。比如编译时、类加载时、运行时。</font></p>
<p><br />
</p>
<p>&nbsp;</p>
<div>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-weight: bold; font-size: 16pt; color: rgb(0,0,255); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">通知、切点、通知者</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-weight: bold; font-size: 14pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">通知</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">在Spring&nbsp;AOP里有5中类型的通知，分别由一个接口进行定义</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<table style="border-collapse: collapse; mso-table-layout-alt: fixed">
    <tbody>
        <tr>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: rgb(0,0,0) 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0pt; border-left: rgb(0,0,0) 0.5pt solid; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">Before(<font face="宋体">前)</font></span></p>
            </td>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: rgb(0,0,0) 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0pt; border-left: medium none; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">org.springframework.aop.MethodBeforeAdvice</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0pt; border-left: rgb(0,0,0) 0.5pt solid; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">After-returning(<font face="宋体">返回后)</font></span></p>
            </td>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0pt; border-left: medium none; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">org.springframework.aop.AfterReturningAdvice</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0pt; border-left: rgb(0,0,0) 0.5pt solid; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">After-throwing(<font face="宋体">抛出后)</font></span></p>
            </td>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0pt; border-left: medium none; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">org.springframework.aop.ThrowsAdvice</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0pt; border-left: rgb(0,0,0) 0.5pt solid; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">Around(<font face="宋体">周围)</font></span></p>
            </td>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0pt; border-left: medium none; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">org.aopalliance.intercept.MethodInterceptor</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0pt; border-left: rgb(0,0,0) 0.5pt solid; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">Introduction(<font face="宋体">引入)</font></span></p>
            </td>
            <td style="border-right: rgb(0,0,0) 0.5pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0pt; border-left: medium none; width: 221.4pt; padding-top: 0pt; border-bottom: rgb(0,0,0) 0.5pt solid" valign="top" width="295">
            <p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">org.springframework.aop.IntroductionInterceptor</span></p>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">&lt;bean&nbsp;id="audienceAdvice"&nbsp;class="com.springidol.AudienceAdvice"&gt;&lt;/bean&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'">//AudienceAdvice<font face="宋体">类实现了3中不同的3中不同类型的AOP通知。</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">Public&nbsp;class&nbsp;AudienceAdvice&nbsp;implements&nbsp;</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice{</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">//<font face="宋体">前通知要求实现的方法</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">public&nbsp;void&nbsp;before(Method&nbsp;method,Object[]&nbsp;args,Object&nbsp;target)&nbsp;throws&nbsp;Throwable{</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><font face="宋体" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">}</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><font face="宋体" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">//<font face="宋体">返回后通知要求实现的方法，Object&nbsp;returnValue表示被调用方法的返回值</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">public&nbsp;void&nbsp;&nbsp;afterReturning(Object&nbsp;returnValue,Method&nbsp;method,Object[]&nbsp;args,Object&nbsp;target)&nbsp;throws&nbsp;Throwable{</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><font face="宋体" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">}</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><font face="宋体" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">//<font face="宋体">抛出后通知不需要实现任何方法，它只是一个标记接口，告诉spring相应的通知要求处理被抛出的异常，除最后一个参数外，其他参数都是可选的</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">public&nbsp;void&nbsp;afterThrowing(Method&nbsp;method,Object[]&nbsp;args,Object&nbsp;target,NullPointerException&nbsp;e)&nbsp;throws&nbsp;Throwable{</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><font face="宋体" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">//<font face="宋体">当发生NullPointerException&nbsp;时，记录日志</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">LOGGER.error("NPE&nbsp;thrown&nbsp;from&nbsp;"+method.getName());</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">}</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><font face="宋体" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">}</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">其中的</font></span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">Method&nbsp;method<font face="宋体">参数，表示要使用这个通知的方法，第二个参数Object[]&nbsp;args是方法被调用时要传递的参数。最后一个是方法调用的目标也就是被调用方法所在的对象。</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'">//<font face="宋体">周围通知相当于前通知、后通知、抛出后通知的结合。</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">Public&nbsp;class&nbsp;AudienceAdvice&nbsp;implements&nbsp;MethodInterceptor</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">{</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">Public&nbsp;Object&nbsp;invoke(MethodInvocation&nbsp;invocation)&nbsp;throws&nbsp;Throwable{</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">try{</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">..............................&nbsp;&nbsp;&nbsp;&nbsp;//<font face="宋体">在方法调用之前</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">Object&nbsp;returnValue=invocation.proceed();&nbsp;&nbsp;&nbsp;&nbsp;<font face="宋体">调用目标方法</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">.............................&nbsp;&nbsp;&nbsp;&nbsp;//<font face="宋体">在方法调用之后</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">}catch(PerformanceException&nbsp;e){</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 108pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">.............................&nbsp;&nbsp;&nbsp;&nbsp;/<font face="宋体">在出现异常之后</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 108pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">}</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 72pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">}</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">}</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-weight: bold; font-size: 14pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">切点</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: bold; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">1.</span><span style="font-weight: bold; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">正则切点</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><strong><br />
</strong></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">切点的作用主要在于选择需要使用通知的方法，比如下面的正则表达式切点：</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;bean&nbsp;id="performancePointcut"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.aop.support.JbkRegexpMethodPointcut"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;property&nbsp;name="pattern"&nbsp;value=".*perform"&nbsp;/&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;/bean&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><br />
</font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">Pattern<font face="宋体">属性用于制定方法匹配所使用的切点模板，本例中被设置为一个正则表达式，它应该匹配任何类里名为perform的方法。</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><br />
</font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">定义切点后，把切点与通知关联</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><br />
</font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;bean&nbsp;id="audienceAdvisor" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class="org.springframework.aop.support.DefaultPointcutAdvisor"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;property&nbsp;name="advice"&nbsp;value="</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">audienceAdvice</span><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">"&nbsp;/&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;property&nbsp;name="pointcut"&nbsp;value="performancePointcut"&nbsp;/&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;/bean&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><br />
</font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">DefaultPointcutAdvisor<font face="宋体">是一个通知者类，它只是把</font></span><span style="font-weight: normal; font-size: 10.5pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">通知关联到一个切点</font></span><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">。</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><br />
</font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">也可以使用RegexpMethodPointcutAdvisor是一个特殊的通知者类，可以在一个Bean里面定义切点和通知者</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;bean&nbsp;id="audienceAdvisor" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;property&nbsp;name="advice"&nbsp;value="</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">audienceAdvice</span><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">"&nbsp;/&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;property&nbsp;name="pattern"&nbsp;value=".*perform"&nbsp;/&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;/bean&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><br />
</font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: bold; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">2.<font face="宋体">定义AspectJ切点</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><strong><br />
</strong></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">正则表达式虽然可以作为切点定义语言来使用，但是它并不是针对切点而创建的，其主要用途还是文本解析。AspectJ里定义切点的方法就可以看出AspectJ的切点语言是一种真正的切点表达式语言。</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><br />
</font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;bean&nbsp;id="performancePointcut" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class="org.springframework.aop.aspectj.AspectJExpressionPointcut"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;property&nbsp;name="expression"&nbsp;value="execution(*&nbsp;Performer+.perform(..))"&nbsp;/&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;/bean&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><font face="宋体"><br />
</font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">可以使用DefaultPointcutAdvisor把它和通知关联起来，就像前面一样。同样，也可以设置一个特殊的通知者</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;bean&nbsp;id="audienceAdvisor" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;property&nbsp;name="advice"&nbsp;value="</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">audienceAdvice</span><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">"&nbsp;/&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;property&nbsp;name="expression"&nbsp;value="execution(*&nbsp;*.perform(..))"&nbsp;/&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 36pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">&lt;/bean&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">execution<font face="宋体">（</font></span><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,255); font-family: '宋体'; mso-spacerun: 'yes'">*&nbsp;*</span><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">.perform(..))&nbsp;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-weight: normal; font-size: 10.5pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'">execution<font face="宋体">表示执行方法时，*&nbsp;*表示任意返回类型，.perform表示perform方法，(..)表示任意参数设置</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><font face="宋体" color="#0000ff" size="6"><span style="font-size: 21px; line-height: 33px"><strong><br />
</strong></span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-weight: bold; font-size: 16pt; color: rgb(0,0,255); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">使用ProxyFactoryBean</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><font face="宋体" color="#0000ff" size="6"><span style="font-size: 21px; line-height: 33px"><strong><br />
</strong></span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&lt;bean&nbsp;id="</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'">duke</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">"</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.aop.framework.ProxyFactoryBean"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&lt;property&nbsp;name="proxyInterfaces"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;genericdaotest.dao.PersonDao&lt;/value&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="target"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean&nbsp;parent="abstractDaoTarget"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;constructor-arg&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;genericdaotest.domain.Person&lt;/value&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/constructor-arg&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'"> </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&lt;property&nbsp;name="interceptorNames"&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'"> </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&lt;list&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'"> </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;</span><span style="font-weight: normal; font-size: 10.5pt; color: rgb(0,0,0); font-family: '宋体'; mso-spacerun: 'yes'">audienceAdvisor</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&lt;/value&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'"> </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&lt;/list&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'"> </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;&lt;/property&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&nbsp;</span><span style="font-size: 10pt; font-family: '宋体'; mso-spacerun: 'yes'"> </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-spacerun: 'yes'">&lt;/bean&gt;</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><font face="'Courier New'" size="3"><span style="font-size: 13px; line-height: 20px"><br />
</span></font></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'">S</span><span style="font-size: 10pt; color: rgb(255,0,0); font-family: 'Courier New'; mso-spacerun: 'yes'">pring里面的ProxyFactoryBean是个工厂Bean，用于生成一个代理，把一个或者多个拦截者(和通知者)应用到Bean，有target、interceptorNames、proxyInterfaces三个属性，后两个都是数组属性target表示要代理的对象</span><span style="font-size: 10pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">。</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; color: rgb(255,0,0); font-family: 'Courier New'; mso-spacerun: 'yes'">interceptorNames属性告诉ProxyFactoryBean哪个通知者要应用于被代理的</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; color: rgb(255,0,0); font-family: 'Courier New'; mso-spacerun: 'yes'">beanproxyInterfaces告诉ProxyFactoryBean代理应该实现哪个接口</span><span style="font-size: 10pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">。本例中代理的是</font></span><span style="font-size: 10pt; color: rgb(255,0,0); font-family: 'Courier New'; mso-spacerun: 'yes'">genericdaotest.dao.PersonDao</span><span style="font-size: 10pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">接口</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><span style="font-size: 10pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'">target<font face="宋体">告诉</font></span><span style="font-size: 10pt; color: rgb(255,0,0); font-family: 'Courier New'; mso-spacerun: 'yes'">ProxyFactoryBean</span><span style="font-size: 10pt; color: rgb(255,0,0); font-family: '宋体'; mso-spacerun: 'yes'"><font face="宋体">，哪个Bean是代理。</font></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"><br />
<br />
----------------以上转载自：http://bhsc.happy.blog.163.com/blog/static/1043895522008111144158773/<br />
<br />
<br />
</p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 36pt"></p>
</div>
</div>
<img src ="http://www.blogjava.net/freeman1984/aggbug/331350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-09-07 22:03 <a href="http://www.blogjava.net/freeman1984/archive/2010/09/07/331350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>注意spring, singleton不single！ ？</title><link>http://www.blogjava.net/freeman1984/archive/2010/08/30/330214.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Sun, 29 Aug 2010 16:41:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/08/30/330214.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/330214.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/08/30/330214.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/330214.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/330214.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;spring的singleton真的会在整个应用中创建单一的对象吗？非也，他只会在内部springframework的一个applicationContext上下文中保持单利，但是如果有两个applicationContext呢？<br />
<br />
&nbsp;首先看以下实例 ：<br />
&nbsp;&nbsp; <br />
&nbsp;首先定义一个bean 并注册为单利，非懒加载对象：<br />
&nbsp;
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.joe.service;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img id="Codehighlighter1_52_130_Open_Image" onclick="this.style.display='none'; Codehighlighter1_52_130_Open_Text.style.display='none'; Codehighlighter1_52_130_Closed_Image.style.display='inline'; Codehighlighter1_52_130_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_52_130_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_52_130_Closed_Text.style.display='none'; Codehighlighter1_52_130_Open_Image.style.display='inline'; Codehighlighter1_52_130_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;TestService&nbsp;</span><span id="Codehighlighter1_52_130_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_52_130_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_76_128_Open_Image" onclick="this.style.display='none'; Codehighlighter1_76_128_Open_Text.style.display='none'; Codehighlighter1_76_128_Closed_Image.style.display='inline'; Codehighlighter1_76_128_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_76_128_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_76_128_Closed_Text.style.display='none'; Codehighlighter1_76_128_Open_Image.style.display='inline'; Codehighlighter1_76_128_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;TestService()</span><span id="Codehighlighter1_76_128_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_76_128_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">create&nbsp;&nbsp;TestService&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
<br />
配置：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">testservice</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">com.joe.service.TestService</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;scope</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">singleton</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;lazy</span><span style="color: #000000">-</span><span style="color: #000000">init</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">false</span><span style="color: #000000">"</span><span style="color: #000000">&gt;&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span></div>
<br />
测试代码：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;ApplicationContext&nbsp;context1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;ApplicationContext&nbsp;context2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ClassPathXmlApplicationContext(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;String[]{</span><span style="color: #000000">"</span><span style="color: #000000">classpath:spring-bean_*.xml</span><span style="color: #000000">"</span><span style="color: #000000">});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ClassPathXmlApplicationContext(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;String[]{</span><span style="color: #000000">"</span><span style="color: #000000">classpath:spring-bean_*.xml</span><span style="color: #000000">"</span><span style="color: #000000">});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;SQLException,&nbsp;IOException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">context1&nbsp;中&nbsp;testservice&nbsp;是否单利？</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">context1.isSingleton(</span><span style="color: #000000">"</span><span style="color: #000000">testservice</span><span style="color: #000000">"</span><span style="color: #000000">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestService&nbsp;service&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(TestService)&nbsp;context1.getBean(</span><span style="color: #000000">"</span><span style="color: #000000">testservice</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(service);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">context2&nbsp;&nbsp;中&nbsp;testservice&nbsp;是否单利？</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">context2.isSingleton(</span><span style="color: #000000">"</span><span style="color: #000000">testservice</span><span style="color: #000000">"</span><span style="color: #000000">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestService&nbsp;service2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(TestService)&nbsp;context2.getBean(</span><span style="color: #000000">"</span><span style="color: #000000">testservice</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(service2);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(service);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">context1&nbsp;中&nbsp;testservice&nbsp;是否和context2&nbsp;中&nbsp;testservice&nbsp;是一个对象？</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">(service</span><span style="color: #000000">==</span><span style="color: #000000">service2));</span><span style="color: #008000">//</span><span style="color: #008000">关键地方&nbsp;两个ApplicationContext&nbsp;中拿&nbsp;到的是否是一个对象？</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span></div>
<br />
结果：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">create&nbsp;&nbsp;TestService&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />create&nbsp;&nbsp;TestService&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />context1&nbsp;中&nbsp;testservice&nbsp;是否单利？</span><span style="color: #0000ff">true</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />com.joe.service.TestService@54c4ad<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />context2&nbsp;&nbsp;中&nbsp;testservice&nbsp;是否单利？</span><span style="color: #0000ff">true</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />com.joe.service.TestService@13c7378<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />com.joe.service.TestService@54c4ad<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />context1&nbsp;中&nbsp;testservice&nbsp;是否和context2&nbsp;中&nbsp;testservice&nbsp;是一个对象？</span><span style="color: #0000ff">false</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
<br />
&nbsp;很明显在一个jvm应用中出现两个被标注为单利的实例。<br />
&nbsp;&nbsp;&nbsp; spring内部通过上下文中的集合来管理对象，核心为beanFactory，而非通过asm等来动态改变类结构来控制类的scope。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; 我们跟着源码来看看：<br />
&nbsp; 在调用new ClassPathXmlApplicationContext实际上调用了<br />
&nbsp; this(configLocations, true, null);其中的true代表要刷新上下文：而最终的refresh是这样的<br />
&nbsp;
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_22_68_Open_Image" onclick="this.style.display='none'; Codehighlighter1_22_68_Open_Text.style.display='none'; Codehighlighter1_22_68_Closed_Image.style.display='inline'; Codehighlighter1_22_68_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_22_68_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_22_68_Closed_Text.style.display='none'; Codehighlighter1_22_68_Open_Image.style.display='inline'; Codehighlighter1_22_68_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(hasBeanFactory())&nbsp;</span><span id="Codehighlighter1_22_68_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_22_68_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destroyBeans();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closeBeanFactory();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
但是很费解的是hasBeanFactory的判断：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_41_129_Open_Image" onclick="this.style.display='none'; Codehighlighter1_41_129_Open_Text.style.display='none'; Codehighlighter1_41_129_Closed_Image.style.display='inline'; Codehighlighter1_41_129_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_41_129_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_41_129_Closed_Text.style.display='none'; Codehighlighter1_41_129_Open_Image.style.display='inline'; Codehighlighter1_41_129_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">boolean</span><span style="color: #000000">&nbsp;hasBeanFactory()&nbsp;</span><span id="Codehighlighter1_41_129_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_41_129_Open_Text"><span style="color: #000000">{<br />
<img id="Codehighlighter1_84_126_Open_Image" onclick="this.style.display='none'; Codehighlighter1_84_126_Open_Text.style.display='none'; Codehighlighter1_84_126_Closed_Image.style.display='inline'; Codehighlighter1_84_126_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_84_126_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_84_126_Closed_Text.style.display='none'; Codehighlighter1_84_126_Open_Image.style.display='inline'; Codehighlighter1_84_126_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">synchronized</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">this</span><span style="color: #000000">.beanFactoryMonitor)&nbsp;</span><span id="Codehighlighter1_84_126_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_84_126_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">this</span><span style="color: #000000">.beanFactory&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
其中的this.beanFactory是ClassPathXmlApplicationContext的实例的属性private DefaultListableBeanFactory beanFactory;<br />
&nbsp; 不用说this.beanFactory==null因为我们new了一个ClassPathXmlApplicationContext&nbsp;，&nbsp;beanFactory也没有初始化操作，也没有parentContext （因为我根本不知道有没有parentContext）而beanFactory也不是static的。<br />
&nbsp; 也就是说在第二次new&nbsp; ClassPathXmlApplicationContext的时候并不会refresh beanFactory 当然就会有两个单利的实例。<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: red">此问题在项目中出现，当时由于一个同事在自己的一个类里面的static区域new了ClassPathXmlApplicationContext用来测试忘记删掉， 而我们的所有类又是通过web容器来加载，结果就导致项目中出现单利对象出现两个的问题，结果害的那个苦啊！<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp; 希望大家在实际项目中注意到，也希望大家跟帖讨论下，我分析的是否正确，大家实际项目中有没有解决方案来避免这样的问题！</span>
<img src ="http://www.blogjava.net/freeman1984/aggbug/330214.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-08-30 00:41 <a href="http://www.blogjava.net/freeman1984/archive/2010/08/30/330214.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于@Transactional和配置文件混用的问题</title><link>http://www.blogjava.net/freeman1984/archive/2010/08/18/329225.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 18 Aug 2010 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/08/18/329225.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/329225.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/08/18/329225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/329225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/329225.html</trackback:ping><description><![CDATA[使用顺序：<br />
1&nbsp;&nbsp; &lt;tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /&gt;<br />
<br />
之后才是xml配置：<br />
&nbsp;2&nbsp; &lt;tx:advice id="txAdviceService" transaction-manager="transactionManager"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tx:attributes&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tx:method name="add*" read-only="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tx:method name="add*" read-only="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tx:method name="update*" read-only="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tx:method name="del*" read-only="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tx:method name="apply*" read-only="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tx:method name="*" read-only="true"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/tx:attributes&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/tx:advice&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;aop:config&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;aop:pointcut id="serviceMethods"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expression="execution(* com.joe.service.*.*(..))"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;aop:advisor advice-ref="txAdviceService" pointcut-ref="serviceMethods"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/aop:config&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="transactionManager"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="sessionFactory" ref="sessionFactory"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
如果写反会出现如果使用的<br />
@Transactional的方法在&nbsp; &lt;tx:method name="*" read-only="true"/&gt;<br />
里面 就会发现没有可写事务 ：<br />
error:Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.<br />
<img src ="http://www.blogjava.net/freeman1984/aggbug/329225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-08-18 15:56 <a href="http://www.blogjava.net/freeman1984/archive/2010/08/18/329225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Spring 2.5 注释驱动的 IoC 功能  </title><link>http://www.blogjava.net/freeman1984/archive/2010/08/18/329211.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 18 Aug 2010 06:00:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/08/18/329211.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/329211.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/08/18/329211.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/329211.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/329211.html</trackback:ping><description><![CDATA[<p>&nbsp;转载自：http://www.ibm.com/developerworks/cn/java/j-lo-spring25-ioc/?ca=drs-tp0808</p>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr valign="top">
            <td width="100%">
            <h1>使用 Spring 2.5 注释驱动的 IoC 功能</h1>
            <img class="display-img" alt="" src="//www.ibm.com/i/c.gif" width="1" height="6" /></td>
            <td class="no-print" width="192"></td>
        </tr>
    </tbody>
</table>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr valign="top">
            <td width="10"><img alt="" src="//www.ibm.com/i/c.gif" width="10" height="1" /></td>
            <td width="100%">
            <p>基于注释（Annotation）的配置有越来越流行的趋势，Spring 2.5 顺应这种趋势，提供了完全基于注释配置 Bean、装配 Bean 的功能，您可以使用基于注释的 Spring IoC 替换原来基于 XML 的配置。本文通过实例详细讲述了 Spring 2.5 基于注释 IoC 功能的使用。</p>
            <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p><a name="N1004A"><span class="atitle">概述</span></a></p>
            <p>注释配置相对于 XML 配置具有很多的优势：</p>
            <ul>
                <li>它可以充分利用 Java 的反射机制获取类结构信息，这些信息可以有效减少配置的工作。如使用 JPA 注释配置 ORM 映射时，我们就不需要指定 PO 的属性名、类型等信息，如果关系表字段和 PO 属性名、类型都一致，您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取。
                <li>注释和 Java 代码位于一个文件中，而 XML 配置采用独立的配置文件，大多数配置信息在程序开发完成后都不会调整，如果配置信息和 Java 代码放在一起，有助于增强程序的内聚性。而采用独立的 XML 配置文件，程序员在编写一个功能时，往往需要在程序文件和配置文件中不停切换，这种思维上的不连贯会降低开发效率。 </li>
            </ul>
            <p>因此在很多情况下，注释配置比 XML 配置更受欢迎，注释配置有进一步流行的趋势。Spring 2.5 的一大增强就是引入了很多注释类，现在您已经可以使用注释配置完成大部分 XML 配置的功能。在这篇文章里，我们将向您讲述使用注释进行 Bean 定义和依赖注入的内容。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10060"><span class="atitle">原来我们是怎么做的</span></a></p>
            <p>在使用注释配置之前，先来回顾一下传统上是如何配置 Bean 并完成 Bean 之间依赖关系的建立。下面是 3 个类，它们分别是 Office、Car 和 Boss，这 3 个类需要在 Spring 容器中配置为 Bean：</p>
            <p>Office 仅有一个属性：</p>
            <br />
            <a name="N1006E"><strong>清单 1. Office.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        public class Office {
                        private String officeNo =&#8221;001&#8221;;
                        //省略 get/setter
                        @Override
                        public String toString() {
                        return "officeNo:" + officeNo;
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>Car 拥有两个属性：</p>
            <br />
            <a name="N1007A"><strong>清单 2. Car.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        public class Car {
                        private String brand;
                        private double price;
                        // 省略 get/setter
                        @Override
                        public String toString() {
                        return "brand:" + brand + "," + "price:" + price;
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>Boss 拥有 Office 和 Car 类型的两个属性：</p>
            <br />
            <a name="N10086"><strong>清单 3. Boss.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        public class Boss {
                        private Car car;
                        private Office office;
                        // 省略 get/setter
                        @Override
                        public String toString() {
                        return "car:" + car + "\n" + "office:" + office;
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>我们在 Spring 容器中将 Office 和 Car 声明为 Bean，并注入到 Boss Bean 中：下面是使用传统 XML 完成这个工作的配置文件 beans.xml：</p>
            <br />
            <a name="N10092"><strong>清单 4. beans.xml 将以上三个类配置成 Bean</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        &lt;?xml version="1.0" encoding="UTF-8" ?&gt;
                        &lt;beans xmlns="http://www.springframework.org/schema/beans"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt;
                        &lt;bean id="boss" class="com.baobaotao.Boss"&gt;
                        &lt;property name="car" ref="car"/&gt;
                        &lt;property name="office" ref="office" /&gt;
                        &lt;/bean&gt;
                        &lt;bean id="office" class="com.baobaotao.Office"&gt;
                        &lt;property name="officeNo" value="002"/&gt;
                        &lt;/bean&gt;
                        &lt;bean id="car" class="com.baobaotao.Car" scope="singleton"&gt;
                        &lt;property name="brand" value=" 红旗 CA72"/&gt;
                        &lt;property name="price" value="2000"/&gt;
                        &lt;/bean&gt;
                        &lt;/beans&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>当我们运行以下代码时，控制台将正确打出 boss 的信息：</p>
            <br />
            <a name="N1009E"><strong>清单 5. 测试类：AnnoIoCTest.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        import org.springframework.context.ApplicationContext;
                        import org.springframework.context.support.ClassPathXmlApplicationContext;
                        public class AnnoIoCTest {
                        public static void main(String[] args) {
                        String[] locations = {"beans.xml"};
                        ApplicationContext ctx =
                        new ClassPathXmlApplicationContext(locations);
                        Boss boss = (Boss) ctx.getBean("boss");
                        System.out.println(boss);
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>这说明 Spring 容器已经正确完成了 Bean 创建和装配的工作。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img alt="" src="//www.ibm.com/i/c.gif" width="100%" height="4" /><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N100A7"><span class="atitle">使用 @Autowired 注释</span></a></p>
            <p>Spring 2.5 引入了 <code>@Autowired</code> 注释，它可以对类成员变量、方法及构造函数进行标注，完成自动装配的工作。来看一下使用 <code>@Autowired</code> 进行成员变量自动注入的代码：</p>
            <br />
            <a name="N100BA"><strong>清单 6. 使用 @Autowired 注释的 Boss.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import org.springframework.beans.factory.annotation.Autowired;
                        public class Boss {
                        @Autowired
                        private Car car;
                        @Autowired
                        private Office office;
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>Spring 通过一个 <code>BeanPostProcessor</code> 对 <code>@Autowired</code> 进行解析，所以要让 <code>@Autowired</code> 起作用必须事先在 Spring 容器中声明 <code>AutowiredAnnotationBeanPostProcessor</code> Bean。</p>
            <br />
            <a name="N100D6"><strong>清单 7. 让 @Autowired 注释工作起来</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        &lt;?xml version="1.0" encoding="UTF-8" ?&gt;
                        &lt;beans xmlns="http://www.springframework.org/schema/beans"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt;
                        &lt;!-- 该 BeanPostProcessor 将自动起作用，对标注 @Autowired 的 Bean 进行自动注入 --&gt;
                        &lt;bean class="org.springframework.beans.factory.annotation.
                        AutowiredAnnotationBeanPostProcessor"/&gt;
                        &lt;!-- 移除 boss Bean 的属性注入配置的信息 --&gt;
                        &lt;bean id="boss" class="com.baobaotao.Boss"/&gt;
                        &lt;bean id="office" class="com.baobaotao.Office"&gt;
                        &lt;property name="officeNo" value="001"/&gt;
                        &lt;/bean&gt;
                        &lt;bean id="car" class="com.baobaotao.Car" scope="singleton"&gt;
                        &lt;property name="brand" value=" 红旗 CA72"/&gt;
                        &lt;property name="price" value="2000"/&gt;
                        &lt;/bean&gt;
                        &lt;/beans&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>这样，当 Spring 容器启动时，<code>AutowiredAnnotationBeanPostProcessor</code> 将扫描 Spring 容器中所有 Bean，当发现 Bean 中拥有 <code>@Autowired</code> 注释时就找到和其匹配（默认按类型匹配）的 Bean，并注入到对应的地方中去。</p>
            <p>按照上面的配置，Spring 将直接采用 Java 反射机制对 Boss 中的 <code>car</code> 和 <code>office</code> 这两个私有成员变量进行自动注入。所以对成员变量使用 <code>@Autowired</code> 后，您大可将它们的 setter 方法（<code>setCar()</code> 和 <code>setOffice()</code>）从 Boss 中删除。</p>
            <p>当然，您也可以通过 <code>@Autowired</code> 对方法或构造函数进行标注，来看下面的代码：</p>
            <br />
            <a name="N10108"><strong>清单 8. 将 @Autowired 注释标注在 Setter 方法上</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        public class Boss {
                        private Car car;
                        private Office office;
                        @Autowired
                        public void setCar(Car car) {
                        this.car = car;
                        }
                        @Autowired
                        public void setOffice(Office office) {
                        this.office = office;
                        }
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>这时，<code>@Autowired</code> 将查找被标注的方法的入参类型的 Bean，并调用方法自动注入这些 Bean。而下面的使用方法则对构造函数进行标注：</p>
            <br />
            <a name="N10118"><strong>清单 9. 将 @Autowired 注释标注在构造函数上</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        public class Boss {
                        private Car car;
                        private Office office;
                        @Autowired
                        public Boss(Car car ,Office office){
                        this.car = car;
                        this.office = office ;
                        }
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>由于 <code>Boss()</code> 构造函数有两个入参，分别是 <code>car</code> 和 <code>office</code>，<code>@Autowired</code> 将分别寻找和它们类型匹配的 Bean，将它们作为 <code>Boss(Car car ,Office office)</code> 的入参来创建 <code>Boss</code> Bean。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img alt="" src="//www.ibm.com/i/c.gif" width="100%" height="4" /><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10139"><span class="atitle">当候选 Bean 数目不为 1 时的应对方法</span></a></p>
            <p>在默认情况下使用 <code>@Autowired</code> 注释进行自动注入时，Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时，Spring 容器将抛出 <code>BeanCreationException</code> 异常，并指出必须至少拥有一个匹配的 Bean。我们可以来做一个实验：</p>
            <br />
            <a name="N1014C"><strong>清单 10. 候选 Bean 数目为 0 时</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        &lt;?xml version="1.0" encoding="UTF-8" ?&gt;
                        &lt;beans xmlns="http://www.springframework.org/schema/beans"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "&gt;
                        &lt;bean class="org.springframework.beans.factory.annotation.
                        AutowiredAnnotationBeanPostProcessor"/&gt;
                        &lt;bean id="boss" class="com.baobaotao.Boss"/&gt;
                        &lt;!-- 将 office Bean 注释掉 --&gt;
                        &lt;!-- &lt;bean id="office" class="com.baobaotao.Office"&gt;
                        &lt;property name="officeNo" value="001"/&gt;
                        &lt;/bean&gt;--&gt;
                        &lt;bean id="car" class="com.baobaotao.Car" scope="singleton"&gt;
                        &lt;property name="brand" value=" 红旗 CA72"/&gt;
                        &lt;property name="price" value="2000"/&gt;
                        &lt;/bean&gt;
                        &lt;/beans&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>由于 <code>office</code> Bean 被注释掉了，所以 Spring 容器中将没有类型为 <code>Office</code> 的 Bean 了，而 Boss 的 <code>office</code> 属性标注了 <code>@Autowired</code>，当启动 Spring 容器时，异常就产生了。</p>
            <p>当不能确定 Spring 容器中一定拥有某个类的 Bean 时，可以在需要自动注入该类 Bean 的地方可以使用 <code>@Autowired(required = false)</code>，这等于告诉 Spring：在找不到匹配 Bean 时也不报错。来看一下具体的例子：</p>
            <br />
            <a name="N1016F"><strong>清单 11. 使用 @Autowired(required = false)</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import org.springframework.beans.factory.annotation.Autowired;
                        import org.springframework.beans.factory.annotation.Required;
                        public class Boss {
                        private Car car;
                        private Office office;
                        @Autowired
                        public void setCar(Car car) {
                        this.car = car;
                        }
                        @Autowired(required = false)
                        public void setOffice(Office office) {
                        this.office = office;
                        }
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>当然，一般情况下，使用 <code>@Autowired</code> 的地方都是需要注入 Bean 的，使用了自动注入而又允许不注入的情况一般仅会在开发期或测试期碰到（如为了快速启动 Spring 容器，仅引入一些模块的 Spring 配置文件），所以 <code>@Autowired(required = false)</code> 会很少用到。</p>
            <p>和找不到一个类型匹配 Bean 相反的一个错误是：如果 Spring 容器中拥有多个候选 Bean，Spring 容器在启动时也会抛出 <code>BeanCreationException</code> 异常。来看下面的例子：</p>
            <br />
            <a name="N1018A"><strong>清单 12. 在 beans.xml 中配置两个 Office 类型的 Bean</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        &#8230;
                        &lt;bean id="office" class="com.baobaotao.Office"&gt;
                        &lt;property name="officeNo" value="001"/&gt;
                        &lt;/bean&gt;
                        &lt;bean id="office2" class="com.baobaotao.Office"&gt;
                        &lt;property name="officeNo" value="001"/&gt;
                        &lt;/bean&gt;
                        &#8230;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>我们在 Spring 容器中配置了两个类型为 <code>Office</code> 类型的 Bean，当对 Boss 的 <code>office</code> 成员变量进行自动注入时，Spring 容器将无法确定到底要用哪一个 Bean，因此异常发生了。</p>
            <p>Spring 允许我们通过 <code>@Qualifier</code> 注释指定注入 Bean 的名称，这样歧义就消除了，可以通过下面的方法解决异常：</p>
            <br />
            <a name="N101A5"><strong>清单 13. 使用 @Qualifier 注释指定注入 Bean 的名称</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        @Autowired
                        public void setOffice(@Qualifier("office")Office office) {
                        this.office = office;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p><code>@Qualifier("office")</code> 中的 <code>office</code> 是 Bean 的名称，所以 <code>@Autowired</code> 和 <code>@Qualifier</code> 结合使用时，自动注入的策略就从 byType 转变成 byName 了。<code>@Autowired</code> 可以对成员变量、方法以及构造函数进行注释，而 <code>@Qualifier</code> 的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同，所以 Spring 不将 <code>@Autowired</code> 和 <code>@Qualifier</code> 统一成一个注释类。下面是对成员变量和构造函数入参进行注释的代码：</p>
            <p>对成员变量进行注释：</p>
            <br />
            <a name="N101D4"><strong>清单 14. 对成员变量使用 @Qualifier 注释</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        public class Boss {
                        @Autowired
                        private Car car;
                        @Autowired
                        @Qualifier("office")
                        private Office office;
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>对构造函数入参进行注释：</p>
            <br />
            <a name="N101E0"><strong>清单 15. 对构造函数变量使用 @Qualifier 注释</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        public class Boss {
                        private Car car;
                        private Office office;
                        @Autowired
                        public Boss(Car car , @Qualifier("office")Office office){
                        this.car = car;
                        this.office = office ;
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p><code>@Qualifier</code> 只能和 <code>@Autowired</code> 结合使用，是对 <code>@Autowired</code> 有益的补充。一般来讲，<code>@Qualifier</code> 对方法签名中入参进行注释会降低代码的可读性，而对成员变量注释则相对好一些。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img alt="" src="//www.ibm.com/i/c.gif" width="100%" height="4" /><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N101F9"><span class="atitle">使用 JSR-250 的注释</span></a></p>
            <p>Spring 不但支持自己定义的 <code>@Autowired</code> 的注释，还支持几个由 JSR-250 规范定义的注释，它们分别是 <code>@Resource</code>、<code>@PostConstruct</code> 以及 <code>@PreDestroy</code>。</p>
            <p><a name="N10211"><span class="smalltitle">@Resource</span></a></p>
            <p><code>@Resource</code> 的作用相当于 <code>@Autowired</code>，只不过 <code>@Autowired</code> 按 byType 自动注入，面 <code>@Resource</code> 默认按 byName 自动注入罢了。<code>@Resource</code> 有两个属性是比较重要的，分别是 name 和 type，Spring 将 <code>@Resource</code> 注释的 name 属性解析为 Bean 的名字，而 type 属性则解析为 Bean 的类型。所以如果使用 name 属性，则使用 byName 的自动注入策略，而使用 type 属性时则使用 byType 自动注入策略。如果既不指定 name 也不指定 type 属性，这时将通过反射机制使用 byName 自动注入策略。</p>
            <p>Resource 注释类位于 Spring 发布包的 lib/j2ee/common-annotations.jar 类包中，因此在使用之前必须将其加入到项目的类库中。来看一个使用 <code>@Resource</code> 的例子：</p>
            <br />
            <a name="N1023B"><strong>清单 16. 使用 @Resource 注释的 Boss.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import javax.annotation.Resource;
                        public class Boss {
                        // 自动注入类型为 Car 的 Bean
                        @Resource
                        private Car car;
                        // 自动注入 bean 名称为 office 的 Bean
                        @Resource(name = "office")
                        private Office office;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>一般情况下，我们无需使用类似于 <code>@Resource(type=Car.class)</code> 的注释方式，因为 Bean 的类型信息可以通过 Java 反射从代码中获取。</p>
            <p>要让 JSR-250 的注释生效，除了在 Bean 类中标注这些注释外，还需要在 Spring 容器中注册一个负责处理这些注释的 <code>BeanPostProcessor</code>：</p>
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;bean
                        class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p><code>CommonAnnotationBeanPostProcessor</code> 实现了 <code>BeanPostProcessor</code> 接口，它负责扫描使用了 JSR-250 注释的 Bean，并对它们进行相应的操作。</p>
            <p><a name="N1025E"><span class="smalltitle">@PostConstruct 和 @PreDestroy</span></a></p>
            <p>Spring 容器中的 Bean 是有生命周期的，Spring 允许在 Bean 在初始化完成后以及 Bean 销毁前执行特定的操作，您既可以通过实现 InitializingBean/DisposableBean 接口来定制初始化之后 / 销毁之前的操作方法，也可以通过 &lt;bean&gt; 元素的 init-method/destroy-method 属性指定初始化之后 / 销毁之前调用的操作方法。关于 Spring 的生命周期，笔者在《精通 Spring 2.x—企业应用开发精解》第 3 章进行了详细的描述，有兴趣的读者可以查阅。</p>
            <p>JSR-250 为初始化之后/销毁之前方法的指定定义了两个注释类，分别是 @PostConstruct 和 @PreDestroy，这两个注释只能应用于方法上。标注了 @PostConstruct 注释的方法将在类实例化后调用，而标注了 @PreDestroy 的方法将在类销毁之前调用。</p>
            <br />
            <a name="N1026C"><strong>清单 17. 使用 @PostConstruct 和 @PreDestroy 注释的 Boss.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import javax.annotation.Resource;
                        import javax.annotation.PostConstruct;
                        import javax.annotation.PreDestroy;
                        public class Boss {
                        @Resource
                        private Car car;
                        @Resource(name = "office")
                        private Office office;
                        @PostConstruct
                        public void postConstruct1(){
                        System.out.println("postConstruct1");
                        }
                        @PreDestroy
                        public void preDestroy1(){
                        System.out.println("preDestroy1");
                        }
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>您只需要在方法前标注 <code>@PostConstruct</code> 或 <code>@PreDestroy</code>，这些方法就会在 Bean 初始化后或销毁之前被 Spring 容器执行了。</p>
            <p>我们知道，不管是通过实现 <code>InitializingBean</code>/<code>DisposableBean</code> 接口，还是通过 &lt;bean&gt; 元素的 <code>init-method/destroy-method</code> 属性进行配置，都只能为 Bean 指定一个初始化 / 销毁的方法。但是使用 <code>@PostConstruct</code> 和 <code>@PreDestroy</code> 注释却可以指定多个初始化 / 销毁方法，那些被标注 <code>@PostConstruct</code> 或 <code>@PreDestroy</code> 注释的方法都会在初始化 / 销毁时被执行。</p>
            <p>通过以下的测试代码，您将可以看到 Bean 的初始化 / 销毁方法是如何被执行的：</p>
            <br />
            <a name="N102A2"><strong>清单 18. 测试类代码</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import org.springframework.context.support.ClassPathXmlApplicationContext;
                        public class AnnoIoCTest {
                        public static void main(String[] args) {
                        String[] locations = {"beans.xml"};
                        ClassPathXmlApplicationContext ctx =
                        new ClassPathXmlApplicationContext(locations);
                        Boss boss = (Boss) ctx.getBean("boss");
                        System.out.println(boss);
                        ctx.destroy();// 关闭 Spring 容器，以触发 Bean 销毁方法的执行
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>这时，您将看到标注了 <code>@PostConstruct</code> 的 <code>postConstruct1()</code> 方法将在 Spring 容器启动时，创建 <code>Boss</code> Bean 的时候被触发执行，而标注了 <code>@PreDestroy</code> 注释的 <code>preDestroy1()</code> 方法将在 Spring 容器关闭前销毁 <code>Boss</code> Bean 的时候被触发执行。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img alt="" src="//www.ibm.com/i/c.gif" width="100%" height="4" /><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N102C3"><span class="atitle">使用 &lt;context:annotation-config/&gt; 简化配置</span></a></p>
            <p>Spring 2.1 添加了一个新的 context 的 Schema 命名空间，该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会做任何事情的，它仅提供元数据信息。要使元数据信息真正起作用，必须让负责处理这些元数据的处理器工作起来。 </p>
            <p>而我们前面所介绍的 <code>AutowiredAnnotationBeanPostProcessor</code> 和 <code>CommonAnnotationBeanPostProcessor</code> 就是处理这些注释元数据的处理器。但是直接在 Spring 配置文件中定义这些 Bean 显得比较笨拙。Spring 为我们提供了一种方便的注册这些 <code>BeanPostProcessor</code> 的方式，这就是 &lt;context:annotation-config/&gt;。请看下面的配置：</p>
            <br />
            <a name="N102DE"><strong>清单 19. 调整 beans.xml 配置文件</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        &lt;?xml version="1.0" encoding="UTF-8" ?&gt;
                        &lt;beans xmlns="http://www.springframework.org/schema/beans"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xmlns:context="http://www.springframework.org/schema/context"
                        xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-2.5.xsd"&gt;
                        &lt;context:annotation-config/&gt;
                        &lt;bean id="boss" class="com.baobaotao.Boss"/&gt;
                        &lt;bean id="office" class="com.baobaotao.Office"&gt;
                        &lt;property name="officeNo" value="001"/&gt;
                        &lt;/bean&gt;
                        &lt;bean id="car" class="com.baobaotao.Car" scope="singleton"&gt;
                        &lt;property name="brand" value=" 红旗 CA72"/&gt;
                        &lt;property name="price" value="2000"/&gt;
                        &lt;/bean&gt;
                        &lt;/beans&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>&lt;context:annotationconfig/&gt; 将隐式地向 Spring 容器注册 <code>AutowiredAnnotationBeanPostProcessor</code>、<code>CommonAnnotationBeanPostProcessor</code>、<code>PersistenceAnnotationBeanPostProcessor</code> 以及 <code>equiredAnnotationBeanPostProcessor</code> 这 4 个 BeanPostProcessor。</p>
            <p>在配置文件中使用 context 命名空间之前，必须在 &lt;beans&gt; 元素中声明 context 命名空间。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img alt="" src="//www.ibm.com/i/c.gif" width="100%" height="4" /><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N102FA"><span class="atitle">使用 @Component</span></a></p>
            <p>虽然我们可以通过 <code>@Autowired</code> 或 <code>@Resource</code> 在 Bean 类中使用自动注入功能，但是 Bean 还是在 XML 文件中通过 &lt;bean&gt; 进行定义 —— 也就是说，在 XML 配置文件中定义 Bean，通过 <code>@Autowired</code> 或 <code>@Resource</code> 为 Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。能否也通过注释定义 Bean，从 XML 配置文件中完全移除 Bean 定义的配置呢？答案是肯定的，我们通过 Spring 2.5 提供的 <code>@Component</code> 注释就可以达到这个目标了。</p>
            <p>下面，我们完全使用注释定义 Bean 并完成 Bean 之间装配：</p>
            <br />
            <a name="N1031C"><strong>清单 20. 使用 @Component 注释的 Car.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import org.springframework.stereotype.Component;
                        @Component
                        public class Car {
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>仅需要在类定义处，使用 <code>@Component</code> 注释就可以将一个类定义了 Spring 容器中的 Bean。下面的代码将 <code>Office</code> 定义为一个 Bean：</p>
            <br />
            <a name="N10330"><strong>清单 21. 使用 @Component 注释的 Office.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import org.springframework.stereotype.Component;
                        @Component
                        public class Office {
                        private String officeNo = "001";
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>这样，我们就可以在 Boss 类中通过 <code>@Autowired</code> 注入前面定义的 <code>Car</code> 和 <code>Office Bean</code> 了。</p>
            <br />
            <a name="N10348"><strong>清单 22. 使用 @Component 注释的 Boss.java</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import org.springframework.beans.factory.annotation.Autowired;
                        import org.springframework.beans.factory.annotation.Required;
                        import org.springframework.beans.factory.annotation.Qualifier;
                        import org.springframework.stereotype.Component;
                        @Component("boss")
                        public class Boss {
                        @Autowired
                        private Car car;
                        @Autowired
                        private Office office;
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p><code>@Component</code> 有一个可选的入参，用于指定 Bean 的名称，在 Boss 中，我们就将 Bean 名称定义为&#8220;<code>boss</code>&#8221;。一般情况下，Bean 都是 singleton 的，需要注入 Bean 的地方仅需要通过 byType 策略就可以自动注入了，所以大可不必指定 Bean 的名称。</p>
            <p>在使用 <code>@Component</code> 注释后，Spring 容器必须启用类扫描机制以启用注释驱动 Bean 定义和注释驱动 Bean 自动注入的策略。Spring 2.5 对 context 命名空间进行了扩展，提供了这一功能，请看下面的配置：</p>
            <br />
            <a name="N10363"><strong>清单 23. 简化版的 beans.xml</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        &lt;?xml version="1.0" encoding="UTF-8" ?&gt;
                        &lt;beans xmlns="http://www.springframework.org/schema/beans"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xmlns:context="http://www.springframework.org/schema/context"
                        xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-2.5.xsd"&gt;
                        &lt;context:component-scan base-package="com.baobaotao"/&gt;
                        &lt;/beans&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>这里，所有通过 &lt;bean&gt; 元素定义 Bean 的配置内容已经被移除，仅需要添加一行 &lt;context:component-scan/&gt; 配置就解决所有问题了——Spring XML 配置文件得到了极致的简化（当然配置元数据还是需要的，只不过以注释形式存在罢了）。&lt;context:component-scan/&gt; 的 base-package 属性指定了需要扫描的类包，类包及其递归子包中所有的类都会被处理。</p>
            <p>&lt;context:component-scan/&gt; 还允许定义过滤器将基包下的某些类纳入或排除。Spring 支持以下 4 种类型的过滤方式，通过下表说明：</p>
            <br />
            <a name="N1036F"><strong>表 1. 扫描过滤方式</strong></a><br />
            <table class="data-table-1" border="0" cellspacing="0" summary="" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <th width="20%">过滤器类型</th>
                        <th width="80%">说明</th>
                    </tr>
                    <tr>
                        <td>注释</td>
                        <td>假如 com.baobaotao.SomeAnnotation 是一个注释类，我们可以将使用该注释的类过滤出来。</td>
                    </tr>
                    <tr>
                        <td>类名指定</td>
                        <td>通过全限定类名进行过滤，如您可以指定将 com.baobaotao.Boss 纳入扫描，而将 com.baobaotao.Car 排除在外。</td>
                    </tr>
                    <tr>
                        <td>正则表达式</td>
                        <td>通过正则表达式定义过滤的类，如下所示： com\.baobaotao\.Default.*</td>
                    </tr>
                    <tr>
                        <td>AspectJ 表达式</td>
                        <td>通过 AspectJ 表达式定义过滤的类，如下所示： com. baobaotao..*Service+</td>
                    </tr>
                </tbody>
            </table>
            <p>下面是一个简单的例子：</p>
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;context:component-scan base-package="com.baobaotao"&gt;
                        &lt;context:include-filter type="regex"
                        expression="com\.baobaotao\.service\..*"/&gt;
                        &lt;context:exclude-filter type="aspectj"
                        expression="com.baobaotao.util..*"/&gt;
                        &lt;/context:component-scan&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>值得注意的是 &lt;context:component-scan/&gt; 配置项不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能，同时还启用了注释驱动自动注入的功能（即还隐式地在内部注册了 <code>AutowiredAnnotationBeanPostProcessor</code> 和 <code>CommonAnnotationBeanPostProcessor</code>），因此当使用 &lt;context:component-scan/&gt; 后，就可以将 &lt;context:annotation-config/&gt; 移除了。</p>
            <p>默认情况下通过 <code>@Component</code> 定义的 Bean 都是 singleton 的，如果需要使用其它作用范围的 Bean，可以通过 <code>@Scope</code> 注释来达到目标，如以下代码所示：</p>
            <br />
            <a name="N103CC"><strong>清单 24. 通过 @Scope 指定 Bean 的作用范围</strong></a><br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                        package com.baobaotao;
                        import org.springframework.context.annotation.Scope;
                        &#8230;
                        @Scope("prototype")
                        @Component("boss")
                        public class Boss {
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>这样，当从 Spring 容器中获取 <code>boss</code> Bean 时，每次返回的都是新的实例了。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N103D9"><span class="atitle">采用具有特殊语义的注释</span></a></p>
            <p>Spring 2.5 中除了提供 <code>@Component</code> 注释外，还定义了几个拥有特殊语义的注释，它们分别是：<code>@Repository</code>、<code>@Service</code> 和 <code>@Controller</code>。在目前的 Spring 版本中，这 3 个注释和 <code>@Component</code> 是等效的，但是从注释类的命名上，很容易看出这 3 个注释分别和持久层、业务层和控制层（Web 层）相对应。虽然目前这 3 个注释和 <code>@Component</code> 相比没有什么新意，但 Spring 将在以后的版本中为它们添加特殊的功能。所以，如果 Web 应用程序采用了经典的三层分层结构的话，最好在持久层、业务层和控制层分别采用 <code>@Repository</code>、<code>@Service</code> 和 <code>@Controller</code> 对分层中的类进行注释，而用 <code>@Component</code> 对那些比较中立的类进行注释。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10409"><span class="atitle">注释配置和 XML 配置的适用场合</span></a></p>
            <p>是否有了这些 IOC 注释，我们就可以完全摒除原来 XML 配置的方式呢？答案是否定的。有以下几点原因：</p>
            <ul>
                <li>注释配置不一定在先天上优于 XML 配置。如果 Bean 的依赖关系是固定的，（如 Service 使用了哪几个 DAO 类），这种配置信息不会在部署时发生调整，那么注释配置优于 XML 配置；反之如果这种依赖关系会在部署时发生调整，XML 配置显然又优于注释配置，因为注释是对 Java 源代码的调整，您需要重新改写源代码并重新编译才可以实施调整。
                <li>如果 Bean 不是自己编写的类（如 <code>JdbcTemplate</code>、<code>SessionFactoryBean</code> 等），注释配置将无法实施，此时 XML 配置是唯一可用的方式。
                <li>注释配置往往是类级别的，而 XML 配置则可以表现得更加灵活。比如相比于 <code>@Transaction</code> 事务注释，使用 aop/tx 命名空间的事务配置更加灵活和简单。 </li>
            </ul>
            <p>所以在实现应用中，我们往往需要同时使用注释配置和 XML 配置，对于类级别且不会发生变动的配置可以优先考虑注释配置；而对于那些第三方类以及容易发生调整的配置则应优先考虑使用 XML 配置。Spring 会在具体实施 Bean 创建和 Bean 注入之前将这两种配置方式的元信息融合在一起。</p>
            <br />
            <table border="0" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                        <td><img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
                        <img border="0" alt="" src="//www.ibm.com/i/c.gif" width="8" height="6" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img alt="" src="//www.ibm.com/i/c.gif" width="100%" height="4" /><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N1042C"><span class="atitle">小结</span></a></p>
            <p>Spring 在 2.1 以后对注释配置提供了强力的支持，注释配置功能成为 Spring 2.5 的最大的亮点之一。合理地使用 Spring 2.5 的注释配置，可以有效减少配置的工作量，提高程序的内聚性。但是这并不意味着传统 XML 配置将走向消亡，在第三方类 Bean 的配置，以及那些诸如数据源、缓存池、持久层操作模板类、事务管理等内容的配置上，XML 配置依然拥有不可替代的地位。</p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/freeman1984/aggbug/329211.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-08-18 14:00 <a href="http://www.blogjava.net/freeman1984/archive/2010/08/18/329211.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于log4j的日志文件保存位置解决方案</title><link>http://www.blogjava.net/freeman1984/archive/2010/06/10/323236.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Thu, 10 Jun 2010 07:02:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/06/10/323236.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/323236.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/06/10/323236.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/323236.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/323236.html</trackback:ping><description><![CDATA[以DailyRollingFileAppender 为例：假设每天一个日志文件<br />
有以下设置：<br />
<br />
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender <br />
log4j.appender.A1.File=app.log<br />
log4j.appender.A1.DatePattern='.'yyyy-MM-dd<br />
log4j.appender.A1.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.A1.layout.ConversionPattern=%d %5p - %c -%-4r [%t]&nbsp;&nbsp;&nbsp; - %m%n<br />
<br />
此时生成日志文件将位于tomcat的bin目录下，如要将日志文件保存在 ：根目录/web-info/logs/下，个人有以下4种解决方案：<br />
1 绝对路径<br />
log4j.appender.A1.File=D:\apache-tomcat-6.0.18/webapps/项目/WEB-INF/logs/app.log<br />
但这种写法灵活性很差<br />
<br />
以下3中使用相同的设置原理： jvm的环境变量<br />
&nbsp;2：spring的Log4jConfigListener<br />
通过以下配置：<br />
&lt;context-param&gt;<br />
&nbsp; &nbsp;&nbsp;&lt;param-name&gt;webAppRootKey&lt;/param-name&gt;<br />
&nbsp; &nbsp;&nbsp;&lt;param-value&gt;webApp.root&lt;/param-value&gt;<br />
&nbsp;&nbsp;&lt;/context-param&gt;<br />
&nbsp;&lt;context-param&gt;<br />
&nbsp;&nbsp;&lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;<br />
&nbsp;&nbsp; &nbsp;&lt;param-value&gt;classpath:log4j.properties&lt;/param-value&gt;<br />
&nbsp;&lt;/context-param&gt;<br />
&lt;listener&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;&nbsp; <br />
&nbsp;&lt;/listener&gt;<br />
...<br />
log4j.appender.logfile.File=${webApp.root}/WEB-INF/logs/app.log<br />
...<br />
来解决<br />
&nbsp;2:使用已有jvm变量：<br />
例如：<br />
&nbsp;&nbsp;&nbsp; log4j.appender.logfile.File=${user.home}/logs/app.log<br />
&nbsp; 日志将位于：例如windows：C:\Documents and Settings\joe\logs\app.log<br />
<br />
3 自己设置目录，也就是在项目启动时通过System.setProperty设置<br />
通过实现ServletContextListener来解决：例如<br />
<p>public class log4jlistener implements ServletContextListener {</p>
<p>&nbsp;public static final String log4jdirkey = "log4jdir";<br />
&nbsp;public void contextDestroyed(ServletContextEvent servletcontextevent) {<br />
&nbsp;&nbsp;System.getProperties().remove(log4jdirkey);</p>
<p>&nbsp;}</p>
<p>&nbsp;public void contextInitialized(ServletContextEvent servletcontextevent) {<br />
&nbsp;&nbsp;String log4jdir = servletcontextevent.getServletContext().getRealPath("/");<br />
&nbsp;&nbsp;//System.out.println("log4jdir:"+log4jdir);<br />
&nbsp;&nbsp;System.setProperty(log4jdirkey, log4jdir);</p>
<p>&nbsp;}</p>
<p>}<br />
web.xml配置：<br />
</p>
&lt;listener&gt;<br />
&nbsp; &lt;listener-class&gt;com.log4j.log4jlistener&lt;/listener-class&gt;<br />
&nbsp;&lt;/listener&gt;<br />
<br />
log4j.prtperties 配置：<br />
log4j.appender.A1.File=${log4jdir}/WEB-INF/logs/app1.log<br />
来解决。<br />
<br />
如果各位还有其他方法，请回帖补充 谢谢。。。<br />
<img src ="http://www.blogjava.net/freeman1984/aggbug/323236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-06-10 15:02 <a href="http://www.blogjava.net/freeman1984/archive/2010/06/10/323236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Log4j</title><link>http://www.blogjava.net/freeman1984/archive/2010/06/10/323220.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Thu, 10 Jun 2010 05:00:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/06/10/323220.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/323220.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/06/10/323220.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/323220.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/323220.html</trackback:ping><description><![CDATA[转载自<a href="http://hi.baidu.com/%D3%B1%CB%AE%CB%AE/blog/item/175115949f263612d31b703b.html" target="_blank">http://hi.baidu.com/%D3%B1%CB%AE%CB%AE/blog/item/175115949f263612d31b703b.html</a> <br />
在实际编程时，要使Log4j真正在系统中运行事先还要对配置文件进行定义。定义步骤就是对Logger、Appender及Layout的分别使用。<br />
&nbsp;&nbsp;&nbsp; Log4j支持两种配置文件格式，一种是XML格式的文件，一种是java properties（key=value）【Java特性文件（键=值）】。下面我们介绍使用Java特性文件做为配置文件的方法<br />
&nbsp;&nbsp; 具体如下：<br />
　　<strong>1、配置根Logger，</strong>其语法为：<br />
　　log4j.rootLogger = [ level ] , appenderName1, appenderName2, &#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; level : 是日志记录的优先级，分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别，优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别，您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别，则应用程序中所有DEBUG级别的日志信息将不被打印出来。<br />
　　&nbsp;&nbsp;&nbsp;&nbsp; appenderName:就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。<br />
&nbsp;&nbsp; 例如：log4j.rootLogger＝info,A1,B2,C3<br />
　　<strong>2、配置日志信息输出目的地</strong>，其语法为：<br />
　　log4j.appender.appenderName = fully.qualified.name.of.appender.class //<br />
　　 "fully.qualified.name.of.appender.class" 可以指定下面五个目的地中的一个：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.org.apache.log4j.ConsoleAppender（控制台）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.org.apache.log4j.FileAppender（文件）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生一个新的文件）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>1.ConsoleAppender选项<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Threshold=WARN:指定日志消息的输出最低层次。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Target=System.err：默认情况下是：System.out,指定输出控制台<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>2.FileAppender</strong> 选项<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Threshold=WARN:指定日志消息的输出最低层次。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File=mylog.txt:指定消息输出到mylog.txt文件。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Append=false:默认值是true,即将消息增加到指定文件中，false指将消息覆盖指定的文件内容。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.<strong>DailyRollingFileAppender</strong> 选项<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Threshold=WARN:指定日志消息的输出最低层次。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File=mylog.txt:指定消息输出到mylog.txt文件。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Append=false:默认值是true,即将消息增加到指定文件中，false指将消息覆盖指定的文件内容。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DatePattern='.'yyyy-ww:每周滚动一次文件，即每周产生一个新的文件。当然也可以指定按月、周、天、时和分。即对应的格式如下：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1)'.'yyyy-MM: 每月<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2)'.'yyyy-ww: 每周 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3)'.'yyyy-MM-dd: 每天<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4)'.'yyyy-MM-dd-a: 每天两次<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5)'.'yyyy-MM-dd-HH: 每小时<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6)'.'yyyy-MM-dd-HH-mm: 每分钟<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.<strong>RollingFileAppender</strong> 选项<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Threshold=WARN:指定日志消息的输出最低层次。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File=mylog.txt:指定消息输出到mylog.txt文件。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Append=false:默认值是true,即将消息增加到指定文件中，false指将消息覆盖指定的文件内容。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时，将会自动滚动，即将原来的内容移到mylog.log.1文件。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MaxBackupIndex=2:指定可以产生的滚动文件的最大数。
<div>实际应用：<br />
　　log4j.appender.A1=org.apache.log4j.ConsoleAppender //这里指定了日志输出的第一个位置A1是控制台ConsoleAppender<br />
　　<strong>3、配置日志信息的格式</strong>，其语法为：<br />
　　<strong>A.</strong> <strong>log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "fully.qualified.name.of.layout.class" 可以指定下面4个格式中的一个：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.org.apache.log4j.HTMLLayout（以HTML表格形式布局），<br />
　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.org.apache.log4j.PatternLayout（可以灵活地指定布局模式），<br />
　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），<br />
　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.HTMLLayout 选项<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LocationInfo=true:默认值是false,输出java文件名称和行号<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Title=my app file: 默认值是 Log4J Log Messages.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.PatternLayout 选项<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConversionPattern=%m%n :指定怎样格式化指定的消息。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.XMLLayout 选项<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LocationInfo=true:默认值是false,输出java文件和行号<br />
&nbsp;&nbsp; 实际应用：<br />
&nbsp;&nbsp; 　　log4j.appender.A1.layout=org.apache.log4j.PatternLayout</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>B</strong>.<strong> log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里需要说明的就是日志信息格式中几个符号所代表的含义：<br />
　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; －X号: X信息输出时左对齐；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %p: 输出日志信息优先级，即DEBUG，INFO，WARN，ERROR，FATAL,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %d: 输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy MMM dd HH:mm:ss,SSS}，输出类似：2002年10月18日 22：10：28，921<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %r: 输出自应用启动到输出该log信息耗费的毫秒数<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %c: 输出日志信息所属的类目，通常就是所在类的全名<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %t: 输出产生该日志事件的线程名<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %l: 输出日志事件的发生位置，相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程，以及在代码中的行数。举例：Testlog4.main(TestLog4.java:10)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %%: 输出一个"%"字符<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %F: 输出日志消息产生时所在的文件名称<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %L: 输出代码中的行号<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %m: 输出代码中指定的消息,产生的日志具体信息<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %n: 输出一个回车换行符，Windows平台为"\r\n"，Unix平台为"\n"输出日志信息换行<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1)%20c：指定输出category的名称，最小的宽度是20，如果category的名称小于20的话，默认的情况下右对齐。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2)%-20c:指定输出category的名称，最小的宽度是20，如果category的名称小于20的话，"-"号指定左对齐。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3)%.30c:指定输出category的名称，最大的宽度是30，如果category的名称大于30的话，就会将左边多出的字符截掉，但小于30的话也不会有空格。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4)%20.30c:如果category的名称小于20就补空格，并且右对齐，如果其名称长于30字符，就从左边交远销出的字符截掉。</div>
<div>　　这里上面三个步骤是对前面Log4j组件说明的一个简化；下面给出一个具体配置例子，在程序中可以参照执行：<br />
　　log4j.rootLogger=INFO,A1，B2<br />
　　log4j.appender.A1=org.apache.log4j.ConsoleAppender<br />
　　log4j.appender.A1.layout=org.apache.log4j.PatternLayout<br />
　　log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n<br />
　　根据上面的日志格式，某一个程序的输出结果如下：<br />
　　0　　INFO　2003-06-13 13:23:46968 ClientWithLog4j Client socket: Socket[addr=localhost/127.0.0.1,port=8002,localport=2014]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16　 DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server says: 'Java server with log4j, Fri Jun 13 13:23:46 CST 2003'<br />
　　16　 DEBUG 2003-06-13 13:23:46984 ClientWithLog4j GOOD<br />
　　16　 DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server responds: 'Command 'HELLO' not understood.'<br />
　　16　 DEBUG 2003-06-13 13:23:46984 ClientWithLog4j HELP<br />
　　16　 DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server responds: 'Vocabulary: HELP QUIT'<br />
　　16　 DEBUG 2003-06-13 13:23:46984 ClientWithLog4j QUIT<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> 4. # 当输出信息于回滚文件时</strong></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender&nbsp;&nbsp; //指定以文件的方式输出日志<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.ROLLING_FILE.Threshold=ERROR <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.ROLLING_FILE.File=rolling.log //文件位置,也可以用变量${java.home}、rolling.log<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.ROLLING_FILE.Append=true <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.ROLLING_FILE.MaxFileSize=10KB //文件最大尺寸<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.ROLLING_FILE.MaxBackupIndex=1 //备份数<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 　　</div>
<div>&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;<strong><font color="#0000ff"><br />
</font></strong><strong><font color="#0000ff">&gt;&gt;&gt;&gt; 6. Log4j比较全面的配置 &lt;&lt;&lt;&lt;</font></strong></div>
<div>LOG4J的配置之简单使它遍及于越来越多的应用中了：Log4J配置文件实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签等全套功能。择其一二使用就够用了，</div>
<div>log4j.rootLogger=DEBUG,CONSOLE,A1,im <br />
log4j.addivity.org.apache=true</div>
<div># 应用于控制台</div>
<div>log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender <br />
log4j.appender.Threshold=DEBUG <br />
log4j.appender.CONSOLE.Target=System.out <br />
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout <br />
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br />
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n</div>
<div>#应用于文件</div>
<div>log4j.appender.FILE=org.apache.log4j.FileAppender <br />
log4j.appender.FILE.File=file.log <br />
log4j.appender.FILE.Append=false <br />
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout <br />
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br />
# Use this layout for LogFactor 5 analysis</div>
<div># 应用于文件回滚</div>
<div>log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender <br />
log4j.appender.ROLLING_FILE.Threshold=ERROR <br />
log4j.appender.ROLLING_FILE.File=rolling.log //文件位置,也可以用变量${java.home}、rolling.log<br />
log4j.appender.ROLLING_FILE.Append=true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //true:添加 false:覆盖<br />
log4j.appender.ROLLING_FILE.MaxFileSize=10KB&nbsp;&nbsp; //文件最大尺寸<br />
log4j.appender.ROLLING_FILE.MaxBackupIndex=1 //备份数<br />
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout <br />
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br />
#应用于socket <br />
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender <br />
log4j.appender.SOCKET.RemoteHost=localhost <br />
log4j.appender.SOCKET.Port=5001 <br />
log4j.appender.SOCKET.LocationInfo=true <br />
# Set up for Log Facter 5 <br />
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout <br />
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n <br />
# Log Factor 5 Appender <br />
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender <br />
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000</div>
<div># 发送日志给邮件</div>
<div>log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender <br />
log4j.appender.MAIL.Threshold=FATAL <br />
log4j.appender.MAIL.BufferSize=10 <br />
<a><font color="#000080">www.wuset.com</font></a>"&gt;log4j.appender.MAIL.From=web@<a href="http://www.wuset.com/" target="_blank"><font color="#000080">www.wuset.com</font></a> <br />
log4j.appender.MAIL.SMTPHost=www.wusetu.com <br />
log4j.appender.MAIL.Subject=Log4J Message <br />
<a><font color="#000080">www.wusetu.com</font></a>"&gt;log4j.appender.MAIL.To=web@<a href="http://www.wusetu.com/" target="_blank"><font color="#000080">www.wusetu.com</font></a> <br />
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout <br />
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</div>
<div># 用于数据库 <br />
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender <br />
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test <br />
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver <br />
log4j.appender.DATABASE.user=root <br />
log4j.appender.DATABASE.password= <br />
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n') <br />
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout <br />
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br />
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender <br />
log4j.appender.A1.File=SampleMessages.log4j <br />
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j' <br />
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout</div>
<div>#自定义Appender</div>
<div>log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender</div>
<div>log4j.appender.im.host = mail.cybercorlin.net <br />
log4j.appender.im.username = username <br />
log4j.appender.im.password = password <br />
log4j.appender.im.recipient = <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#111;&#114;&#108;&#105;&#110;&#64;&#99;&#121;&#98;&#101;&#114;&#99;&#111;&#114;&#108;&#105;&#110;&#46;&#110;&#101;&#116;"><font color="#000080">corlin@cybercorlin.net</font></a></div>
<div>log4j.appender.im.layout=org.apache.log4j.PatternLayout <br />
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</div>
<img src ="http://www.blogjava.net/freeman1984/aggbug/323220.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-06-10 13:00 <a href="http://www.blogjava.net/freeman1984/archive/2010/06/10/323220.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring事务的传播行为和隔离级别 </title><link>http://www.blogjava.net/freeman1984/archive/2010/04/28/319595.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 28 Apr 2010 06:30:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/04/28/319595.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/319595.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/04/28/319595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/319595.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/319595.html</trackback:ping><description><![CDATA[<p style="line-height: 150%; margin: 5px">转载自：http://blog.chinaunix.net/u1/55983/showart_2091761.html<code><span style="color: #000000"><br />
7个传播行为，4个隔离级别， <br />
<br />
Spring事务的传播行为和隔离级别<span style="color: #0000cc">[</span><span style="color: #ff0000">transaction</span> behavior <span style="color: #ff0000">and</span> isolated <span style="color: #ff0000">level</span><span style="color: #0000cc">]</span>2007<span style="color: #0000cc">-</span>08<span style="color: #0000cc">-</span>01 16<span style="color: #0000cc">:</span>33事务的传播行为和隔离级别<span style="color: #0000cc">[</span><span style="color: #ff0000">transaction</span> behavior <span style="color: #ff0000">and</span> isolated <span style="color: #ff0000">level</span><span style="color: #0000cc">]</span><br />
<br />
Spring中事务的定义：<br />
一、Propagation ：<br />
　　key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用：<br />
PROPAGATION_REQUIRED<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>支持当前事务，如果当前没有事务，就新建一个事务。这是最常见的选择。 <br />
PROPAGATION_SUPPORTS<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>支持当前事务，如果当前没有事务，就以非事务方式执行。 <br />
PROPAGATION_MANDATORY<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>支持当前事务，如果当前没有事务，就抛出异常。 <br />
PROPAGATION_REQUIRES_NEW<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>新建事务，如果当前存在事务，把当前事务挂起。 <br />
PROPAGATION_NOT_SUPPORTED<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>以非事务方式执行操作，如果当前存在事务，就把当前事务挂起。 <br />
PROPAGATION_NEVER<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>以非事务方式执行，如果当前存在事务，则抛出异常。 <br />
<br />
很多人看到事务的传播行为属性都不甚了解，我昨晚看了j2ee without ejb的时候，看到这里也不了解，甚至重新翻起数据库系统的教材书，但是也没有找到对这个的分析。今天搜索，找到一篇极好的分析文章，虽然这篇文章是重点分析PROPAGATION_REQUIRED 和 PROPAGATION_REQUIRED_NESTED的<br />
<span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><br />
&nbsp;&nbsp;<br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />
解惑 <span style="color: #ff0000">spring</span> 嵌套事务 <br />
<span style="color: #ff9900">/** <br />
* @date 2006-11-24 <br />
* @note 转载自http://www.javaeye.com/topic/35907?page=1<br />
*/</span> <br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span>TransactionDefinition 接口定义<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><br />
<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Support a current transaction, create a new one if none exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
This is typically the default setting of a transaction definition. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_REQUIRED <span style="color: #0000cc">=</span> 0<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Support a current transaction, execute non-transactionally if none exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
<br />
Note: For transaction managers with transaction synchronization, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* PROPAGATION_SUPPORTS is slightly different from no transaction at all, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* as it defines a transaction scopp that synchronization will apply for. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* As a consequence, the same resources (JDBC Connection, Hibernate Session, etc) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* will be shared for the entire specified scope. Note that this depends on <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* the actual synchronization configuration of the transaction manager. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_SUPPORTS <span style="color: #0000cc">=</span> 1<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Support a current transaction, throw an exception if none exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_MANDATORY <span style="color: #0000cc">=</span> 2<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Create a new transaction, suspend the current transaction if one exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
<br />
Note: Actual transaction suspension will not work on out-of-the-box <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* on all transaction managers. This in particular applies to JtaTransactionManager, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* which requires the javax.transaction.TransactionManager to be <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* made available it to it (which is server-specific in standard J2EE). <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_REQUIRES_NEW <span style="color: #0000cc">=</span> 3<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Execute non-transactionally, suspend the current transaction if one exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
<br />
Note: Actual transaction suspension will not work on out-of-the-box <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* on all transaction managers. This in particular applies to JtaTransactionManager, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* which requires the javax.transaction.TransactionManager to be <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* made available it to it (which is server-specific in standard J2EE). <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_NOT_SUPPORTED <span style="color: #0000cc">=</span> 4<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Execute non-transactionally, throw an exception if a transaction exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_NEVER <span style="color: #0000cc">=</span> 5<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Execute within a nested transaction if a current transaction exists, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
<br />
Note: Actual creation of a nested transaction will only work on specific <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* transaction managers. Out of the box, this only applies to the JDBC <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* DataSourceTransactionManager when working on a JDBC 3.0 driver. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Some JTA providers might support nested transactions as well. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.springframework.jdbc.datasource.DataSourceTransactionManager <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_NESTED <span style="color: #0000cc">=</span> 6<span style="color: #0000cc">;</span> <br />
<br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><br />
在这篇文章里，他用两个嵌套的例子辅助分析，我这里直接引用了。<br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span>sample<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><br />
ServiceA <span style="color: #0000cc">{</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* 事务属性配置为 PROPAGATION_REQUIRED <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">void</span> methodA<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span> <span style="color: #0000cc">{</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServiceB<span style="color: #0000cc">.</span>methodB<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span><span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000cc">}</span> <br />
&nbsp;&nbsp;<br />
<span style="color: #0000cc">}</span> <br />
&nbsp;&nbsp;<br />
ServiceB <span style="color: #0000cc">{</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* 事务属性配置为 PROPAGATION_REQUIRED <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">void</span> methodB<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span> <span style="color: #0000cc">{</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000cc">}</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #0000cc">}</span> <br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><br />
1： PROPAGATION_REQUIRED <br />
加入当前正要执行的事务不在另外一个事务里，那么就起一个新的事务 <br />
比如说，ServiceB<span style="color: #0000cc">.</span>methodB的事务级别定义为PROPAGATION_REQUIRED<span style="color: #0000cc">,</span> 那么由于执行ServiceA<span style="color: #0000cc">.</span>methodA的时候， <br />
ServiceA<span style="color: #0000cc">.</span>methodA已经起了事务，这时调用ServiceB<span style="color: #0000cc">.</span>methodB，ServiceB<span style="color: #0000cc">.</span>methodB看到自己已经运行在ServiceA<span style="color: #0000cc">.</span>methodA <br />
的事务内部，就不再起新的事务。而假如ServiceA<span style="color: #0000cc">.</span>methodA运行的时候发现自己没有在事务中，他就会为自己分配一个事务。 <br />
这样，在ServiceA<span style="color: #0000cc">.</span>methodA或者在ServiceB<span style="color: #0000cc">.</span>methodB内的任何地方出现异常，事务都会被回滚。即使ServiceB<span style="color: #0000cc">.</span>methodB的事务已经被 <br />
提交，但是ServiceA<span style="color: #0000cc">.</span>methodA在接下来fail要回滚，ServiceB<span style="color: #0000cc">.</span>methodB也要回滚 <br />
<br />
2： PROPAGATION_SUPPORTS <br />
如果当前在事务中，即以事务的形式运行，如果当前不再一个事务中，那么就以非事务的形式运行 <br />
<br />
<br />
3： PROPAGATION_MANDATORY <br />
必须在一个事务中运行。也就是说，他只能被一个父事务调用。否则，他就要抛出异常 <br />
<br />
4： PROPAGATION_REQUIRES_NEW <br />
这个就比较绕口了。 比如我们设计ServiceA<span style="color: #0000cc">.</span>methodA的事务级别为PROPAGATION_REQUIRED，ServiceB<span style="color: #0000cc">.</span>methodB的事务级别为PROPAGATION_REQUIRES_NEW， <br />
那么当执行到ServiceB<span style="color: #0000cc">.</span>methodB的时候，ServiceA<span style="color: #0000cc">.</span>methodA所在的事务就会挂起，ServiceB<span style="color: #0000cc">.</span>methodB会起一个新的事务，等待ServiceB<span style="color: #0000cc">.</span>methodB的事务完成以后， <br />
他才继续执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB<span style="color: #0000cc">.</span>methodB是新起一个事务，那么就是存在 <br />
两个不同的事务。如果ServiceB<span style="color: #0000cc">.</span>methodB已经提交，那么ServiceA<span style="color: #0000cc">.</span>methodA失败回滚，ServiceB<span style="color: #0000cc">.</span>methodB是不会回滚的。如果ServiceB<span style="color: #0000cc">.</span>methodB失败回滚， <br />
如果他抛出的异常被ServiceA<span style="color: #0000cc">.</span>methodA捕获，ServiceA<span style="color: #0000cc">.</span>methodA事务仍然可能提交。 <br />
<br />
5： PROPAGATION_NOT_SUPPORTED <br />
当前不支持事务。比如ServiceA<span style="color: #0000cc">.</span>methodA的事务级别是PROPAGATION_REQUIRED ，而ServiceB<span style="color: #0000cc">.</span>methodB的事务级别是PROPAGATION_NOT_SUPPORTED ， <br />
那么当执行到ServiceB<span style="color: #0000cc">.</span>methodB时，ServiceA<span style="color: #0000cc">.</span>methodA的事务挂起，而他以非事务的状态运行完，再继续ServiceA<span style="color: #0000cc">.</span>methodA的事务。 <br />
<br />
6： PROPAGATION_NEVER <br />
不能在事务中运行。假设ServiceA<span style="color: #0000cc">.</span>methodA的事务级别是PROPAGATION_REQUIRED， 而ServiceB<span style="color: #0000cc">.</span>methodB的事务级别是PROPAGATION_NEVER ， <br />
那么ServiceB<span style="color: #0000cc">.</span>methodB就要抛出异常了。 <br />
<br />
7： PROPAGATION_NESTED <br />
理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是，PROPAGATION_REQUIRES_NEW另起一个事务，将会与他的父事务相互独立， <br />
而Nested的事务和他的父事务是相依的，他的提交是要等和他的父事务一块提交的。也就是说，如果父事务最后回滚，他也要回滚的。 <br />
而Nested事务的好处是他有一个savepoint。 <br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span> <br />
ServiceA <span style="color: #0000cc">{</span> <br />
<br />
<span style="color: #ff9900">/** <br />
* 事务属性配置为 PROPAGATION_REQUIRED <br />
*/</span> <br />
<span style="color: #0000ff">void</span> methodA<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span> <span style="color: #0000cc">{</span> <br />
<span style="color: #0000ff">try</span> <span style="color: #0000cc">{</span> <br />
<span style="color: #ff9900">//savepoint <br />
</span><br />
ServiceB<span style="color: #0000cc">.</span>methodB<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span><span style="color: #0000cc">;</span> <span style="color: #ff9900">//PROPAGATION_NESTED 级别 <br />
</span><br />
<span style="color: #0000cc">}</span> <span style="color: #0000ff">catch</span> <span style="color: #0000cc">(</span>SomeException<span style="color: #0000cc">)</span> <span style="color: #0000cc">{</span> <br />
<span style="color: #ff9900">// 执行其他业务, 如 ServiceC.methodC(); <br />
</span><br />
<span style="color: #0000cc">}</span> <br />
<span style="color: #0000cc">}</span> <br />
<br />
<span style="color: #0000cc">}</span> <br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span> <br />
也就是说ServiceB<span style="color: #0000cc">.</span>methodB失败回滚，那么ServiceA<span style="color: #0000cc">.</span>methodA也会回滚到savepoint点上，ServiceA<span style="color: #0000cc">.</span>methodA可以选择另外一个分支，比如 <br />
ServiceC<span style="color: #0000cc">.</span>methodC，继续执行，来尝试完成自己的事务。 <br />
但是这个事务并没有在EJB标准中定义。 <br />
<br />
二、Isolation <span style="color: #ff0000">Level</span><span style="color: #0000cc">(</span>事务隔离等级<span style="color: #0000cc">)</span><span style="color: #0000cc">:</span> <br />
1、Serializable：最严格的级别，事务串行执行，资源消耗最大； <br />
2、REPEATABLE READ：保证了一个事务不会修改已经由另一个事务读取但未提交（回滚）的数据。避免了&#8220;脏读取&#8221;和&#8220;不可重复读取&#8221;的情况，但是带来了更多的性能损失。 <br />
3、READ COMMITTED<span style="color: #0000cc">:</span>大多数主流数据库的默认事务等级，保证了一个事务不会读到另一个并行事务已修改但未提交的数据，避免了&#8220;脏读取&#8221;。该级别适用于大多数系统。 <br />
4、Read Uncommitted：保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。 <br />
我们知道并行可以提高数据库的吞吐量和效率，但是并不是所有的并发事务都可以并发运行，这需要查看数据库教材的可串行化条件判断了。 <br />
这里就不阐述。 <br />
我们首先说并发中可能发生的3中不讨人喜欢的事情 <br />
1： <span style="color: #ff0000">Dirty</span> reads<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>读脏数据。也就是说，比如事务A的未提交（还依然缓存）的数据被事务B读走，如果事务A失败回滚，会导致事务B所读取的的数据是错误的。 <br />
2： non<span style="color: #0000cc">-</span>repeatable reads<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>数据不可重复读。比如事务A中两处读取数据<span style="color: #0000cc">-</span>total<span style="color: #0000cc">-</span>的值。在第一读的时候，total是100，然后事务B就把total的数据改成200，事务A再读一次，结果就发现，total竟然就变成200了，造成事务A数据混乱。 <br />
3： phantom reads<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>幻象读数据，这个和non<span style="color: #0000cc">-</span>repeatable reads相似，也是同一个事务中多次读不一致的问题。但是non<span style="color: #0000cc">-</span>repeatable reads的不一致是因为他所要取的数据集被改变了（比如total的数据），但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变，而是他的条件数据集改变。比如Select account<span style="color: #0000cc">.</span><span style="color: #ff0000">id</span> where account<span style="color: #0000cc">.</span><span style="color: #ff0000">name</span><span style="color: #0000cc">=</span><span style="color: #ff00ff">"ppgogo*"</span><span style="color: #0000cc">,</span>第一次读去了6个符合条件的id，第二次读取的时候，由于事务b把一个帐号的名字由<span style="color: #ff00ff">"dd"</span>改成<span style="color: #ff00ff">"ppgogo1"</span>，结果取出来了7个数据。 <span style="color: #ff0000">Dirty</span> reads non<span style="color: #0000cc">-</span>repeatable reads phantom reads <br />
<span style="color: #ff0000">Serializable</span> 不会 不会 不会 <br />
REPEATABLE <span style="color: #ff0000">READ</span> 不会 不会 会 <br />
<span style="color: #ff0000">READ</span> COMMITTED 不会 会 会 <br />
<span style="color: #ff0000">Read</span> Uncommitted 会 会 会 <br />
<br />
<br />
<br />
<br />
<br />
三、readOnly <br />
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。<br />
<br />
这是一个最优化提示。在一些情况下，一些事务策略能够起到显著的最优化效果，例如在使用Object<span style="color: #0000cc">/</span>Relational映射工具（如：Hibernate或TopLink）时避免dirty checking（试图&#8220;刷新&#8221;）。<br />
<br />
四、Timeout <br />
<br />
在事务属性中还有定义&#8220;timeout&#8221;值的选项，指定事务超时为几秒。在JTA中，这将被简单地传递到J2EE服务器的事务协调程序，并据此得到相应的解释。<br />
</span></code></p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/319595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-04-28 14:30 <a href="http://www.blogjava.net/freeman1984/archive/2010/04/28/319595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring事务的传播行为和隔离级别 </title><link>http://www.blogjava.net/freeman1984/archive/2010/04/28/319596.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 28 Apr 2010 06:30:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/04/28/319596.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/319596.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/04/28/319596.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/319596.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/319596.html</trackback:ping><description><![CDATA[<p style="line-height: 150%; margin: 5px">转载自：http://blog.chinaunix.net/u1/55983/showart_2091761.html<code><span style="color: #000000"><br />
7个传播行为，4个隔离级别， <br />
<br />
Spring事务的传播行为和隔离级别<span style="color: #0000cc">[</span><span style="color: #ff0000">transaction</span> behavior <span style="color: #ff0000">and</span> isolated <span style="color: #ff0000">level</span><span style="color: #0000cc">]</span>2007<span style="color: #0000cc">-</span>08<span style="color: #0000cc">-</span>01 16<span style="color: #0000cc">:</span>33事务的传播行为和隔离级别<span style="color: #0000cc">[</span><span style="color: #ff0000">transaction</span> behavior <span style="color: #ff0000">and</span> isolated <span style="color: #ff0000">level</span><span style="color: #0000cc">]</span><br />
<br />
Spring中事务的定义：<br />
一、Propagation ：<br />
　　key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用：<br />
PROPAGATION_REQUIRED<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>支持当前事务，如果当前没有事务，就新建一个事务。这是最常见的选择。 <br />
PROPAGATION_SUPPORTS<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>支持当前事务，如果当前没有事务，就以非事务方式执行。 <br />
PROPAGATION_MANDATORY<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>支持当前事务，如果当前没有事务，就抛出异常。 <br />
PROPAGATION_REQUIRES_NEW<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>新建事务，如果当前存在事务，把当前事务挂起。 <br />
PROPAGATION_NOT_SUPPORTED<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>以非事务方式执行操作，如果当前存在事务，就把当前事务挂起。 <br />
PROPAGATION_NEVER<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>以非事务方式执行，如果当前存在事务，则抛出异常。 <br />
<br />
很多人看到事务的传播行为属性都不甚了解，我昨晚看了j2ee without ejb的时候，看到这里也不了解，甚至重新翻起数据库系统的教材书，但是也没有找到对这个的分析。今天搜索，找到一篇极好的分析文章，虽然这篇文章是重点分析PROPAGATION_REQUIRED 和 PROPAGATION_REQUIRED_NESTED的<br />
<span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><span style="color: #0000cc">=</span><br />
&nbsp;&nbsp;<br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />
解惑 <span style="color: #ff0000">spring</span> 嵌套事务 <br />
<span style="color: #ff9900">/** <br />
* @date 2006-11-24 <br />
* @note 转载自http://www.javaeye.com/topic/35907?page=1<br />
*/</span> <br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span>TransactionDefinition 接口定义<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><br />
<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Support a current transaction, create a new one if none exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
This is typically the default setting of a transaction definition. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_REQUIRED <span style="color: #0000cc">=</span> 0<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Support a current transaction, execute non-transactionally if none exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
<br />
Note: For transaction managers with transaction synchronization, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* PROPAGATION_SUPPORTS is slightly different from no transaction at all, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* as it defines a transaction scopp that synchronization will apply for. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* As a consequence, the same resources (JDBC Connection, Hibernate Session, etc) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* will be shared for the entire specified scope. Note that this depends on <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* the actual synchronization configuration of the transaction manager. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_SUPPORTS <span style="color: #0000cc">=</span> 1<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Support a current transaction, throw an exception if none exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_MANDATORY <span style="color: #0000cc">=</span> 2<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Create a new transaction, suspend the current transaction if one exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
<br />
Note: Actual transaction suspension will not work on out-of-the-box <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* on all transaction managers. This in particular applies to JtaTransactionManager, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* which requires the javax.transaction.TransactionManager to be <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* made available it to it (which is server-specific in standard J2EE). <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_REQUIRES_NEW <span style="color: #0000cc">=</span> 3<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Execute non-transactionally, suspend the current transaction if one exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
<br />
Note: Actual transaction suspension will not work on out-of-the-box <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* on all transaction managers. This in particular applies to JtaTransactionManager, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* which requires the javax.transaction.TransactionManager to be <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* made available it to it (which is server-specific in standard J2EE). <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_NOT_SUPPORTED <span style="color: #0000cc">=</span> 4<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Execute non-transactionally, throw an exception if a transaction exists. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Analogous to EJB transaction attribute of the same name. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_NEVER <span style="color: #0000cc">=</span> 5<span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Execute within a nested transaction if a current transaction exists, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <br />
<br />
Note: Actual creation of a nested transaction will only work on specific <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* transaction managers. Out of the box, this only applies to the JDBC <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* DataSourceTransactionManager when working on a JDBC 3.0 driver. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Some JTA providers might support nested transactions as well. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.springframework.jdbc.datasource.DataSourceTransactionManager <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span> PROPAGATION_NESTED <span style="color: #0000cc">=</span> 6<span style="color: #0000cc">;</span> <br />
<br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><br />
在这篇文章里，他用两个嵌套的例子辅助分析，我这里直接引用了。<br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span>sample<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><br />
ServiceA <span style="color: #0000cc">{</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* 事务属性配置为 PROPAGATION_REQUIRED <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">void</span> methodA<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span> <span style="color: #0000cc">{</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServiceB<span style="color: #0000cc">.</span>methodB<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span><span style="color: #0000cc">;</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000cc">}</span> <br />
&nbsp;&nbsp;<br />
<span style="color: #0000cc">}</span> <br />
&nbsp;&nbsp;<br />
ServiceB <span style="color: #0000cc">{</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900">/** <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* 事务属性配置为 PROPAGATION_REQUIRED <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">void</span> methodB<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span> <span style="color: #0000cc">{</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000cc">}</span> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #0000cc">}</span> <br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><br />
1： PROPAGATION_REQUIRED <br />
加入当前正要执行的事务不在另外一个事务里，那么就起一个新的事务 <br />
比如说，ServiceB<span style="color: #0000cc">.</span>methodB的事务级别定义为PROPAGATION_REQUIRED<span style="color: #0000cc">,</span> 那么由于执行ServiceA<span style="color: #0000cc">.</span>methodA的时候， <br />
ServiceA<span style="color: #0000cc">.</span>methodA已经起了事务，这时调用ServiceB<span style="color: #0000cc">.</span>methodB，ServiceB<span style="color: #0000cc">.</span>methodB看到自己已经运行在ServiceA<span style="color: #0000cc">.</span>methodA <br />
的事务内部，就不再起新的事务。而假如ServiceA<span style="color: #0000cc">.</span>methodA运行的时候发现自己没有在事务中，他就会为自己分配一个事务。 <br />
这样，在ServiceA<span style="color: #0000cc">.</span>methodA或者在ServiceB<span style="color: #0000cc">.</span>methodB内的任何地方出现异常，事务都会被回滚。即使ServiceB<span style="color: #0000cc">.</span>methodB的事务已经被 <br />
提交，但是ServiceA<span style="color: #0000cc">.</span>methodA在接下来fail要回滚，ServiceB<span style="color: #0000cc">.</span>methodB也要回滚 <br />
<br />
2： PROPAGATION_SUPPORTS <br />
如果当前在事务中，即以事务的形式运行，如果当前不再一个事务中，那么就以非事务的形式运行 <br />
<br />
<br />
3： PROPAGATION_MANDATORY <br />
必须在一个事务中运行。也就是说，他只能被一个父事务调用。否则，他就要抛出异常 <br />
<br />
4： PROPAGATION_REQUIRES_NEW <br />
这个就比较绕口了。 比如我们设计ServiceA<span style="color: #0000cc">.</span>methodA的事务级别为PROPAGATION_REQUIRED，ServiceB<span style="color: #0000cc">.</span>methodB的事务级别为PROPAGATION_REQUIRES_NEW， <br />
那么当执行到ServiceB<span style="color: #0000cc">.</span>methodB的时候，ServiceA<span style="color: #0000cc">.</span>methodA所在的事务就会挂起，ServiceB<span style="color: #0000cc">.</span>methodB会起一个新的事务，等待ServiceB<span style="color: #0000cc">.</span>methodB的事务完成以后， <br />
他才继续执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB<span style="color: #0000cc">.</span>methodB是新起一个事务，那么就是存在 <br />
两个不同的事务。如果ServiceB<span style="color: #0000cc">.</span>methodB已经提交，那么ServiceA<span style="color: #0000cc">.</span>methodA失败回滚，ServiceB<span style="color: #0000cc">.</span>methodB是不会回滚的。如果ServiceB<span style="color: #0000cc">.</span>methodB失败回滚， <br />
如果他抛出的异常被ServiceA<span style="color: #0000cc">.</span>methodA捕获，ServiceA<span style="color: #0000cc">.</span>methodA事务仍然可能提交。 <br />
<br />
5： PROPAGATION_NOT_SUPPORTED <br />
当前不支持事务。比如ServiceA<span style="color: #0000cc">.</span>methodA的事务级别是PROPAGATION_REQUIRED ，而ServiceB<span style="color: #0000cc">.</span>methodB的事务级别是PROPAGATION_NOT_SUPPORTED ， <br />
那么当执行到ServiceB<span style="color: #0000cc">.</span>methodB时，ServiceA<span style="color: #0000cc">.</span>methodA的事务挂起，而他以非事务的状态运行完，再继续ServiceA<span style="color: #0000cc">.</span>methodA的事务。 <br />
<br />
6： PROPAGATION_NEVER <br />
不能在事务中运行。假设ServiceA<span style="color: #0000cc">.</span>methodA的事务级别是PROPAGATION_REQUIRED， 而ServiceB<span style="color: #0000cc">.</span>methodB的事务级别是PROPAGATION_NEVER ， <br />
那么ServiceB<span style="color: #0000cc">.</span>methodB就要抛出异常了。 <br />
<br />
7： PROPAGATION_NESTED <br />
理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是，PROPAGATION_REQUIRES_NEW另起一个事务，将会与他的父事务相互独立， <br />
而Nested的事务和他的父事务是相依的，他的提交是要等和他的父事务一块提交的。也就是说，如果父事务最后回滚，他也要回滚的。 <br />
而Nested事务的好处是他有一个savepoint。 <br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span> <br />
ServiceA <span style="color: #0000cc">{</span> <br />
<br />
<span style="color: #ff9900">/** <br />
* 事务属性配置为 PROPAGATION_REQUIRED <br />
*/</span> <br />
<span style="color: #0000ff">void</span> methodA<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span> <span style="color: #0000cc">{</span> <br />
<span style="color: #0000ff">try</span> <span style="color: #0000cc">{</span> <br />
<span style="color: #ff9900">//savepoint <br />
</span><br />
ServiceB<span style="color: #0000cc">.</span>methodB<span style="color: #0000cc">(</span><span style="color: #0000cc">)</span><span style="color: #0000cc">;</span> <span style="color: #ff9900">//PROPAGATION_NESTED 级别 <br />
</span><br />
<span style="color: #0000cc">}</span> <span style="color: #0000ff">catch</span> <span style="color: #0000cc">(</span>SomeException<span style="color: #0000cc">)</span> <span style="color: #0000cc">{</span> <br />
<span style="color: #ff9900">// 执行其他业务, 如 ServiceC.methodC(); <br />
</span><br />
<span style="color: #0000cc">}</span> <br />
<span style="color: #0000cc">}</span> <br />
<br />
<span style="color: #0000cc">}</span> <br />
<span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span><span style="color: #0000cc">*</span> <br />
也就是说ServiceB<span style="color: #0000cc">.</span>methodB失败回滚，那么ServiceA<span style="color: #0000cc">.</span>methodA也会回滚到savepoint点上，ServiceA<span style="color: #0000cc">.</span>methodA可以选择另外一个分支，比如 <br />
ServiceC<span style="color: #0000cc">.</span>methodC，继续执行，来尝试完成自己的事务。 <br />
但是这个事务并没有在EJB标准中定义。 <br />
<br />
二、Isolation <span style="color: #ff0000">Level</span><span style="color: #0000cc">(</span>事务隔离等级<span style="color: #0000cc">)</span><span style="color: #0000cc">:</span> <br />
1、Serializable：最严格的级别，事务串行执行，资源消耗最大； <br />
2、REPEATABLE READ：保证了一个事务不会修改已经由另一个事务读取但未提交（回滚）的数据。避免了&#8220;脏读取&#8221;和&#8220;不可重复读取&#8221;的情况，但是带来了更多的性能损失。 <br />
3、READ COMMITTED<span style="color: #0000cc">:</span>大多数主流数据库的默认事务等级，保证了一个事务不会读到另一个并行事务已修改但未提交的数据，避免了&#8220;脏读取&#8221;。该级别适用于大多数系统。 <br />
4、Read Uncommitted：保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。 <br />
我们知道并行可以提高数据库的吞吐量和效率，但是并不是所有的并发事务都可以并发运行，这需要查看数据库教材的可串行化条件判断了。 <br />
这里就不阐述。 <br />
我们首先说并发中可能发生的3中不讨人喜欢的事情 <br />
1： <span style="color: #ff0000">Dirty</span> reads<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>读脏数据。也就是说，比如事务A的未提交（还依然缓存）的数据被事务B读走，如果事务A失败回滚，会导致事务B所读取的的数据是错误的。 <br />
2： non<span style="color: #0000cc">-</span>repeatable reads<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>数据不可重复读。比如事务A中两处读取数据<span style="color: #0000cc">-</span>total<span style="color: #0000cc">-</span>的值。在第一读的时候，total是100，然后事务B就把total的数据改成200，事务A再读一次，结果就发现，total竟然就变成200了，造成事务A数据混乱。 <br />
3： phantom reads<span style="color: #0000cc">-</span><span style="color: #0000cc">-</span>幻象读数据，这个和non<span style="color: #0000cc">-</span>repeatable reads相似，也是同一个事务中多次读不一致的问题。但是non<span style="color: #0000cc">-</span>repeatable reads的不一致是因为他所要取的数据集被改变了（比如total的数据），但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变，而是他的条件数据集改变。比如Select account<span style="color: #0000cc">.</span><span style="color: #ff0000">id</span> where account<span style="color: #0000cc">.</span><span style="color: #ff0000">name</span><span style="color: #0000cc">=</span><span style="color: #ff00ff">"ppgogo*"</span><span style="color: #0000cc">,</span>第一次读去了6个符合条件的id，第二次读取的时候，由于事务b把一个帐号的名字由<span style="color: #ff00ff">"dd"</span>改成<span style="color: #ff00ff">"ppgogo1"</span>，结果取出来了7个数据。 <span style="color: #ff0000">Dirty</span> reads non<span style="color: #0000cc">-</span>repeatable reads phantom reads <br />
<span style="color: #ff0000">Serializable</span> 不会 不会 不会 <br />
REPEATABLE <span style="color: #ff0000">READ</span> 不会 不会 会 <br />
<span style="color: #ff0000">READ</span> COMMITTED 不会 会 会 <br />
<span style="color: #ff0000">Read</span> Uncommitted 会 会 会 <br />
<br />
<br />
<br />
<br />
<br />
三、readOnly <br />
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。<br />
<br />
这是一个最优化提示。在一些情况下，一些事务策略能够起到显著的最优化效果，例如在使用Object<span style="color: #0000cc">/</span>Relational映射工具（如：Hibernate或TopLink）时避免dirty checking（试图&#8220;刷新&#8221;）。<br />
<br />
四、Timeout <br />
<br />
在事务属性中还有定义&#8220;timeout&#8221;值的选项，指定事务超时为几秒。在JTA中，这将被简单地传递到J2EE服务器的事务协调程序，并据此得到相应的解释。<br />
</span></code></p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/319596.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-04-28 14:30 <a href="http://www.blogjava.net/freeman1984/archive/2010/04/28/319596.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring  execution 表达式</title><link>http://www.blogjava.net/freeman1984/archive/2010/02/25/313886.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Thu, 25 Feb 2010 06:35:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/02/25/313886.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/313886.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/02/25/313886.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/313886.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/313886.html</trackback:ping><description><![CDATA[<p>execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)<br />
除了返回类型模式（上面代码片断中的ret-type-pattern），名字模式和参数模式以外，所有的部分都是可选的。 返回类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是 *，它代表了匹配任意的返回类型。 一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。 你可以使用 * 通配符作为所有或者部分命名模式。 参数模式稍微有点复杂：() 匹配了一个不接受任何参数的方法， 而 (..) 匹配了一个接受任意数量参数的方法（零或者更多）。 模式 (*) 匹配了一个接受一个任何类型的参数的方法。 模式 (*,String) 匹配了一个接受两个参数的方法，第一个可以是任意类型，第二个则必须是String类型。</p>
<p>下面给出一些常见切入点表达式的例子。</p>
<p>任意公共方法的执行：<br />
execution(public * *(..)) <br />
任何一个以&#8220;set&#8221;开始的方法的执行：<br />
execution(* set*(..)) <br />
AccountService 接口的任意方法的执行：<br />
execution(* com.xyz.service.AccountService.*(..)) <br />
定义在service包里的任意方法的执行：<br />
execution(* com.xyz.service.*.*(..)) <br />
定义在service包或者子包里的任意方法的执行：<br />
execution(* com.xyz.service..*.*(..)) <br />
在service包里的任意连接点（在Spring AOP中只是方法执行） ：<br />
within(com.xyz.service.*) <br />
在service包或者子包里的任意连接点（在Spring AOP中只是方法执行） ：<br />
within(com.xyz.service..*) <br />
实现了 AccountService 接口的代理对象的任意连接点（在Spring AOP中只是方法执行） ：<br />
this(com.xyz.service.AccountService)<br />
'this'在binding form中用的更多：- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。 <br />
实现了 AccountService 接口的目标对象的任意连接点（在Spring AOP中只是方法执行） ：<br />
target(com.xyz.service.AccountService)<br />
'target'在binding form中用的更多：- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。 <br />
任何一个只接受一个参数，且在运行时传入的参数实现了 Serializable 接口的连接点 （在Spring AOP中只是方法执行） <br />
args(java.io.Serializable)<br />
'args'在binding form中用的更多：- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。 请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable))： args只有在动态运行时候传入参数是可序列化的（Serializable）才匹配，而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。 <br />
有一个 @Transactional 注解的目标对象中的任意连接点（在Spring AOP中只是方法执行） <br />
@target(org.springframework.transaction.annotation.Transactional)<br />
'@target' 也可以在binding form中使用：请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。 <br />
任何一个目标对象声明的类型有一个 @Transactional 注解的连接点（在Spring AOP中只是方法执行）<br />
@within(org.springframework.transaction.annotation.Transactional)<br />
'@within'也可以在binding form中使用：- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。 <br />
任何一个执行的方法有一个 @Transactional annotation的连接点（在Spring AOP中只是方法执行） <br />
@annotation(org.springframework.transaction.annotation.Transactional)<br />
'@annotation' 也可以在binding form中使用：- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。 <br />
任何一个接受一个参数，并且传入的参数在运行时的类型实现了 @Classified annotation的连接点（在Spring AOP中只是方法执行） <br />
@args(com.xyz.security.Classified) </p>
<p><br />
本文来自CSDN博客，http://blog.csdn.net/terryzero/archive/2009/04/27/4128858.aspx</p>
 <img src ="http://www.blogjava.net/freeman1984/aggbug/313886.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-02-25 14:35 <a href="http://www.blogjava.net/freeman1984/archive/2010/02/25/313886.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ActiveMQ</title><link>http://www.blogjava.net/freeman1984/archive/2010/01/29/311178.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Fri, 29 Jan 2010 02:14:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/29/311178.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/311178.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/29/311178.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/311178.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/311178.html</trackback:ping><description><![CDATA[<p>企业中各项目中相互协作的时候可能用得到消息通知机制。比如有东西更新了，可以通知做索引。</p>
<p>在 Java 里有 JMS 的多个实现。其中 apache 下的 ActiveMQ 就是不错的选择。还有一个比较热的是 RabbitMQ （是 erlang 语言实现的）。这里示例下使用 ActiveMQ</p>
<p>用 ActiveMQ 最好还是了解下 JMS</p>
<table border="2">
    <tbody>
        <tr>
            <td><strong>JMS 公共</strong></td>
            <td><strong>点对点域</strong></td>
            <td><strong>发布/订阅域</strong></td>
        </tr>
        <tr>
            <td>ConnectionFactory</td>
            <td>QueueConnectionFactory</td>
            <td>TopicConnectionFactory</td>
        </tr>
        <tr>
            <td>Connection</td>
            <td>QueueConnection</td>
            <td>TopicConnection</td>
        </tr>
        <tr>
            <td>Destination</td>
            <td>Queue</td>
            <td>Topic</td>
        </tr>
        <tr>
            <td>Session</td>
            <td>QueueSession</td>
            <td>TopicSession</td>
        </tr>
        <tr>
            <td>MessageProducer</td>
            <td>QueueSender</td>
            <td>TopicPublisher</td>
        </tr>
        <tr>
            <td>MessageConsumer</td>
            <td>QueueReceiver</td>
            <td>TopicSubscriber</td>
        </tr>
    </tbody>
</table>
<p>JMS 定义了两种方式：Quere（点对点）；Topic（发布/订阅）。</p>
<p>ConnectionFactory 是连接工厂，负责创建Connection。</p>
<p>Connection 负责创建 Session。</p>
<p>Session 创建 MessageProducer（用来发消息） 和 MessageConsumer（用来接收消息）。</p>
<p>Destination 是消息的目的地。</p>
<p>详细的可以网上找些 JMS 规范（有中文版）。</p>
<p>下载 apache-activemq-5.3.0。<a href="http://activemq.apache.org/download.html" target="_blank">http://activemq.apache.org/download.html</a>，解压，然后双击 bin/activemq.bat。运行后，可以在 <a href="http://localhost:8161/admin" target="_blank">http://localhost:8161/admin</a> 观察。也有 demo， <a href="http://localhost:8161/demo" target="_blank">http://localhost:8161/demo</a>。把 activemq-all-5.3.0.jar 加入 classpath。</p>
<p>Jms 发送 代码：</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ConnectionFactory&nbsp;connectionFactory&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ActiveMQConnectionFactory(); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;connection&nbsp;=&nbsp;connectionFactory.createConnection(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;connection.start(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session&nbsp;=&nbsp;connection.createSession(Boolean.TRUE,&nbsp;Session.AUTO_ACKNOWLEDGE); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Destination&nbsp;destination&nbsp;=&nbsp;session.createQueue(</span><span class="string">"my-queue"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;MessageProducer&nbsp;producer&nbsp;=&nbsp;session.createProducer(destination); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>(</span><span class="keyword">int</span><span>&nbsp;i=</span><span class="number">0</span><span>;&nbsp;i&lt;</span><span class="number">3</span><span>;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MapMessage&nbsp;message&nbsp;=&nbsp;session.createMapMessage(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message.setLong(</span><span class="string">"count"</span><span>,&nbsp;</span><span class="keyword">new</span><span>&nbsp;Date().getTime()); &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span class="number">1000</span><span>); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//通过消息生产者发出消息 </span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;producer.send(message); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;session.commit(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;session.close(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;connection.close(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">public static void main(String[] args) throws Exception {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("my-queue");
MessageProducer producer = session.createProducer(destination);
for(int i=0; i&lt;3; i++) {
MapMessage message = session.createMapMessage();
message.setLong("count", new Date().getTime());
Thread.sleep(1000);
//通过消息生产者发出消息
producer.send(message);
}
session.commit();
session.close();
connection.close();
}
</pre>
<p>Jms 接收代码：</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ConnectionFactory&nbsp;connectionFactory&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ActiveMQConnectionFactory(); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;connection&nbsp;=&nbsp;connectionFactory.createConnection(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;connection.start(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">final</span><span>&nbsp;Session&nbsp;session&nbsp;=&nbsp;connection.createSession(Boolean.TRUE,&nbsp;Session.AUTO_ACKNOWLEDGE); &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Destination&nbsp;destination&nbsp;=&nbsp;session.createQueue(</span><span class="string">"my-queue"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;MessageConsumer&nbsp;consumer&nbsp;=&nbsp;session.createConsumer(destination); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/*//listener&nbsp;方式 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;consumer.setMessageListener(new&nbsp;MessageListener()&nbsp;{ </span>&nbsp;</span></li>
    <li class="alt"><span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onMessage(Message&nbsp;msg)&nbsp;{ </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MapMessage&nbsp;message&nbsp;=&nbsp;(MapMessage)&nbsp;msg; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//TODO&nbsp;something.... </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("收到消息："&nbsp;+&nbsp;new&nbsp;Date(message.getLong("count"))); </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.commit(); </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} </span>&nbsp;</span></li>
    <li class=""><span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;}); </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(30000); </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;i=</span><span class="number">0</span><span>; &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>(i&lt;</span><span class="number">3</span><span>)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MapMessage&nbsp;message&nbsp;=&nbsp;(MapMessage)&nbsp;consumer.receive(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.commit(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//TODO&nbsp;something.... </span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"收到消息："</span><span>&nbsp;+&nbsp;</span><span class="keyword">new</span><span>&nbsp;Date(message.getLong(</span><span class="string">"count"</span><span>))); &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;session.close(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;connection.close(); &nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">public static void main(String[] args) throws Exception {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
Connection connection = connectionFactory.createConnection();
connection.start();
final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("my-queue");
MessageConsumer consumer = session.createConsumer(destination);
/*//listener 方式
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message msg) {
MapMessage message = (MapMessage) msg;
//TODO something....
System.out.println("收到消息：" + new Date(message.getLong("count")));
session.commit();
}
});
Thread.sleep(30000);
*/
int i=0;
while(i&lt;3) {
i++;
MapMessage message = (MapMessage) consumer.receive();
session.commit();
//TODO something....
System.out.println("收到消息：" + new Date(message.getLong("count")));
}
session.close();
connection.close();
}
</pre>
<p>启动 JmsReceiver 和 JmsSender 可以在看输出三条时间信息。当然 Jms 还指定有其它格式的数据，如 TextMessage </p>
<p>结合 Spring 的 JmsTemplate 方便用：</p>
<p>xml：</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"UTF-8"</span><span class="tag">?&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span class="tag">&lt;</span><span class="tag-name">beans</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://www.springframework.org/schema/beans"</span><span>&nbsp;</span><span class="attribute">xmlns:xsi</span><span>=</span><span class="attribute-value">"http://www.w3.org/2001/XMLSchema-instance"</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">xsi:schemaLocation</span><span>=</span><span class="attribute-value">"http://www.springframework.org/schema/beans&nbsp;http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&lt;!--&nbsp;在非&nbsp;web&nbsp;/&nbsp;ejb&nbsp;容器中使用&nbsp;pool&nbsp;时，要手动&nbsp;stop，spring&nbsp;不会为你执行&nbsp;destroy-method&nbsp;的方法 &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"jmsFactory"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.apache.activemq.pool.PooledConnectionFactory"</span><span>&nbsp;</span><span class="attribute">destroy-method</span><span>=</span><span class="attribute-value">"stop"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"connectionFactory"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.apache.activemq.ActiveMQConnectionFactory"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"brokerURL"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"tcp://localhost:61616"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>--</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"jmsFactory"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.apache.activemq.ActiveMQConnectionFactory"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"brokerURL"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"tcp://localhost:61616"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"jmsTemplate"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.jms.core.JmsTemplate"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"connectionFactory"</span><span>&nbsp;</span><span class="attribute">ref</span><span>=</span><span class="attribute-value">"jmsFactory"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"defaultDestination"</span><span>&nbsp;</span><span class="attribute">ref</span><span>=</span><span class="attribute-value">"destination"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"messageConverter"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.jms.support.converter.SimpleMessageConverter"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"destination"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.apache.activemq.command.ActiveMQQueue"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">constructor-arg</span><span>&nbsp;</span><span class="attribute">index</span><span>=</span><span class="attribute-value">"0"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"my-queue"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span class="tag">&lt;/</span><span class="tag-name">beans</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt;
&lt;!-- 在非 web / ejb 容器中使用 pool 时，要手动 stop，spring 不会为你执行 destroy-method 的方法
&lt;bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"&gt;
&lt;property name="connectionFactory"&gt;
&lt;bean class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;property name="brokerURL" value="tcp://localhost:61616" /&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;/bean&gt;
--&gt;
&lt;bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;property name="brokerURL" value="tcp://localhost:61616" /&gt;
&lt;/bean&gt;
&lt;bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"&gt;
&lt;property name="connectionFactory" ref="jmsFactory" /&gt;
&lt;property name="defaultDestination" ref="destination" /&gt;
&lt;property name="messageConverter"&gt;
&lt;bean class="org.springframework.jms.support.converter.SimpleMessageConverter" /&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"&gt;
&lt;constructor-arg index="0" value="my-queue" /&gt;
&lt;/bean&gt;
&lt;/beans&gt;
</pre>
<p>sender：</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;ctx&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileSystemXmlApplicationContext(</span><span class="string">"classpath:app*.xml"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;JmsTemplate&nbsp;jmsTemplate&nbsp;=&nbsp;(JmsTemplate)&nbsp;ctx.getBean(</span><span class="string">"jmsTemplate"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;jmsTemplate.send(</span><span class="keyword">new</span><span>&nbsp;MessageCreator()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;Message&nbsp;createMessage(Session&nbsp;session)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;JMSException&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MapMessage&nbsp;mm&nbsp;=&nbsp;session.createMapMessage(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mm.setLong(</span><span class="string">"count"</span><span>,&nbsp;</span><span class="keyword">new</span><span>&nbsp;Date().getTime()); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;mm; &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:app*.xml");
JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");
jmsTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
MapMessage mm = session.createMapMessage();
mm.setLong("count", new Date().getTime());
return mm;
}
});
}
</pre>
<p>receiver：</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;ctx&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileSystemXmlApplicationContext(</span><span class="string">"classpath:app*.xml"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;JmsTemplate&nbsp;jmsTemplate&nbsp;=&nbsp;(JmsTemplate)&nbsp;ctx.getBean(</span><span class="string">"jmsTemplate"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>(</span><span class="keyword">true</span><span>)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map&lt;String,&nbsp;Object&gt;&nbsp;mm&nbsp;=&nbsp;&nbsp;(Map&lt;String,&nbsp;Object&gt;)&nbsp;jmsTemplate.receiveAndConvert(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"收到消息："</span><span>&nbsp;+&nbsp;</span><span class="keyword">new</span><span>&nbsp;Date((Long)mm.get(</span><span class="string">"count"</span><span>))); &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:app*.xml");
JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");
while(true) {
Map&lt;String, Object&gt; mm =  (Map&lt;String, Object&gt;) jmsTemplate.receiveAndConvert();
System.out.println("收到消息：" + new Date((Long)mm.get("count")));
}
}
</pre>
<p>注意：直接用 Jms 接口时接收了消息后要提交一下，否则下次启动接收者时还可以收到旧数据。有了 JmsTemplate 就不用自己提交 session.commit() 了。如果使用了 PooledConnectionFactory 要把 apache-activemq-5.3.0\lib\optional\activemq-pool-5.3.0.jar 加到 classpath</p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/311178.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-29 10:14 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/29/311178.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring cxf</title><link>http://www.blogjava.net/freeman1984/archive/2010/01/28/311098.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Thu, 28 Jan 2010 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/28/311098.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/311098.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/28/311098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/311098.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/311098.html</trackback:ping><description><![CDATA[<font style="background-color: #cce8cf">例子可照做<font style="background-color: #cce8cf"><a href="http://www.ibm.com/developerworks/cn/webservices/ws-pojo-springcxf/">http://www.ibm.com/developerworks/cn/webservices/ws-pojo-springcxf/</a></font><br />主要是jar包和jdk 要不一大堆错误就郁闷死了<br />jak 1.6 update04以上<br />jar包：<br /></font><br />
<p><font style="background-color: #cce8cf">以下的 jar 包是所有 CXF 项目所必需的：</font></p>
<p><font style="background-color: #cce8cf">cxf.jar <br />commons-logging.jar <br />geronimo-activation.jar (Or the Sun equivalent) <br />geronimo-annotation.jar (Or the Sun equivalent) <br />geronimo-javamail.jar (Or the Sun equivalent) <br />neethi.jar <br />jaxb-api.jar <br />jaxb-impl.jar <br />stax-api.jar <br />XmlSchema.jar <br />wstx-asl.jar <br />xml-resolver.jar </font></p>
<p>具体可见<font style="background-color: #cce8cf"><a href="http://blog.csdn.net/yyh30/archive/2008/09/19/2952145.aspx">http://blog.csdn.net/yyh30/archive/2008/09/19/2952145.aspx</a>或者<br /><a href="http://blog.csdn.net/sz_bdqn/article/details/6737931">http://blog.csdn.net/sz_bdqn/article/details/6737931</a><br /></font>no spring <a href="http://zzxanadu.iteye.com/blog/542249">http://zzxanadu.iteye.com/blog/542249</a><br /><font style="background-color: #cce8cf"><br /></font></p><img src ="http://www.blogjava.net/freeman1984/aggbug/311098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-28 17:40 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/28/311098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>phprcp 以及和spring的集成</title><link>http://www.blogjava.net/freeman1984/archive/2010/01/28/311005.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Thu, 28 Jan 2010 02:50:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/28/311005.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/311005.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/28/311005.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/311005.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/311005.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p><span class="first-word">PHPRPC</span> 是一个轻型的、安全的、跨网际的、跨语言的、跨平台的、跨环境的、跨域的、支持复杂对象传输的、支持引用参数传递的、支持内容输出重定向的、支持分级错误处理的、支持会话的、面向服务的高性能远程过程调用协议。<br />
<br />
</p>
通过两个例子来简单入门下：<br />
下载：<a href="http://www.phprpc.org/download/phprpc_3.0.2_java.zip" target="_blank">PHPRPC 3.0.2 for Java</a>&nbsp;, 当然要使用3.0.2 在这之前不支持集合类型，然后双击make.bat生成服务与客户端（当然环境变量要设置的，老在myeclipse里开发，从来不设置，这下又敲半天。），生成phprpc.jar和phprpc_client.jar还有<font style="background-color: #cce8cf">phprpc_spring.jar </font>3个jar，在没有集成spring的时候将phprpc.jar和phprpc_client.jar分别放到服务端可客户端的lib下<br />
1，servlet（或者jsp）模式：<br />
首先建立接口：
<p>public interface Hello {</p>
<p>&nbsp;public String sayHi(String name);<br />
&nbsp;public TestPo getPo(TestPo po);<br />
&nbsp;public List&lt;TestPo&gt; getPos(List&lt;TestPo&gt; pos);</p>
实现：<br />
<p>public class HelloImpl implements Hello {</p>
<p>&nbsp;public String sayHi(String name) {<br />
&nbsp;&nbsp;// TODO Auto-generated method stub<br />
&nbsp;&nbsp;return "Hi,"+name;<br />
&nbsp;}<br />
&nbsp;public TestPo getPo(TestPo po) {<br />
&nbsp;&nbsp;System.out.println("client :"+po.toString());<br />
&nbsp;&nbsp;return new TestPo("server name", "server address");<br />
&nbsp;}<br />
&nbsp;public List&lt;TestPo&gt; getPos(List&lt;TestPo&gt; pos) {<br />
&nbsp;&nbsp;List&lt;TestPo&gt; ps = new ArrayList&lt;TestPo&gt;();<br />
&nbsp;&nbsp;for (int i = 0; i &lt; pos.size(); i++) {<br />
&nbsp;&nbsp;&nbsp;ps.add(new TestPo("server name_"+i,"server address_"+i));<br />
&nbsp;&nbsp;&nbsp;System.out.println(pos.get(i).toString());<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;return ps;<br />
&nbsp;}</p>
Testpo.java 需要序列化<br />
<p>public class TestPo implements Serializable{</p>
<p>&nbsp;private static final long serialVersionUID = 1L;<br />
&nbsp;private String name;<br />
&nbsp;private String address;<br />
&nbsp;public TestPo(String name, String address) {<br />
&nbsp;&nbsp;super();<br />
&nbsp;&nbsp;this.name = name;<br />
&nbsp;&nbsp;this.address = address;<br />
&nbsp;}<br />
&nbsp;public String getName() {<br />
&nbsp;&nbsp;return name;<br />
&nbsp;}<br />
&nbsp;public void setName(String name) {<br />
&nbsp;&nbsp;this.name = name;<br />
&nbsp;}<br />
&nbsp;public String getAddress() {<br />
&nbsp;&nbsp;return address;<br />
&nbsp;}<br />
&nbsp;public void setAddress(String address) {<br />
&nbsp;&nbsp;this.address = address;<br />
&nbsp;}<br />
&nbsp;@Override<br />
&nbsp;public String toString() {<br />
&nbsp;&nbsp;return "TestPo [address=" + address + ", name=" + name + "]";<br />
&nbsp;}<br />
&nbsp;<br />
}</p>
服务类：<br />
<p>public class PHPrcpServer extends HttpServlet {</p>
<p><br />
&nbsp;@Override<br />
&nbsp;protected void service(HttpServletRequest request, HttpServletResponse response)<br />
&nbsp;&nbsp;&nbsp;throws ServletException, IOException {<br />
&nbsp;&nbsp;// TODO Auto-generated method stub<br />
&nbsp;&nbsp;Hello hello = new HelloImpl();&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;PHPRPC_Server phprpc_server = new PHPRPC_Server();&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;phprpc_server.add(hello);&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;phprpc_server.start(request, response);&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;}</p>
<p><br />
}<br />
配置：<br />
&lt;servlet&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;PHPrcpServer&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;com.server.phprcp.PHPrcpServer&lt;/servlet-class&gt;<br />
&nbsp; &lt;/servlet&gt;<br />
&lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;PHPrcpServer&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/servlet/PHPrcpServer&lt;/url-pattern&gt;<br />
&nbsp; &lt;/servlet-mapping&gt;&nbsp; <br />
客户端：<br />
PHPRPC_Client client = new PHPRPC_Client("http://localhost:8080/serverspring/servlet/PHPrcpServer");&nbsp; <br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hello m = (Hello) client.useService(Hello.class);&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(m.sayHi("chenlb")); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TestPo po = m.getPo(new TestPo("clent name","client address"));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(po.toString());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;TestPo&gt; pcs = new ArrayList&lt;TestPo&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; 20; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;TestPo poc = new TestPo("client_name_"+i,"client_address_"+i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;pcs.add(poc);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;TestPo&gt; pl = m.getPos(pcs);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; pl.size(); i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(pl.get(i).toString());<br />
&nbsp;&nbsp;&nbsp;}</p>
<span style="color: red">2 于spring的集成：<br />
</span>当然需要spring.jar spring-webmvc.jar 还有<font style="background-color: #cce8cf">phprpc_spring.jar </font><br />
&nbsp;1建立web项目导入相关的包。<br />
&nbsp;2，配置web.xml 当然如果你以前在spring里配置过rmi，<font style="background-color: #cce8cf">Hessian</font>，httpinvoker，ws，你也许知道这一步如何配置：<br />
<font style="background-color: #cce8cf">&lt;context-param&gt;<br />
&nbsp;&nbsp;&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br />
&nbsp;&nbsp;&lt;param-value&gt;<br />
&nbsp;&nbsp;&nbsp;classpath:applicationContext-*.xml<br />
&nbsp;&nbsp;&lt;/param-value&gt;<br />
&nbsp;&lt;/context-param&gt;<br />
&nbsp; &lt;listener&gt;<br />
&nbsp;&nbsp;&lt;listener-class&gt;<br />
&nbsp;&nbsp;&nbsp;org.springframework.web.context.ContextLoaderListener<br />
&nbsp;&nbsp;&lt;/listener-class&gt;<br />
&nbsp;&lt;/listener&gt;<br />
&nbsp;&lt;servlet&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;remote&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />
&nbsp;&lt;/servlet&gt;<br />
&nbsp;&lt;servlet-mapping&gt;<br />
&nbsp;&nbsp; &lt;servlet-name&gt;remote&lt;/servlet-name&gt;<br />
&nbsp;&nbsp; &lt;url-pattern&gt;/remoteserver/*&lt;/url-pattern&gt;<br />
&nbsp;&lt;/servlet-mapping&gt;<br />
<br />
上文的接口和实现类不变，当然对list map都是支持的（测试通过） 这里只做了string<br />
在server端发布服务：<br />
当然是在web-inf 下面建立remote-servlet.xml<br />
内容：<br />
<font style="background-color: #cce8cf">&lt;bean name="phps" class="接口实现"/&gt;<br />
&nbsp;&lt;bean name="/phpremote" class="org.phprpc.spring.remoting.PHPRPC_Exporter"&gt;//当然可以看出 phprcp实现了spring 对remote的通用接口 <br />
&nbsp; &lt;property name="service" ref="phps"/&gt;<br />
&nbsp; &lt;property name="serviceInterface" value="接口"/&gt;<br />
&nbsp;&lt;/bean&gt;<br />
配置tomcat 启动后服务就启动了，<br />
3客户端：客户端使用java项目 当然也可以是web项目<br />
添加spring.jar&nbsp; spring-webmvc.jar <br />
配置客户端：<br />
<font style="background-color: #cce8cf">&lt;bean name="phprcp" class="org.phprpc.spring.remoting.PHPRPC_ProxyFactoryBean"&gt;<br />
&nbsp;&lt;property name="serviceUrl" value="http://localhost:8080/sall/remoteserver/phpremote"/&gt;<br />
&nbsp;&lt;property name="serviceInterface" value="接口"/&gt;<br />
&lt;/bean&gt;</font><br />
</font>将服务端的接口copy过来，保持包结构不变。<br />
测试：<br />
<font style="background-color: #cce8cf">ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-bean.xml");<br />
&nbsp;&nbsp;Hello phpRcpI = (Hello) context.getBean("phprcp");<br />
&nbsp;&nbsp;System.out.println(phpRcpI.sayHi("this is from phpclient..."));<br />
<br />
<br />
如果对复杂类型 当然&nbsp;<font style="background-color: #cce8cf">&nbsp;implements Serializable</font>是必须的，如同<font style="background-color: #cce8cf">Hessian</font>，<br />
</font>phphrcp效率还是不错的 ，内部序列化和反序列化机制有了优化，还是值得学习和应用的。<br />
</font>
<img src ="http://www.blogjava.net/freeman1984/aggbug/311005.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-28 10:50 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/28/311005.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hessian spring</title><link>http://www.blogjava.net/freeman1984/archive/2010/01/27/310999.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 27 Jan 2010 13:42:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/27/310999.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/310999.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/27/310999.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/310999.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/310999.html</trackback:ping><description><![CDATA[<p>简介 <br />
相比WebService，Hessian更简单、快捷。采用的是二进制RPC协议（Binary），因为采用的是二进制协议，所以它很适合于发送二进制数据。Hessian通常通过Web应用来提供服务，因此非常类似于WebService。只是它不使用SOAP协议。 <br />
Hessian通过Servlet提供远程服务。需要将匹配某个模式的请求映射到Hessian服务。Spring的DispatcherServlet可以完成该功能，DispatcherServlet可将匹配模式的请求转发到Hessian服务。Hessian的server端提供一个servlet基类, 用来处理发送的请求，而Hessian的这个远程过程调用，完全使用动态代理来实现的,，推荐采用面向接口编程，因此，Hessian服务建议通过接口暴露。 <br />
Hessian处理过程示意图： <br />
客户端——&gt;序列化写到输出流——&gt;远程方法（服务器端）——&gt;序列化写到输出流 ——&gt;客户端读取输入流——&gt;输出结果 <br />
环境搭建 <br />
Hessian的下载和安装请按如下步骤进行： <br />
（1）登http://www.caucho.com/hessian/下载Hessian。 <br />
（2）把Hessian相应的Jar包放到Web应用下，所有的jar文件都应该放在WEB-INF/lib下，该文件也不例外。 <br />
两种方式 <br />
纯Hessian <br />
这种方式主要是适用于工程中没有适用像spring框架的情况下，好处是配置方便，但是当内容多的情况下，配置的内容很多。 <br />
下面我就把我在做实例的一些相关步骤描述如下： <br />
1：把Hessian相应jar包放入至工程中。 <br />
2：由于Hessian是采用面向接口编程的，所以编写一个接口，因为客户端仅仅需要接口，而无须真实的实现类。 <br />
package jzh.demo; <br />
public interface IHello { <br />
String sayHello(); <br />
} <br />
3：编写一个类实现这个接口。 <br />
package jzh.demo.impl; <br />
import jzh.demo.IHello; <br />
import com.caucho.hessian.server.HessianServlet; <br />
public class Hello extends HessianServlet implements IHello { <br />
public String sayHello() { <br />
return "Hello world"; <br />
} <br />
} <br />
4：web.xml的详细配置 <br />
&lt;servlet&gt; <br />
&lt;servlet-name&gt;Hello&lt;/servlet-name&gt; <br />
&lt;servlet-class&gt;com.caucho.hessian.server.HessianServlet&lt;/servlet-class&gt; <br />
&lt;init-param&gt; <br />
&lt;param-name&gt;home-class&lt;/param-name&gt; <br />
&lt;param-value&gt;jzh.demo.imple.Hello&lt;/param-value&gt; <br />
&lt;/init-param&gt; <br />
&lt;init-param&gt; <br />
&lt;param-name&gt;home-api&lt;/param-name&gt; <br />
&lt;param-value&gt;jzh.demo.IHello&lt;/param-value&gt; <br />
&lt;/init-param&gt; <br />
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt; <br />
&lt;/servlet&gt; <br />
<br />
&lt;servlet-mapping&gt; <br />
&lt;servlet-name&gt;Hello&lt;/servlet-name&gt; <br />
&lt;url-pattern&gt;/Hello&lt;/url-pattern&gt; <br />
&lt;/servlet-mapping&gt; <br />
<br />
5：客户端远程调用服务器端提供的接口，利用的就是Hessian的HessianProxyFactory，来实现远程代理。 <br />
1） 把服务器端的生成的jar包，放入工程中。 <br />
2） 相应的片段程序如下： <br />
String url = "http://220.114.108.185:8080/Hessian/Hello"; <br />
HessianProxyFactory factory = new HessianProxyFactory(); <br />
try { <br />
IHello hello =(IHello)factory.create(IHello.class,url); <br />
System.out.println(hello.sayHello()); <br />
} catch (MalformedURLException e) { <br />
e.printStackTrace(); <br />
} <br />
6：功能完成。 <br />
Hessian与Spring整合 <br />
相比上一种方式，这个方式就有点麻烦了。Hessian通过Servlet提供远程服务。需要将匹配某个模式的请求映射到Hessian服务。Spring的DispatcherServlet可以完成该功能，DispatcherServlet可将匹配模式的请求转发到Hessian服务，web.xml只是定义了&#8220;请求转发器&#8221;，该转发器将匹配/remoting/*的请求截获，转发给context的bean处理。而HessianServiceExporter提供bean服务。 <br />
所以Hessian与Spring整合主要就是一下两个工作： <br />
1：通过DispatcherServlet来拦截URL请求。 <br />
2：HessianServiceExporter提供bean服务，Spring使用HessianServiceExporter，将一个常规bean导出成Hessian服务。 <br />
下面我就把我在做实例的一些相关步骤描述如下： <br />
1：和上面的一样。 <br />
2：和上面的一样。 <br />
3：和上面的一样。 <br />
4：web.xml的详细配置 <br />
&lt;servlet&gt; <br />
&lt;servlet-name&gt;remoting&lt;/servlet-name&gt; <br />
&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt; <br />
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt; <br />
&lt;/servlet&gt; <br />
&lt;servlet-mapping&gt; <br />
&lt;servlet-name&gt;remoting&lt;/servlet-name&gt; <br />
&lt;url-pattern&gt;/remoting/*&lt;/url-pattern&gt; <br />
&lt;/servlet-mapping&gt; <br />
5：配置remoting-servlet.xml文件 <br />
&lt;!-- 定义普通bean实例--&gt; <br />
&lt;bean id="hello" class="jzh.demospring.impl.Hello"/&gt; <br />
&lt;!-- 使用HessianServiceExporter 将普通bean导出成Hessian服务--&gt; <br />
&lt;bean name="/HessianRemoting" class="org.springframework.remoting.caucho.HessianServiceExporter"&gt; <br />
&lt;!-- 需要导出的目标bean--&gt; <br />
&lt;property name="service" ref="hello"/&gt; <br />
&lt;!-- Hessian服务的接口--&gt; <br />
&lt;property name="serviceInterface" value="jzh.demospring.IHello"/&gt; <br />
&lt;/bean&gt; <br />
6：客户端定义一个remote-client.xml文件 <br />
&lt;bean id="myServiceClient" class="org.springframework.remoting.caucho.HessianProxyFactoryBean"&gt; <br />
&lt;property name="serviceUrl"&gt; <br />
&lt;value&gt;http://220.114.99.62:8080/HessianSpring/remoteing/HessianRemoting&lt;/value&gt; <br />
&lt;/property&gt; <br />
&lt;property name="serviceInterface"&gt; <br />
&lt;value&gt;jzh.demospring.IHello&lt;/value&gt; <br />
&lt;/property&gt; <br />
&lt;/bean&gt; <br />
7：客户端调用。 <br />
try <br />
{ <br />
ApplicationContext context = new ClassPathXmlApplicationContext("remote-client.xml"); <br />
<br />
IHello hello =(IHello)context.getBean("myServiceClient"); <br />
<br />
System.out.println(hello.sayHello()); <br />
} <br />
catch (Exception e) <br />
{ <br />
e.printStackTrace(); <br />
} <br />
转载自：http://hi.baidu.com/javahua/blog/item/289e4a66c50a152dab184cec.html</p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/310999.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-27 21:42 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/27/310999.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring rmi例子</title><link>http://www.blogjava.net/freeman1984/archive/2010/01/27/310996.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 27 Jan 2010 13:07:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/27/310996.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/310996.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/27/310996.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/310996.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/310996.html</trackback:ping><description><![CDATA[首先是服务端：<br />
接口和实现<br />
<p>public interface ServerRmiI {</p>
<p>&nbsp;public String sayHi(String name);<br />
}<br />
</p>
<br />
<p>public class ServerRmiImpl implements ServerRmiI{</p>
<p>&nbsp;public String sayHi(String name) {<br />
&nbsp;&nbsp;// TODO Auto-generated method stub<br />
&nbsp;&nbsp;return "Hi,"+name;<br />
&nbsp;}</p>
<p>}</p>
配置：<br />
&lt;?xml version="1.0" encoding="utf-8"?&gt;<br />
&lt;beans xmlns="http://www.springframework.org/schema/beans"<br />
&nbsp;&nbsp;&nbsp; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />
&nbsp;&nbsp;&nbsp; xmlns:context="http://www.springframework.org/schema/context"<br />
&nbsp;&nbsp;&nbsp; xsi:schemaLocation="http://www.springframework.org/schema/beans <br />
&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />
&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context <br />
&nbsp;http://www.springframework.org/schema/context/spring-context-2.5.xsd"<br />
&nbsp;&nbsp;&nbsp; default-autowire="byName" default-lazy-init="true"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean name="rmiserver" class="com.server.ServerRmiImpl"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean name="serverTest" class="org.springframework.remoting.rmi.RmiServiceExporter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="service" ref="rmiserver"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceName" value="serverRmiTest"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceInterface" value="com.server.ServerRmiI"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="registryPort" value="1021"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
&lt;/beans&gt;<br />
<br />
启动：<br />
public static void main(String[] args) {<br />
&nbsp;&nbsp;ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-bean.xml");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.getBean("serverTest");&nbsp;<br />
&nbsp;}<br />
看见如下信息就代表成功了：<br />
信息: Binding service 'serverRmiTest' to RMI registry: RegistryImpl[UnicastServerRef [liveRef: [endpoint:[yourhost:1021](local),objID:[0:0:0, 0]]]]<br />
客户端：<br />
配置：<br />
&lt;?xml version="1.0" encoding="utf-8"?&gt;<br />
&lt;beans xmlns="http://www.springframework.org/schema/beans"<br />
&nbsp;&nbsp;&nbsp; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />
&nbsp;&nbsp;&nbsp; xmlns:context="http://www.springframework.org/schema/context"<br />
&nbsp;&nbsp;&nbsp; xsi:schemaLocation="http://www.springframework.org/schema/beans <br />
&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />
&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context <br />
&nbsp;http://www.springframework.org/schema/context/spring-context-2.5.xsd"<br />
&nbsp;&nbsp;&nbsp; default-autowire="byName" default-lazy-init="true"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean name="clentrmi" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceUrl" value="rmi://yourhost:1021/serverRmiTest"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceInterface" value="com.server.ServerRmiI"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
&lt;/beans&gt;<br />
<br />
测试类：<br />
public static void main(String[] args) {<br />
&nbsp;&nbsp;ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-bean.xml");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServerRmiI rmiI = (ServerRmiI) context.getBean("clentrmi");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(rmiI.sayHi("rmi"));<br />
&nbsp;}<br />
打印：Hi,rmi
<img src ="http://www.blogjava.net/freeman1984/aggbug/310996.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-27 21:07 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/27/310996.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring httpinvoker 例子</title><link>http://www.blogjava.net/freeman1984/archive/2010/01/27/310964.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 27 Jan 2010 08:33:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/27/310964.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/310964.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/27/310964.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/310964.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/310964.html</trackback:ping><description><![CDATA[<p><font style="background-color: #cce8cf">1,创建接口：</p>
<p><font style="background-color: #cce8cf">public interface HttpInvokerTestI {</font></p>
<p><font style="background-color: #cce8cf">&nbsp;public TestPo getTestPo(String desp);<br />
}<br />
</font></p>
<br />
实现：<br />
<br />
<p><font style="background-color: #cce8cf">public class HttpInvokertestImpl implements HttpInvokerTestI {</font></p>
<p><font style="background-color: #cce8cf">&nbsp;@Override<br />
&nbsp;public TestPo getTestPo(String desp) {<br />
&nbsp;&nbsp;// TODO Auto-generated method stub<br />
&nbsp;&nbsp;return new TestPo(desp);<br />
&nbsp;}</font></p>
<p><font style="background-color: #cce8cf">}</font></p>
<p><br />
配置：在web info下添加<font style="background-color: #cce8cf">remote-servlet.xml</font><br />
<br />
内容：<br />
<br />
<font style="background-color: #cce8cf">&nbsp;&lt;bean name="httpinvokertest" class="ztest.httpinvoke.HttpInvokertestImpl"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean name="/hit" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="service" ref="httpinvokertest"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceInterface" value="ztest.httpinvoke.HttpInvokerTestI"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</font></p>
<p>添加spring.jar spring-webmvc.jar(配置dispacherServlet用)<br />
web.xml 添加对context和servlet的支持：<br />
<br />
<font style="background-color: #cce8cf">&lt;context-param&gt;<br />
&nbsp;&nbsp;&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br />
&nbsp;&nbsp;&lt;param-value&gt;<br />
&nbsp;&nbsp;&nbsp;classpath:applicationContext-*.xml<br />
&nbsp;&nbsp;&lt;/param-value&gt;<br />
&nbsp;&lt;/context-param&gt;</font><br />
<font style="background-color: #cce8cf">&nbsp;&lt;listener&gt;<br />
&nbsp;&nbsp;&lt;listener-class&gt;<br />
&nbsp;&nbsp;&nbsp;org.springframework.web.context.ContextLoaderListener<br />
&nbsp;&nbsp;&lt;/listener-class&gt;<br />
&nbsp;&lt;/listener&gt;</font><br />
<br />
<br />
<font style="background-color: #cce8cf">&lt;servlet&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;remote&lt;/servlet-name&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;remote&lt;/servlet-name&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/remoting/*&lt;/url-pattern&gt;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;&nbsp; <br />
</font></p>
<p>客户端配置：<br />
<font style="background-color: #cce8cf"></p>
<p><font style="background-color: #cce8cf">&lt;bean id="remoteService"<br />
&nbsp;&nbsp;&nbsp; class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceUrl"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="http://localhost:8080/ssh/remoting/hit" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceInterface" value="com.s.httpinvoker.HttpInvokerTestI"/&gt;</font></p>
<p><font style="background-color: #cce8cf">&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</font></p>
<p>测试类：<br />
<font style="background-color: #cce8cf">public static void main(String[] args) {<br />
&nbsp;&nbsp;ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-bean.xml");<br />
&nbsp;&nbsp;HttpInvokerTestI httpInvokerTestI = (HttpInvokerTestI) context.getBean("remoteService");<br />
&nbsp;&nbsp;System.out.println(httpInvokerTestI.getTestPo("dddd").getDesp());<br />
&nbsp;&nbsp;<br />
&nbsp;}</font><br />
完成。<br />
</p>
</font></font>
<img src ="http://www.blogjava.net/freeman1984/aggbug/310964.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-27 16:33 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/27/310964.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring任务调度</title><link>http://www.blogjava.net/freeman1984/archive/2010/01/27/310942.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 27 Jan 2010 06:47:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/27/310942.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/310942.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/27/310942.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/310942.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/310942.html</trackback:ping><description><![CDATA[<span style="font-size: medium"><span style="color: red">简单的使用java Timer调度任务</span></span> <br />
首先写一个定时器任务类
<div class="dp-highlighter">
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.myspring.quartz; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;java.util.TimerTask; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;MyTimeTask&nbsp;</span><span class="keyword">extends</span><span>&nbsp;TimerTask&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;run()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"hello"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">package com.myspring.quartz;
import java.util.TimerTask;
public class MyTimeTask extends TimerTask {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("hello");
}
}</pre>
<br />
spring配置文件 <br />
<div class="dp-highlighter">
<div class="bar"><span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"UTF-8"</span><span class="tag">?&gt;</span><span>&nbsp;&nbsp;</span></span></div>
<ol class="dp-xml">
    <li><span class="tag">&lt;</span><span class="tag-name">beans</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://www.springframework.org/schema/beans"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">xmlns:xsi</span><span>=</span><span class="attribute-value">"http://www.w3.org/2001/XMLSchema-instance"</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">xmlns:p</span><span>=</span><span class="attribute-value">"http://www.springframework.org/schema/p"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">xsi:schemaLocation</span><span>=</span><span class="attribute-value">"http://www.springframework.org/schema/beans&nbsp;http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"timeTask"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.myspring.quartz.MyTimeTask"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"myTimeTask"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.timer.ScheduledTimerTask"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"timerTask"</span><span>&nbsp;</span><span class="attribute">ref</span><span>=</span><span class="attribute-value">"timeTask"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;指定任务运行周期,单位毫秒&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"period"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"1000"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;指定任务延时时间,即第一次运行之前等待时间,单位毫秒&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"delay"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"1000"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.timer.TimerFactoryBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"scheduledTimerTasks"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">ref</span><span>&nbsp;</span><span class="attribute">bean</span><span>=</span><span class="attribute-value">"myTimeTask"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="tag">&lt;/</span><span class="tag-name">beans</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt;
&lt;bean id="timeTask" class="com.myspring.quartz.MyTimeTask"&gt;&lt;/bean&gt;
&lt;bean id="myTimeTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"&gt;
&lt;property name="timerTask" ref="timeTask"&gt;&lt;/property&gt;
&lt;!-- 指定任务运行周期,单位毫秒 --&gt;
&lt;property name="period" value="1000"&gt;&lt;/property&gt;
&lt;!-- 指定任务延时时间,即第一次运行之前等待时间,单位毫秒 --&gt;
&lt;property name="delay" value="1000"&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean class="org.springframework.scheduling.timer.TimerFactoryBean"&gt;
&lt;property name="scheduledTimerTasks"&gt;
&lt;list&gt;
&lt;ref bean="myTimeTask"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/beans&gt;</pre>
<br />
局限性:Java Timer无法精确指定何时运行 <br />
<span style="font-size: medium"><span style="color: red">使用Quartz调度器</span></span> <br />
同Java Timer一样首先创建一个任务类MyQuartzJob.java <br />
<div class="dp-highlighter">
<div class="bar"><span><span class="keyword">package</span><span>&nbsp;com.myspring.quartz; &nbsp;&nbsp;</span></span></div>
<ol class="dp-j">
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.quartz.JobExecutionContext; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.quartz.JobExecutionException; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.springframework.scheduling.quartz.*; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;MyQuartzJob&nbsp;</span><span class="keyword">extends</span><span>&nbsp;QuartzJobBean{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">protected</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;executeInternal(JobExecutionContext&nbsp;arg0) &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">throws</span><span>&nbsp;JobExecutionException&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"方法调用"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">package com.myspring.quartz;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.*;
public class MyQuartzJob extends QuartzJobBean{
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
// TODO Auto-generated method stub
System.out.println("方法调用");
}
}</pre>
<br />
添加spring配置 <br />
<div class="dp-highlighter">
<div class="bar"><span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"quartzJob"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.quartz.JobDetailBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></div>
<ol class="dp-xml">
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"jobClass"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"com.myspring.quartz.MyQuartzJob"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;接受一个Map,其中包含了需要设置给jobClass的各种属性&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"jobDataAsMap"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">map</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">map</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"simplerTrigger"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.quartz.SimpleTriggerBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"jobDetail"</span><span>&nbsp;</span><span class="attribute">ref</span><span>=</span><span class="attribute-value">"quartzJob"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;设置延迟工作的第一次执行,单位毫秒&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"startDelay"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"1000"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;设置调度任务频度,单位毫秒&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"repeatInterval"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"1000"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">&lt;bean id="quartzJob" class="org.springframework.scheduling.quartz.JobDetailBean"&gt;
&lt;property name="jobClass" value="com.myspring.quartz.MyQuartzJob"&gt;&lt;/property&gt;
&lt;!-- 接受一个Map,其中包含了需要设置给jobClass的各种属性 --&gt;
&lt;property name="jobDataAsMap"&gt;
&lt;map&gt;&lt;/map&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="simplerTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"&gt;
&lt;property name="jobDetail" ref="quartzJob"&gt;&lt;/property&gt;
&lt;!-- 设置延迟工作的第一次执行,单位毫秒 --&gt;
&lt;property name="startDelay" value="1000"&gt;&lt;/property&gt;
&lt;!-- 设置调度任务频度,单位毫秒 --&gt;
&lt;property name="repeatInterval" value="1000"&gt;&lt;/property&gt;
&lt;/bean&gt;</pre>
<br />
为了精确的控制调度工作,Quartz提供了cron工作 <br />
调度一个cron工作 <br />
例如,要在每天晚上11:59运行任务 <br />
可以如下配置spring配置 <br />
<div class="dp-highlighter">
<div class="bar"><span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"cronTrigger"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.quartz.CronTriggerBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></div>
<ol class="dp-xml">
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"jobDetail"</span><span>&nbsp;</span><span class="attribute">ref</span><span>=</span><span class="attribute-value">"quartzJob"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"cronExpression"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"0&nbsp;59&nbsp;23&nbsp;*&nbsp;*&nbsp;?"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">&lt;bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"&gt;
&lt;property name="jobDetail" ref="quartzJob"&gt;&lt;/property&gt;
&lt;property name="cronExpression" value="0 59 23 * * ?"&gt;&lt;/property&gt;&lt;/bean&gt;</pre>
<br />
<a href="http://blog.csdn.net/sfdev/archive/2009/03/02/3950640.aspx" target="_blank">我的主管写的cronExpression配置说明</a> <br />
最后启动工作,添加spring配置 <br />
<div class="dp-highlighter">
<div class="bar"><span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.quartz.SchedulerFactoryBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></div>
<ol class="dp-xml">
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;接受一组触发器,可以接受一个列表&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"triggers"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">ref</span><span>&nbsp;</span><span class="attribute">bean</span><span>=</span><span class="attribute-value">"simplerTrigger"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">ref</span><span>&nbsp;</span><span class="attribute">bean</span><span>=</span><span class="attribute-value">"cronTrigger"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">&lt;bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"&gt;
&lt;!-- 接受一组触发器,可以接受一个列表 --&gt;
&lt;property name="triggers"&gt;
&lt;list&gt;
&lt;ref bean="simplerTrigger"/&gt;
&lt;ref bean="cronTrigger"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;</pre>
<br />
使用org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean类,直接调度任务,而不用继承QuartzJobBean <br />
首先编写一个简单任务类MyQuartz.java <br />
<div class="dp-highlighter">
<div class="tools"><a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/487970#"></a>&nbsp;</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.myspring.quartz; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;MyQuartz&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;hello(){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"hello"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">package com.myspring.quartz;
public class MyQuartz {
public void hello(){
System.out.println("hello");
}
}</pre>
<br />
然后添加spring配置
<div class="dp-highlighter">
<div class="tools">&nbsp;</div>
<ol class="dp-xml">
    <li><span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"myQuartz"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.myspring.quartz.MyQuartz"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"newJob"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"targetObject"</span><span>&nbsp;</span><span class="attribute">ref</span><span>=</span><span class="attribute-value">"myQuartz"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"targetMethod"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"hello"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">&lt;bean id="myQuartz" class="com.myspring.quartz.MyQuartz"&gt;&lt;/bean&gt;
&lt;bean id="newJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"&gt;
&lt;property name="targetObject" ref="myQuartz"&gt;&lt;/property&gt;
&lt;property name="targetMethod" value="hello"&gt;&lt;/property&gt;
&lt;/bean&gt;</pre>
<br />
最后同理添加spring配置 <br />
<div class="dp-highlighter">
<div class="tools"><a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/487970#"></a>&nbsp;</div>
<ol class="dp-xml">
    <li><span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"simplerTrigger2"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.quartz.SimpleTriggerBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"jobDetail"</span><span>&nbsp;</span><span class="attribute">ref</span><span>=</span><span class="attribute-value">"newJob"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"startDelay"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"1000"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"repeatInterval"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"1000"</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.springframework.scheduling.quartz.SchedulerFactoryBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;接受一组触发器,可以接受一个列表&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"triggers"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">ref</span><span>&nbsp;</span><span class="attribute">bean</span><span>=</span><span class="attribute-value">"simplerTrigger2"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span>?&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<img src ="http://www.blogjava.net/freeman1984/aggbug/310942.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-27 14:47 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/27/310942.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Quartz任务调度CronTrigger配置格式详细说明 </title><link>http://www.blogjava.net/freeman1984/archive/2010/01/27/310928.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 27 Jan 2010 05:15:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/27/310928.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/310928.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/27/310928.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/310928.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/310928.html</trackback:ping><description><![CDATA[<p>转载自：<font style="background-color: #cce8cf">http://blog.csdn.net/sfdev/archive/2009/03/02/3950640.aspx</font><font style="background-color: #cce8cf"><br />
Quartz任务调度CronTrigger配置格式详细说明 <br />
CronTrigger配置完整格式为： [秒] [分] [小时] [日] [月] [周] [年]</font></p>
<p><font style="background-color: #cce8cf">&nbsp;序号 说明&nbsp; 是否必填&nbsp; 允许填写的值 允许的通配符&nbsp; <br />
&nbsp;1&nbsp; 秒&nbsp; 是&nbsp; 0-59&nbsp;&nbsp;&nbsp;&nbsp; , - * / <br />
&nbsp;2&nbsp; 分&nbsp; 是&nbsp; 0-59 <br />
&nbsp;&nbsp; , - * / <br />
&nbsp;3 小时&nbsp; 是&nbsp; 0-23&nbsp;&nbsp; , - * / <br />
&nbsp;4&nbsp; 日&nbsp; 是&nbsp; 1-31&nbsp;&nbsp; , - * ? / L W <br />
&nbsp;5&nbsp; 月&nbsp; 是&nbsp; 1-12 or JAN-DEC&nbsp;&nbsp; , - * / <br />
&nbsp;6&nbsp; 周&nbsp; 是&nbsp; 1-7 or SUN-SAT&nbsp;&nbsp; , - * ? / L #&nbsp; <br />
&nbsp;7&nbsp; 年&nbsp; 否&nbsp; empty 或 1970-2099&nbsp;&nbsp; , - * / </font></p>
<p><font style="background-color: #cce8cf">通配符说明:<br />
* 表示所有值. 例如:在分的字段上设置 "*",表示每一分钟都会触发。<br />
? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作，但不关心是周几，所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10 * ?<br />
- 表示区间。例如 在小时上设置 "10-12",表示 10,11,12点都会触发。<br />
, 表示指定多个值，例如在周字段上设置 "MON,WED,FRI" 表示周一，周三和周五触发<br />
/ 用于递增触发。如在秒上面设置"5/15" 表示从5秒开始，每增15秒触发(5,20,35,50)。 在月字段上设置'1/3'所示每月1号开始，每隔三天触发一次。<br />
L 表示最后的意思。在日字段设置上，表示当月的最后一天(依据当前月份，如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六，相当于"7"或"SAT"。如果在"L"前加上数字，则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示&#8220;本月最后一个星期五" <br />
W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置"15W"，表示离每月15号最近的那个工作日触发。如果15号正好是周六，则找最近的周五(14号)触发, 如果15号是周未，则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五)，则就在该天触发。如果指定格式为 "1W",它则表示每月1号往后最近的工作日触发。如果1号正是周六，则将在3号下周一触发。(注，"W"前只能设置具体的数字,不允许区间"-").<br />
# 序号(表示每月的第几个周几)，例如在周字段上设置"6#3"表示在每月的第三个周六.注意如果指定"#5",正好第五周没有周六，则不会触发该配置(用在母亲节和父亲节再合适不过了) ；</font></p>
<p><font style="background-color: #cce8cf">小提示：<br />
'L'和 'W'可以一组合使用。如果在日字段上设置"LW",则表示在本月的最后一个工作日触发；<br />
周字段的设置，若使用英文字母是不区分大小写的，即MON 与mon相同；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
常用示例:</font></p>
<p><font style="background-color: #cce8cf">0 0 12 * * ?&nbsp; 每天12点触发 <br />
0 15 10 ? * *&nbsp; 每天10点15分触发 <br />
0 15 10 * * ?&nbsp; 每天10点15分触发&nbsp; <br />
0 15 10 * * ? *&nbsp; 每天10点15分触发&nbsp; <br />
0 15 10 * * ? 2005&nbsp; 2005年每天10点15分触发 <br />
0 * 14 * * ?&nbsp; 每天下午的 2点到2点59分每分触发 <br />
0 0/5 14 * * ?&nbsp; 每天下午的 2点到2点59分(整点开始，每隔5分触发)&nbsp; <br />
0 0/5 14,18 * * ?&nbsp; 每天下午的 2点到2点59分、18点到18点59分(整点开始，每隔5分触发) <br />
0 0-5 14 * * ?&nbsp; 每天下午的 2点到2点05分每分触发 <br />
0 10,44 14 ? 3 WED&nbsp; 3月分每周三下午的 2点10分和2点44分触发 <br />
0 15 10 ? * MON-FRI&nbsp; 从周一到周五每天上午的10点15分触发 <br />
0 15 10 15 * ?&nbsp; 每月15号上午10点15分触发 <br />
0 15 10 L * ?&nbsp; 每月最后一天的10点15分触发 <br />
0 15 10 ? * 6L&nbsp; 每月最后一周的星期五的10点15分触发 <br />
0 15 10 ? * 6L 2002-2005&nbsp; 从2002年到2005年每月最后一周的星期五的10点15分触发 <br />
0 15 10 ? * 6#3&nbsp; 每月的第三周的星期五开始触发 <br />
0 0 12 1/5 * ?&nbsp; 每月的第一个中午开始每隔5天触发一次 <br />
0 11 11 11 11 ?&nbsp; 每年的11月11号 11点11分触发(光棍节) </font></p>
<p><font style="background-color: #cce8cf"><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/sfdev/archive/2009/03/02/3950640.aspx</font></p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/310928.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-27 13:15 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/27/310928.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>