﻿<?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 AOP</title><link>http://www.blogjava.net/liuwentao253/category/19571.html</link><description>SPRING,设计模式,UML,Oracle</description><language>zh-cn</language><lastBuildDate>Wed, 02 Jan 2008 17:43:41 GMT</lastBuildDate><pubDate>Wed, 02 Jan 2008 17:43:41 GMT</pubDate><ttl>60</ttl><item><title>Spring AOP处理日志 </title><link>http://www.blogjava.net/liuwentao253/archive/2007/12/28/171205.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Fri, 28 Dec 2007 07:23:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/12/28/171205.html</guid><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AOP正在成为软件开发的下一个圣杯。使用AOP，你可以将处理aspect的代码注入主程序， 通常主程序的主要目的并不在于处理这些aspect。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AOP可以防止代码混乱。 为了理解AOP 如何做到这点，考虑一下记日志的工作。日志本身不太可能是你开发的主程序的主要任务。 如果能将&#8220;不可见的&#8221;、通用的日志代码注入主程序中，那该多好啊。AOP可以帮助你做到。 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Spring framework是很有前途的AOP技术。作为一种非侵略性的，轻型的AOP framework，你无需使用预编译器或其他的元标签，便可以在Java程序中使用它。这意味着开发团队里只需 一人要对付AOP framework，其他人还是象往常一样编程。 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AOP是很多直觉难以理解的术语的根源。幸运的是，你只要理解三个概念，就可以编写AOP模块。这三个概念是：advice，pointcut和advisor。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; advice是你想向别的程序内部不同的地方注入的代码。pointcut定义了需要注入advice的位置，通常是某个特定的类的一个public方法。advisor是pointcut和advice的装配器，是将advice注入主程序中预定义位置的代码。 </p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 既然我们知道了需要使用advisor向主要代码中注入&#8220;不可见的&#8221;advice，让我们实现一个Spring AOP的例子。 在这个例子中，我们将实现一个before advice，这意味着advice的代码在被调用的public方法开始前被执行。 以下是这个before advice的实现代码： </p>
<p>package com.company.springaop.test; </p>
<p>import java.lang.reflect.Method; <br />
import org.springframework.aop.MethodBeforeAdvice; </p>
<p>public class TestBeforeAdvice implements MethodBeforeAdvice { //这里还有after，Exception，around等Advice<br />
/**<br />
*before 是在方法执行之前执行advice的内容，around是在方法执行之前和之后都得到了执行<br />
*Exception是抛出异常的时候，可以使用aop的方法来统一处理业务的异常。<br />
&#215;在编程的时候，可以由专门的人处理业务的异常，其它人还是一样的编程，不用考虑业务类异常的处理。<br />
*/</p>
<p>&nbsp; public void before(Method m, Object[] args, Object target) <br />
&nbsp; throws Throwable { //这里能用反射？<br />
&nbsp;&nbsp;&nbsp; System.out.println("Hello world! (by " <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + this.getClass().getName() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + ")"); <br />
&nbsp; } <br />
} </p>
<p>接口MethodBeforeAdvice只有一个方法before需要实现，它定义了advice的实现。before方法共用三个参数，它们提供了相当丰富的信息。参数Method m是advice开始后执行的方法。方法名称可以用作判断是否执行代码的条件。Object[] args是传给被调用的public方法的参数数组。当需要记日志时，参数args和被执行方法的名称，都是非常有用的信息。你也可以改变传给m的参数，但要小心使用这个功能；编写最初主程序的程序员并不知道主程序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用。 在下面的BeanImpl类中，每个public方法调用前，都会执行advice： </p>
<p>package com.company.springaop.test; </p>
<p>public class BeanImpl implements Bean { </p>
<p>&nbsp; public void theMethod() { <br />
&nbsp;&nbsp;&nbsp; System.out.println(this.getClass().getName() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "." + new Exception().getStackTrace()[0].getMethodName() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "()" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + " says HELLO!"); <br />
&nbsp; } <br />
} </p>
<p><br />
类BeanImpl实现了下面的接口Bean： </p>
<p>package com.company.springaop.test; </p>
<p>public interface Bean { <br />
&nbsp; public void theMethod(); <br />
} </p>
<p>&nbsp;虽然不是必须使用接口，但面向接口而不是面向实现编程是良好的编程实践，Spring也鼓励这样做。 pointcut和advice通过配置文件来实现，因此，接下来你只需编写主方法的Java代码： </p>
<p><br />
package com.company.springaop.test; </p>
<p>import org.springframework.context.ApplicationContext; <br />
import org.springframework.context.support.FileSystemXmlApplicationContext; </p>
<p>public class Main { </p>
<p>&nbsp; public static void main(String[] args) { <br />
&nbsp;&nbsp;&nbsp; //Read the configuration file <br />
&nbsp;&nbsp;&nbsp; ApplicationContext ctx <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = new FileSystemXmlApplicationContext("springconfig.xml"); </p>
<p>&nbsp;&nbsp;&nbsp; //Instantiate an object <br />
&nbsp;&nbsp;&nbsp; Bean x = (Bean) ctx.getBean("bean"); </p>
<p>&nbsp;&nbsp;&nbsp; //Execute the public method of the bean (the test) <br />
&nbsp;&nbsp;&nbsp; x.theMethod(); <br />
&nbsp; } <br />
} </p>
<p>&nbsp;</p>
<p>我们从读入和处理配置文件开始，接下来马上要创建它。这个配置文件将作为粘合程序不同部分的&#8220;胶水&#8221;。读入和处理配置文件后，我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。 仅仅用配置文件便可把程序的每一部分组装起来。 </p>
<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />
&lt;!DOCTYPE beans PUBLIC&nbsp; "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt; </p>
<p>&lt;beans&gt; <br />
&nbsp; &lt;!--CONFIG--&gt; <br />
&nbsp; &lt;bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;property name="proxyInterfaces"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;com.company.springaop.test.Bean&lt;/value&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/property&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;property name="target"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref local="beanTarget"/&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/property&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;property name="interceptorNames"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;theAdvisor&lt;/value&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/list&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/property&gt; <br />
&nbsp; &lt;/bean&gt; </p>
<p>&nbsp; &lt;!--CLASS--&gt; <br />
&nbsp; &lt;bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/&gt; </p>
<p>&nbsp; &lt;!--ADVISOR--&gt; <br />
&nbsp; &lt;!--Note: An advisor assembles pointcut and advice--&gt; <br />
&nbsp; &lt;bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;property name="advice"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref local="theBeforeAdvice"/&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/property&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;property name="pattern"&gt; //pointcut?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;com\.company\.springaop\.test\.Bean\.theMethod&lt;/value&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/property&gt; <br />
&nbsp; &lt;/bean&gt; </p>
<p>&nbsp; &lt;!--ADVICE--&gt; <br />
&nbsp; &lt;bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/&gt; <br />
&lt;/beans&gt; <br />
&nbsp; </p>
<p><br />
四个bean定义的次序并不重要。我们现在有了一个advice，一个包含了正则表达式pointcut的advisor， 一个主程序类和一个配置好的接口，通过工厂ctx，这个接口返回自己本身实现的一个引用。 BeanImpl 和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创建一个bean元素，并指定了一个实现类。这 就是全部的工作。advisor通过Spring framework提供的一个RegexMethodPointcutAdvisor类来实现。我 们用advisor的一个属性来指定它所需的advice-bean。第二个属性则用正则表达式定义了pointcut，确保 良好的性能和易读性。 最后配置的是bean，它可以通过一个工厂来创建。bean的定义看起来比实际上要 复杂。bean是ProxyFactoryBean的一个实现，它是Spring framework的一部分。这个bean的行为通过一下 的三个属性来定义： </p>
<p>&nbsp;</p>
<p><br />
属性proxyInterface定义了接口类。 属性target指向本地配置的一个bean，这个bean返回一个接口的实现。 属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。 注意，advisor列表的次序是非常重要的。 </p>
<p>&nbsp;</p>
<p>Spring工具 </p>
<p>虽然你可以手工修改Ant构建脚本，但使用SpringUI（译注：SpringUI现在是Spring framework的一部分，并改名 为spring-ide），使用Spring AOP变得很简单，只要点点鼠标即可。你可以把SpringUI安装成Eclipse的一个plug-in。 然后，你只需在你的project上右击鼠标，并选择&#8220;add Spring Project Nature&#8221;。在project属性中，你可以在&#8220;Spring Project&#8221;下添加Spring配置文件。在编译前把下面的类库加入project：aopalliance.jar，commons-logging.jar， jakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息： </p>
<p>... (logging information) <br />
Hello world! (by com.company.springaop.test.TestBeforeAdvice) <br />
com.company.springaop.test.BeanImpl.theMethod() says HELLO! </p>
<p><br />
优点和缺点 </p>
<p>Spring比起其他的framework更有优势，因为除了AOP以外，它提供了更多别的功能。 作为一个轻型framework，它在J2EE不同的部分都可以发挥作用。因此，即使不想使用Spring AOP， 你可能还是想使用Spring。另一个优点是，Spring并不要求开发团队所有的人员都会用它。 学习Spring应该从Spring reference的第一页开始。读了本文后，你应该可以更好地理解Spring reference了。 Spring唯一的缺点是缺乏更多的文档，但它的mailing list是个很好的补充，而且会不断地出现更多的文档。 </p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/liuwentao253/aggbug/171205.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-12-28 15:23 <a href="http://www.blogjava.net/liuwentao253/archive/2007/12/28/171205.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对比Spring1.0 与 2.0 的事务配置方式</title><link>http://www.blogjava.net/liuwentao253/archive/2007/08/31/141719.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Fri, 31 Aug 2007 06:12:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/08/31/141719.html</guid><description><![CDATA[<p>1. 对比 <br />
先看1.0的标准事务配置:</p>
<p>Spring 2.0 的重头戏之一就是AspectJ 式 AOP 配置。 但是一定要通过对比，才能看到2.0式的AOP配置是如何跳出一片新天空的。</p>
<p>1. 对比 <br />
先看1.0的标准事务配置:</p>
<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">&nbsp;&nbsp;&nbsp;&nbsp;</span><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: #ff0000"><strong>transactionManager</strong></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">org.springframework.jdbc.datasource.DataSourceTransactionManager</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">dataSource</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><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;</span><span style="color: #000000">&lt;</span><span style="color: #000000">ref&nbsp;bean</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">dataSource</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span></div>
<p>&nbsp;</p>
<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">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #0000ff"><strong>baseTxService</strong></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">org.springframework.transaction.interceptor.TransactionProxyFactoryBean</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;</span><span style="color: #0000ff">abstract</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">true</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">transactionManager</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;ref</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000"><strong style="color: #ff0000">transactionManager</strong></span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">proxyTargetClass</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;value</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">true</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span></strong><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">transactionAttributes</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<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;</span><span style="color: #000000">&lt;</span><span style="color: #000000">props</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">prop&nbsp;key</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">get*</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED,readOnly</span><span style="color: #000000">&lt;/</span><span style="color: #000000">prop</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">prop&nbsp;key</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">find*</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED,readOnly</span><span style="color: #000000">&lt;/</span><span style="color: #000000">prop</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">prop&nbsp;key</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">save*</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED</span><span style="color: #000000">&lt;/</span><span style="color: #000000">prop</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">prop&nbsp;key</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">remove*</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED</span><span style="color: #000000">&lt;/</span><span style="color: #000000">prop</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<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;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">props</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">preInterceptors</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span></strong><strong><span style="color: #000000">&nbsp;&nbsp;<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;</span><span style="color: #000000">&lt;</span><span style="color: #000000">list</span><span style="color: #000000">&gt;</span></strong><strong><span style="color: #000000">&nbsp;&nbsp;<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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">ref&nbsp;bean</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">methodSecurityInterceptor</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span></strong><strong><span style="color: #000000">&nbsp;&nbsp;<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;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">list</span><span style="color: #000000">&gt;</span></strong><strong><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span></strong><span style="color: #000000"><strong>&nbsp;&nbsp;<br />
</strong><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;</span></div>
<p>&nbsp;</p>
<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">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">bookManager</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;parent</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000"><strong style="color: #0000ff">baseTxService</strong></span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">target</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<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;</span><span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">org.springside.bookstore.admin.manager.BookManager</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
<p><br />
再看2.0的新配置：</p>
<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">&lt;</span><span style="color: #000000">aop:config&nbsp;proxy</span><span style="color: #000000">-</span><span style="color: #000000">target</span><span style="color: #000000">-</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">true</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">aop:advisor&nbsp;pointcut</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">execution(*&nbsp;yourpackagename..*Manager.*(..))</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;advice</span><span style="color: #000000">-</span><span style="color: #000000">ref</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000"><strong style="color: #ff0000">txAdvice</strong></span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">aop:advisor&nbsp;pointcut</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">execution(*&nbsp;yourpackagename..*Manager.save(..))</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;advice</span><span style="color: #000000">-</span><span style="color: #000000">ref</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">fooAdvice</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">aop:config</span><span style="color: #000000">&gt;</span></div>
<p>&nbsp;</p>
<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">&lt;</span><span style="color: #000000">tx:advice&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000"><strong style="color: #ff0000">txAdvice</strong></span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;transaction</span><span style="color: #000000">-</span><span style="color: #000000">manager</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">transactionManager</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tx:attributes</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tx:method&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">save*</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tx:method&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">remove*</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tx:method&nbsp;name</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;read</span><span style="color: #000000">-</span><span style="color: #000000">only</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">true</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">tx:attributes</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">tx:advice</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;</span></div>
<p>&nbsp;</p>
<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">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">bookManager</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">org.springside.bookstore.commons.service.BookManager</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;</span></div>
<p>&nbsp;<br />
</p>
<p>再来看看 appfuse1.9.4的配置 ：<br />
<br />
<img height="620" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/SNAG-0004.jpg" width="1152" border="0" /><br />
<br />
<br />
2.进步 <br />
1. AOP的配置方式也AOP了。 <br />
对比1.0的配置文件，因为下面2提到的限制，事关安全acegi methodSecurityInterceptor 拦截器要配置在关于事务的TransactionProxyFactoryBean的preInterceptors属性里，这样子就一点不AOP了，而2.0使用ponintcut expression，很AOP的配置一切Aspect。 </p>
<p>2. 1.0时，一个已经AOP过的object不能再次被AOP。 <br />
在Spring 1.0的文档里Rod说，比如&lt;bean id="bookManager" parent="baseTxService"&gt;已经进行了一次AOP，如果想在这个Bean上再配一层AOP，比如要对方法执行结果缓存，无论以1.0 还是2.0的方式定义，cglib方式是会报错的，而基于接口的方式，结果不确定。 </p>
<p>3. BookManager能直接定义自己，而不是像1.0那样作匿名内部target。</p>
<p>虽然在1.0时代的BeanNameAutoProxyCreator 达到类似作用，但只能用BeanName来匹配比较危险，没有AspectJ的pointcut语法细致。</p>
<p>3. 语法 <br />
满江红翻译的Spring参考文档 6.3 schema-based AOP support 提供了aspect,advisor,advide三种组装方法的解释，其中aspect是aspectJ原装，但稍复杂.</p>
<p>唯一有点难懂的是pointcut里的语法，其实也很好学，Spring参考文档6.2.3.4里有完整说明 ，其实一排子过去是<br />
</p>
<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">execution(modifiers</span><span style="color: #000000">-</span><span style="color: #000000">pattern</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;ret</span><span style="color: #000000">-</span><span style="color: #000000">type</span><span style="color: #000000">-</span><span style="color: #000000">pattern&nbsp;declaring</span><span style="color: #000000">-</span><span style="color: #000000">type</span><span style="color: #000000">-</span><span style="color: #000000">pattern</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;name</span><span style="color: #000000">-</span><span style="color: #000000">pattern(param</span><span style="color: #000000">-</span><span style="color: #000000">pattern)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">-</span><span style="color: #000000">pattern</span><span style="color: #000000">?</span><span style="color: #000000">)&nbsp;</span></div>
<p><br />
其中带问号的modifiers-pattern?(public/protected) 和 declaring-type-pattern? throws-pattern? 可以不填</p>
<p>可见execution(* *..BookManager.save(..))</p>
<p>第一颗* 代表ret-type-pattern 返回值可任意，<br />
&nbsp;<br />
*..BookManager 代表任意Pacakge里的BookManager类。 <br />
<br />
如果写成com.xyz.service.* 则代表com.xyz.service下的任意类 <br />
com.xyz.service..*&nbsp; com.xyz.service则代表com.xyz.service及其子package下的任意类 <br />
save代表save方法，也可以写save* 代表saveBook()等方法 <br />
(..) 匹配0个参数或者多个参数的，任意类型 <br />
(x,..) 第一个参数的类型必须是X <br />
(x,,,s,..) 匹配至少4个参数，第一个参数必须是x类型，第二个和第三个参数可以任意，第四个必须是s类型。 </p>
<p>注意name-pattern千万不要写成*..*Manager ，这样子的话会把所有第三方类库的Manager比如Spring的PlatformTranstationManager 也加入aop，非常危险。所以最好还是加上项目的package前缀，如org.springside&nbsp;</p>
<img src ="http://www.blogjava.net/liuwentao253/aggbug/141719.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-08-31 14:12 <a href="http://www.blogjava.net/liuwentao253/archive/2007/08/31/141719.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring AOP增强事务有两种代理方式</title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/30/96747.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Tue, 30 Jan 2007 07:52:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/30/96747.html</guid><description><![CDATA[
		<p>Spring AOP增强事务有两种代理方式，<br /><br />一是动态代理，要求你的target类必须是实现某一个或n个接口的。<br />第二种是用CGLIB做动态字节码增强。</p>
<img src ="http://www.blogjava.net/liuwentao253/aggbug/96747.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-01-30 15:52 <a href="http://www.blogjava.net/liuwentao253/archive/2007/01/30/96747.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring2.0中的session作用域被注入</title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/30/96715.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Tue, 30 Jan 2007 05:54:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/30/96715.html</guid><description><![CDATA[样例1：<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">userPreferences</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.foo.UserPreferences</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> scope</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">session</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">userManager</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.foo.UserManager</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">userPreferences</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ref</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">userPreferences</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">bean</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span></div><br />第一个例子： 如果session失效，userManager仍将保留userPreferences实例！<br /><span style="COLOR: #000000">userManager</span>直接将userPreference的引用拷贝了一份到自己的特定地址上！销毁了原来的实例，而拷贝后的实例依赖存在！<br /><br />样例2：<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">userPreferences</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.foo.UserPreferences</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> scope</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">session</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">aop:scoped</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">proxy</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">bean</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">userService</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.foo.SimpleUserService</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">userPreferences</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ref</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">userPreferences</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">      <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">bean</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> <img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />加了&lt;aop:scoped-proxy /&gt;，这个的作用是代理这个实例 <br /><br />第二个例子:     session失效,则userPreferences失效. 单例的userManager保存的是userPreference的代理实例！ <br />这个代理实例不是singleton的,也不是跟随着userPreferences的.它是随着session创建而创建... 如果session销毁，代理实例就无法访问到userPreference了！<br /><img src ="http://www.blogjava.net/liuwentao253/aggbug/96715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-01-30 13:54 <a href="http://www.blogjava.net/liuwentao253/archive/2007/01/30/96715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>幼学琼林-对比Spring 1.0与2.0的事务配置方式 </title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/30/96680.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Tue, 30 Jan 2007 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/30/96680.html</guid><description><![CDATA[
		<p>Spring 2.0 的重头戏之一就是AspectJ 式 AOP 配置。 但是一定要通过对比，才能看到2.0式的AOP配置是如何跳出一片新天空的。</p>
		<p>1. 对比 <br />先看1.0的标准事务配置:</p>
		<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">bean id</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">baseTxService</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">org.springframework.transaction.interceptor.TransactionProxyFactoryBean</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">abstract</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">true</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">property name</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">transactionManager</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> ref</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">transactionManager</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">/&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">property name</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">proxyTargetClass</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> value</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">true</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">/&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">property name</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">transactionAttributes</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">props</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">prop key</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">get*</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">PROPAGATION_REQUIRED,readOnly</span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">prop</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">prop key</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">find*</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">PROPAGATION_REQUIRED,readOnly</span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">prop</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">prop key</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">save*</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">PROPAGATION_REQUIRED</span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">prop</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">prop key</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">remove*</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">PROPAGATION_REQUIRED</span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">prop</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">props</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">property</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">property name</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">preInterceptors</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">list</span>
				<span style="COLOR: #000000">&gt;&lt;</span>
				<span style="COLOR: #000000">ref bean</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">methodSecurityInterceptor</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">/&gt;&lt;/</span>
				<span style="COLOR: #000000">list</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">property</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">bean</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">bean id</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">bookManager</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> parent</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">baseTxService</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">property name</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">target</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&gt;&lt;</span>
				<span style="COLOR: #000000">bean </span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">org.springside.bookstore.admin.manager.BookManager</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">/&gt;&lt;/</span>
				<span style="COLOR: #000000">property</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span>
				<span style="COLOR: #000000">&lt;/</span>
				<span style="COLOR: #000000">bean</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000"> </span>
		</div>
		<br />再看2.0的新配置：<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">aop:config proxy</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">target</span><span style="COLOR: #000000">-</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">true</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">aop:advisor pointcut</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">execution(* yourpackagename..*Manager.*(..))</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> advice</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">ref</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">txAdvice</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">aop:advisor pointcut</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">execution(* yourpackagename..*Manager.save(..))</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> advice</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">ref</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">fooAdvice</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">aop:config</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">tx:advice id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">txAdvice</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> transaction</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">manager</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">transactionManager</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">tx:attributes</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">tx:method name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">save*</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">tx:method name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">remove*</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">tx:method name</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"> read</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">only</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">true</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   </span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">tx:attributes</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">tx:advice</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">bookManager</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.springside.bookstore.commons.service.BookManager</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">  </span></div><p><br /> </p><img src ="http://www.blogjava.net/liuwentao253/aggbug/96680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-01-30 10:33 <a href="http://www.blogjava.net/liuwentao253/archive/2007/01/30/96680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java AOP学习 </title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/29/96503.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Mon, 29 Jan 2007 06:22:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/29/96503.html</guid><description><![CDATA[
		<p>先说说我对几个概念的理解 </p>
		<p>通知（Advice）：横切操作时具体的操作。 <br />切入点（Pointcut）：描述什么时候需要进行横切操作，即在哪些地方需要加入通知，但是切入点不关心具体的通知是什么。 <br />通知者（Advisor）：由于通知者是通过切入点来创建的（<font color="#0000ff"><u>切入点作为创建一个通知者实例时的参数</u></font>），切入点可以对目标类和目标方法进行详细的描述，所以通知者告诉代理哪些类的哪些方法需要进行横切操作，从而对需要实现横切的方法进行灵活的定制。我把通知者理解为切入点和通知的绑定（<font color="#0000ff">通知作为创建通知者实例时的另一个参数</font>），<font color="#ff0000"><u>它描述了哪些类的哪些方法需要进行哪些横切操作</u></font>（即哪个通知）。 </p>
		<p>再说说代理，代理的作用就是透明的为我们提供获得了通知的目标类（具体的使用方法看一下例子就明白了，非常简单）。这个目标类可以是我们自己写的任何类或者其他第三方类。我们在调用通过代理得到的目标类中的方法时就会触发某个通知，从而完成横切操作。 </p>
		<p>最后是我总结的实现横切的一般步骤 <br />简单的切入： <br />1，创建某个通知的实例（spring提供五种通知） <br />2，创建代理的的实例 <br />3，将通知加入代理 <br />4，通过代理获取目标类实例 <br />5，调用目标类的方法。 </p>
		<p>可对需要横切的方法进行具体定制的切入： <br />1，创建切入点实例（Spring提供了七种可对目标类和目标方法进行定制的切入点实现） <br />2，通过切入点和通知创建通知者实例 <br />3，将通知者加入代理 <br />4，通过代理获取目标类实例 <br />5，调用目标类的方法。</p>
		<p>实现Spring IoC容器的访问,可以通过如下两个接口完成 <br />1.BeanFactory:开发者借助于配置文件实现对JavaBean的配置和管理. <br />2.ApplicationContext:构建在BeanFactory基础上,既继承于它,除了具有BeanFactory的功能外,还添加其他的功能 <br />.3区别:BeanFactory 延迟载入所有的Bean,至到getBean()被调用时才被创建。 <br />ApplicationContext 在上下文启动后预载入所有的单实例Bean <br />  </p>
		<p>spring中有2种aop代理类实现，一种是jdk的动态代理，另外一种是CGLib实现的代理类,看看动态代理，对理解aop非常有好处的。</p>
<img src ="http://www.blogjava.net/liuwentao253/aggbug/96503.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-01-29 14:22 <a href="http://www.blogjava.net/liuwentao253/archive/2007/01/29/96503.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring AOP之ThrowsAdvice</title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/23/95494.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Tue, 23 Jan 2007 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/23/95494.html</guid><description><![CDATA[目前的项目中接触了一些Spring的AOP的部分，比如声明式事务管理。<br /><br />1.  几个重要的概念（详细的情况参见Spring的在线文档）<br /><br />·         PointCut：一组JointPoint。在Spring中我们可以通过一些正则表达式定义那些JointPoint组成了我们需要的一个PointCut，从而使我们的Advice可以被编制进来。<br /><br />·         Introduction：Introduction可以我们在已经存在的类中在不修改这个类的情况下增加属性和方法，从而增加其状态和动作；<br /><br />·         Target：满足PointCut定义的条件的一个类，我们可以把Advice用于这个类。大多Spring的AOP是通过动态代理的机制实现的，这个Target就是那个被代理的对象；<br /><br />·         Proxy：为了将一个Advice应用到另外一个类中，比如实现Around Advice，就是在一个方法执行前后加上其他的代码，那么实际的实现一定是先执行一段Advice的代码，然后执行Target的那个方法，之后再执行一段Advice的代码，也就是客户端执行某个类的时候，实际执行的是一个代理，由代理再把调用传递到那个Target中。<br /><br />·         Weaving（编织）：有了Target和Advice，在什么时机将这两个模块编织在一起呢？可以选择的方法包括编译的时候（这样我们需要一个特殊的编译器），装载类的时候（这样我们需要一个特殊的ClassLoader）和运行的时候（AOP容易可以动态的创建一个代理从而将调用由这个代理传递到Target类中）。<br /><br />2. Throws Advice<br />目前的项目中有这么一个要求，对于某些处理流程如果在运行的时候抛出了一些异常，需要将这些异常的信息记录下来，保存在数据库或发邮件给开发人员。我们切不说这个需求跟TDD有什么冲突的地方，先看看如何实现吧。<br /><br />按照上面概念的描述，我们应该主要注意三个概念：Target，Advice和Proxy。<br /><br />2.1 Target的实现<br />Target就是上面所说的业务流程类，我们按照正常的开发编写代码即可，没有什么特殊的要求。如：<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 id="Codehighlighter1_29_86_Open_Image" onclick="this.style.display='none'; Codehighlighter1_29_86_Open_Text.style.display='none'; Codehighlighter1_29_86_Closed_Image.style.display='inline'; Codehighlighter1_29_86_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_29_86_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_29_86_Closed_Text.style.display='none'; Codehighlighter1_29_86_Open_Image.style.display='inline'; Codehighlighter1_29_86_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> IBizProcess </span><span id="Codehighlighter1_29_86_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_29_86_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> doOneThing();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> doAnotherThing();     <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><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_28_152_Open_Image" onclick="this.style.display='none'; Codehighlighter1_28_152_Open_Text.style.display='none'; Codehighlighter1_28_152_Closed_Image.style.display='inline'; Codehighlighter1_28_152_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_28_152_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_28_152_Closed_Text.style.display='none'; Codehighlighter1_28_152_Open_Image.style.display='inline'; Codehighlighter1_28_152_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> BizProcessImpl </span><span id="Codehighlighter1_28_152_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_28_152_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_59_65_Open_Image" onclick="this.style.display='none'; Codehighlighter1_59_65_Open_Text.style.display='none'; Codehighlighter1_59_65_Closed_Image.style.display='inline'; Codehighlighter1_59_65_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_59_65_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_59_65_Closed_Text.style.display='none'; Codehighlighter1_59_65_Open_Image.style.display='inline'; Codehighlighter1_59_65_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> doOneThing() </span><span id="Codehighlighter1_59_65_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_59_65_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_100_150_Open_Image" onclick="this.style.display='none'; Codehighlighter1_100_150_Open_Text.style.display='none'; Codehighlighter1_100_150_Closed_Image.style.display='inline'; Codehighlighter1_100_150_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_100_150_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_100_150_Closed_Text.style.display='none'; Codehighlighter1_100_150_Open_Image.style.display='inline'; Codehighlighter1_100_150_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> doAnotherThing() </span><span id="Codehighlighter1_100_150_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_100_150_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> RuntimeException(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Boom</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><br /><br />2.2 Advice<br />为了实现当业务流程抛出异常时的Advice，我们需要定义个一个Advice类，实现ThrowsAdvice接口。这个接口里面没有定义方法，我们要求我们的类必须实现afterThrows这个方法，如下：<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> afterThrows( [Method method,] [Object args,] [Object target,] Throwable throwable );</span></div><br />这个方法的前面三个参数都是可选的。我们在同一个类中定义这个方法的多个版本，如：<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 id="Codehighlighter1_45_46_Open_Image" onclick="this.style.display='none'; Codehighlighter1_45_46_Open_Text.style.display='none'; Codehighlighter1_45_46_Closed_Image.style.display='inline'; Codehighlighter1_45_46_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_45_46_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_46_Closed_Text.style.display='none'; Codehighlighter1_45_46_Open_Image.style.display='inline'; Codehighlighter1_45_46_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> afterThrowing( MyException1 ex ) </span><span id="Codehighlighter1_45_46_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_45_46_Open_Text"><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_93_94_Open_Image" onclick="this.style.display='none'; Codehighlighter1_93_94_Open_Text.style.display='none'; Codehighlighter1_93_94_Closed_Image.style.display='inline'; Codehighlighter1_93_94_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_93_94_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_93_94_Closed_Text.style.display='none'; Codehighlighter1_93_94_Open_Image.style.display='inline'; Codehighlighter1_93_94_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> afterThrowing( MyException2 ex ) </span><span id="Codehighlighter1_93_94_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_93_94_Open_Text"><span style="COLOR: #000000">{}</span></span></div><br />具体那个方法被调用则根据具体的Exception来判断，由AOP容易自动识别执行。<br />2.3 Proxy（代理）<br />Spring中一个简单的实现是用它的org.springframework.aop.framework.ProxyFactoryBean。这个Bean包含了很多个属性，其中有三个我们需要设置：target，proxyInterfaces和interceptorNames，如下：<br />&lt;bean id=”bizOneTarget” class=”com.company.biz.impl.BizProcessImpl”/&gt;<br />&lt;bean id=”throwsAdvice” class=”com.company.advice.MyThrowsAdvice”/&gt;<br />&lt;bean id=”bizOne” class=”org.springframework.aop.framework.ProxyFactoryBean”&gt;<br />            &lt;property name=”target”&gt;&lt;ref bean=”bizOneTargte”/&gt;&lt;/property&gt;<br />            &lt;property name=”proxyInterfaces”&gt;<br />                        &lt;value&gt;com.company.biz.IBizProcessImpl&lt;/value&gt;<br />            &lt;/property&gt;<br />            &lt;property name=”interceptorNames”&gt;<br />                        &lt;list&gt;<br />                                    &lt;value&gt;throwsAdvice&lt;/value&gt;<br />                        &lt;/list&gt;<br />            &lt;/property&gt;<br />&lt;/bean&gt;<br />通过上面的配置，Spring就把Target和Advice编织在了一起。需要说明的是，proxyInterfaces和interceptorNames都可以是多个，如果是多个的话就需要用list来定义。interceptorNames的先后次序决定了这些Advice执行的先后次序。<br />3. 简化配置<br />从上面的例子可以看出，如果有多个BizProcess的对象需要代理，我们在Spring配置中为每一个Bean都配置一个代理，那么配置文件的维护就成了麻烦。为此，Spring提供了比较方便的方法解决这个问题，比如BeanNameAutoProxyCreator、DefaultAdviceAutoProxyCreator和metadata autoproxying。我们采用了BeanNameAutoProxyCreator，因为他比较直观和简单。<br />配置如下：<br />&lt;bean id=”beanNameAutoProxyCreator” class=”org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator”&gt;<br />            &lt;property name=’beanNames”&gt;<br />                        &lt;list&gt;<br />                                    &lt;value&gt;*Service&lt;/value&gt;<br />                        &lt;/list&gt;<br />            &lt;/property&gt;<br />            &lt;property name=”interceptorNames”&gt;<br />                        &lt;value&gt;throwsAdvice&lt;/value&gt;<br />            &lt;/property&gt;<br />&lt;/bean&gt;<br />从中我们可以看到，所有以Service结尾的bean都会由Spring自动创建代理，从而实现Advice的织入。<br /><img src ="http://www.blogjava.net/liuwentao253/aggbug/95494.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-01-23 11:25 <a href="http://www.blogjava.net/liuwentao253/archive/2007/01/23/95494.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring AOP之Hello World </title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/23/95473.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Tue, 23 Jan 2007 02:31:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/23/95473.html</guid><description><![CDATA[我们使用一个简单的例子来演示一下Spring中的AOP，这是一个log的例子，实际上log是一个对于AOP来说很不好的例子，这里我们只为说明Spring AOP的使用。<br />　　<br />　　1.首先我们来创建一个自己的interceptor <br />　　这个类必须继承org.aopalliance.intercept. MethodInterceptor接口。Spring的AOP框架就是参照aopalliance这个标准实现的，所以我们的MyInterceptor要继承这个标准中的接口。<br />　　这个接口只有一个要求实现的方法：<br />　　public Object invoke(MethodInvocation methodInvocation) throws Throwable;<br />　　下面是我们的MyIntercptor：<br />　　<br />　　public class MyInterceptor implements MethodInterceptor {<br />　　private final Log logger = LogFactory.getLog(getClass());<br />　　 <br />　　public Object invoke(MethodInvocation methodInvocation) throws Throwable {<br />　　logger.info("Beginning method (1): " + <br />　　methodInvocation.getMethod().getDeclaringClass() + "." + <br />　　methodInvocation.getMethod().getName() + "()");<br />　　long startTime = System.currentTimeMillis();<br />　　try{<br />　　Object result = methodInvocation.proceed();<br />　　return result;<br />　　}finally{<br />　　logger.info("Ending method (1): " + <br />　　methodInvocation.getMethod().getDeclaringClass() + "." +<br />　　methodInvocation.getMethod().getName() + "()");<br />　　logger.info("Method invocation time (1): " + <br />　　(System.currentTimeMillis() - startTime) + " ms.");<br />　　}<br />　　}<br />　　}<br />　　<br />　　对于上面的代码需要说明的是下面两行代码：<br />　　Object result = methodInvocation.proceed();<br />　　return result;<br />　　整个程序的流程是这样的：<br />　　1，先是执行在Object result = methodInvocation.proceed();前面的代码；<br />　　2，接着执行Object result = methodInvocation.proceed();，它把执行控制权交给了interceptor stack(拦截器栈)内的下一个interceptor，如果没有了就交给真正的业务方法；<br />　　3，然后执行return result;之前的代码；<br />　　4，最后执行return result;，它把控制权交回它之上的interceptor，如果没有了就退出interceptor stack。<br />　　<br />　　2.写出我们的业务对象及其接口<br />　　为了方便我们的业务接口只有一个hello方法：<br />　　<br />　　public interface BusinessInterface {<br />　　public void hello();<br />　　}<br />　　 <br />　　业务对象的代码如下：<br />　　<br />　　public class BusinessInterfaceImpl implements BusinessInterface{<br />　　public void hello() {<br />　　System.out.println("hello Spring AOP.");<br />　　}<br />　　}<br />　　 <br />　　3.接下来，我们来看看如何使用我们的写的interceptor<br />　　我们把业务对象作为AOP的target：<br />　　&lt;bean id="businessTarget" class="com.rst.spring.testaop.BusinessInterfaceImpl"/&gt;<br />　　接着在bean定义中声明interceptor：<br />　　&lt;bean id="myInterceptor" class="com.rst.spring.testaop.MyInterceptor"/&gt;<br />　　最后，我们来声明真正的业务对象，通过使用它的接口以及Spring的ProxyFactoryBean：<br />　　<br />　　&lt;bean id="businessBean"<br />　　　　class="org.springframework.aop.framework.ProxyFactoryBean"&gt;<br />　　&lt;property name="proxyInterfaces"&gt;<br />　　&lt;value&gt;com.rst.spring.testaop.BusinessInterface&lt;/value&gt;<br />　　&lt;/property&gt;<br />　　&lt;property name="interceptorNames"&gt;<br />　　&lt;list&gt;<br />　　&lt;value&gt;myInterceptor&lt;/value&gt;<br />　　&lt;value&gt;businessTarget&lt;/value&gt;<br />　　&lt;/list&gt;<br />　　&lt;/property&gt;<br />　　&lt;/bean&gt;<br />　　 <br />　　这里需要说明两点：<br />　　proxyInterfaces：就是我们的业务对象的实际接口；<br />　　interceptorNames：定义了所有interceptors的执行顺序，其中业务对象的target作为list的最后一个。记着一定要把业务对象的target放到list中，否则你的业务对象就不会工作。<br />　　<br />　　4.最后，写我们的测试类<br />　　ClassPathResource resource = <br />　　new ClassPathResource("com/rst/spring/testaop/aop_bean.xml");<br />　　XmlBeanFactory beanFactory = new XmlBeanFactory(resource);<br />　　BusinessInterface businessBean = <br />　　(BusinessInterface) beanFactory.getBean("businessBean");<br />　　businessBean.hello();<br />　　 <br />　　一切正常就可以在log上看到相应的信息了。<br />　　以下是附件源代码的执行效果：<br />　　2004-09-08 16:04:51,210 INFO - Beginning method (1): interface com.rst.spring.testaop.BusinessInterface.hello()<br />　　2004-09-08 16:04:51,210 INFO - Beginning method (2): interface com.rst.spring.testaop.BusinessInterface.hello()<br />　　hello Spring AOP.<br />　　2004-09-08 16:04:51,210 INFO - Ending method (2): interface com.rst.spring.testaop.BusinessInterface.hello()<br />　　2004-09-08 16:04:51,210 INFO - Ending method (1): interface com.rst.spring.testaop.BusinessInterface.hello()<br />　　2004-09-08 16:04:51,210 INFO - Method invocation time (1): 0 ms.<br />　　源代码需要spring.jar, aopallience.jar, commons-logging.jar。<br /><img src ="http://www.blogjava.net/liuwentao253/aggbug/95473.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-01-23 10:31 <a href="http://www.blogjava.net/liuwentao253/archive/2007/01/23/95473.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Spring AOP实现开发中松散耦合</title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/23/95454.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Tue, 23 Jan 2007 01:31:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/23/95454.html</guid><description><![CDATA[
		<p>面向方面编程（AOP）是面向对象编程（OOP）的一种扩展技术，能够很好的解决横切关注点问题以及相关的设计难题来实现松散耦合。Spring AOP 是 AOP 技术的一种实现。本文介绍了AOP 概念，然后详细讨论了如何利用Spring AOP 开发AOP 程序，最后展望了Spring AOP 的前景。</p>
		<p>　　AOP（Aspected Oriented Programming）是一种新兴的编程技术。它可以解决OOP和过程化方法不能够很好解决的横切（crosscut）问题，如：事务、安全、日志等横切关注。当未来系统变得越来越复杂，横切关注点就成为一个打问题的时候，AOP就可以很轻松的解决横切关注点这个问题，使得AOP编程成为。Spring 是基于J2EE的轻量级开源开发框架，其中Spring AOP组件实现了面向方面编程。</p>
		<p>　　AOP 概述</p>
		<p>　　面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程（OOP）。 面向对象将应用程序分解成各个层次的对象，而AOP将程序分解成各个方面或者说关注点 。这使得可以模块化诸如事务管理等这些横切多个对象的关注点。 </p>
		<p>　　1、AOP 基本概念</p>
		<p>　　方面（Aspect）： 一个关注点的模块化，这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的 Advisor或拦截器实现。</p>
		<p>　　连接点（Joinpoint）: 程序执行过程中明确的点，如方法的调 用或特定的异常被抛出。</p>
		<p>　　通知（Advice）: 在特定的连接点，AOP框架执行的动作。各种类 型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架 包括Spring都是以拦截器做通知模型，维护一个“围绕”连接点的拦截器链。</p>
		<p>　　切入点（Pointcut）: 指定一个通知将被引发的一系列连接点 的集合。AOP框架必须允许开发者指定切入点：例如，使用正则表达式。</p>
		<p>　　引入（Introduction）: 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如，你可以使用一个引入使任何对象实现 IsModified接口，来简化缓存。</p>
		<p>　　目标对象（Target Object）: 包含连接点的对象。也被称作 被通知或被代理对象。</p>
		<p>　　AOP代理（AOP Proxy）: AOP框架创建的对象，包含通知。 在Spring中，AOP代理可以是JDK动态代理或者CGLIB代理。</p>
		<p>　　织入（Weaving）: 组装方面来创建一个被通知对象。这可以在编译时 完成（例如使用AspectJ编译器），也可以在运行时完成。Spring和其他纯Java AOP框架一样， 在运行时完成织入。</p>
		<p>　　Spring AOP 介绍</p>
		<p>　　Spring的一个关键组件就是AOP框架。 Spring IoC容器(BeanFactory 和ApplicationContext)并不依赖于AOP, 这意味着如果你不需要使用，AOP可以不用，AOP完善了Spring IoC，使之成为一个有效的中间件解决方案。</p>
		<p>　　Spring AOP 是Spring 框架的重要组成部分，它实现了AOP联盟约定的接口。Spring AOP 是由纯Java开发完成的。Spring AOP 只实现了方法级别的连接点，在J2EE应用中，AOP拦截到方法级的操作已经足够。<font color="#0000ff">OOP倡导的是基于setter/getter 的方法访问，而非直接访问域</font>，而Spring 有足够理由仅仅提供方法级的连接点。为了使控制反转（IoC）很方便的使用到非常健壮、灵活的企业服务，则需要Spring AOP 的实现。Spring AOP 在运行时才创建Advice 对象。Spring AOP的优点如下：</p>
		<p>　　·允许开发者使用声明式企业服务，比如事务服务、安全性服务。</p>
		<p>　　·开发者可以开发满足业务需求的自定义方面。</p>
		<p>　　·开发Spring AOP Advice 很方便，可以借助代理类快速搭建Spring AOP 应用。</p>
		<p>　　使用Spring AOP松散耦合</p>
		<p>　　1、创建通知</p>
		<p>　　为实现AOP，开发者需要开发AOP 通知(Advice)。AOP 通知（Advice） 包含了方面（Aspect）的逻辑。当创建一个Advice 对象的时候，你就编写了实现横切（cross-cutting）功能。 Spring 的连接点是用方法拦截器实现的，这就意味着你编写的Spring AOP 通知将在方法调用的不同点组入进程序中。由于在调用一个方法时有几个不同的时间点，Spring 可以在不同的时间点组入进程序。Spring AOP中，提供了四种通知的接口： MethodBeforeAdvice 用于在目标方法调用前触发；AfterReturningAdvice 用于在目标方法调用后触发；ThrowsAdvice 用于在目标方法抛出异常时触发；MethodInterceptor 用于实现 Around 通知（Advice），在目方法执行的前后触发。</p>
		<p>　　如果要实现相应功能，则需要实现上述对应的接口。例如：实现Before 通知（Advice）需要实现方法 void before(Method method, Object[] args, Object target) ，实现 After 通知（Advice） 需要实现方法 void afterReturning (Method method, Object[] args, Object target)。 </p>
		<p>　　2、在Spring 中定义切入点</p>
		<p>　　在不能明确调用方法的时候，通知就很不实用。切入点则可以决定特定的类，特定的方法是否匹配特定标准。如果某匹配，则通知将应用到此方法上。Spring 切入点允许用很灵活的方式将通知组织进我们的类中。Spring 中的切入点框架的核心是Pointcut接口，此接口允许我们定义组入通知中的类和方法。许多方面是通过一系列的通知和切入点组合来定义。</p>
		<p>　　在Spring中，一个advisor就是一个方面的完整的模块化表示。Spring提供了PointcutAdvisor接口把通知和切入点组合成一个对象。Spring中很多内建的切入点都有对应的PointcutAdvisor，这使得你可以很方便在一个地方管理切入点和通知。Spring中的切入点分为两类：静态和动态。因为静态切入点的性能要优于动态切入点，所以优先考虑使用。Spring 为我们提供创建静态切入点很实用的类StaticMethodMatherPointcut。在这个类中，我们只需要关心setMappedName和setMappedNams方法。你可以使用具体的类名，也可以使用通配符。如：设置mappedName属性为set* 则匹配所有的set方法。Spring还提供了另通过正则表达式来创建静态切入点的实用类RegexpMethodPointcut。通过使用Perl样式的正则表达式来定义你感兴趣的方法。当切入点需要运行时参数值来执行通知时，这时就需要使用动态切入点。Spring提供了一个内建的动态切入点：ControlFlowPointcut，此切入点匹配基于当前线程的调用堆栈。我们可以在只有在当前线程执行的执行时找到特定的类和特定的方法才返回true。使用动态切入点有很大的性能损耗。大多数的切入点可以静态确定，我们很少有机会创建动态切入点。为了增加可切入点的可重用性，Spring 提供了切入点上的集合操作——交集和合并。</p>
		<p>　　3、用ProxyFactoryBean创建AOP代理</p>
		<p>　　ProxyFactoryBean，和其他Spring的 FactoryBean实现一样，引入一个间接的层次。如果你定义一个名字为myfactory的ProxyFactoryBean， 引用myfactory的对象所看到的不是ProxyFactoryBean 实例本身，而是由实现ProxyFactoryBean的类的 getObject()方法所创建的对象。这个方法将创建一个包装了目标对象 的AOP代理。使用ProxyFactoryBean或者其他IoC可知的类来创建AOP代理的最重要的优点之一是IoC可以管理通知和切入点。这是一个非常的强大的功能，能够实现其他AOP框架很难实现的特定的方法。例如，一个通知本身可以引用应用对象（除了目标对象， 它在任何AOP框架中都可以引用应用对象），这完全得益于依赖注入所提供的可插入性。通常，我们不需要ProxyFactoryBean的全部功能，因为我们常常只对一个方面感兴趣： 例如，事务管理。当我们仅仅对一个特定的方面感兴趣时，我们可以使用许多便利的工厂来创建AOP代理，如：TransactionProxyFactoryBean。</p>
		<p>　　4、自动代理</p>
		<p>　　在应用较小时，只有很少类需要被通知的时，ProxyFactoryBean 可以很好的工作。当有许多类需要通知的时，显示的创建每个代理就显得很繁琐。幸运的是Spring提供了是使用自动通过容器来创建代理。这时，就只需要配置一个Bean来做繁琐的工作。Spring提供了两个类实现自动代理：BeanNameAutoProxyCreator和DefaultAdvisorAutoProxyCreator。BeanNameAutoProxyCreator为匹配名字的Bean产生代理，它可以使用在将一个或者多个方面应用在命名相似的Bean中。自动代理框架假设代理将要暴露出什么接口。如果目标Bean没有实现任何接口，这时就会动态产生一个子类。而更强大的自动代理是DefaultAdvisorAutoProxyCreator，你所需要做的是在BeanFactory中包含它的配置。这个类的奇妙之处在于他使用实现了BeanPostProcessor接口。在Bean定义被加载倒Spring容器中后，DefaultAdvisorAutoProxyCreator将搜索上下文中的Advisor，最后它将Advisor应用到匹配Advisor切入点的Bean中。这个代理只对Advisor起作用，它需要通过Advisor来得到需要通知的Bean。元数据自动代理（MetaData AutoProxy）。元数据自动代理配置依赖于源代码属性而不是外部XML配置文件。这可以非常方便的使源代码和AOP元数据组织在同一个地方。元数据自动代理最常用的地方是用来声明事务。Spring提供了很强的框架来通过AOP框架来声明事务。这提供了在EJB使用声明式事务的相同功能。</p>
		<p>　　结论</p>
		<p>　　AOP 是面向对象编程的有力补充。通过方面就可以聚合在应用中行为形成可重用模块。</p>
		<p>　　通过程序可以实现怎样和在什么地方来调用这些行为。这可以减少代码重复，并使你更加关注业务逻辑。Spring 提供了AOP框架来实现调用方法时加入方面。在AOP框架中可以很方便的使用预定义的静态切入点来定义被调用的类和方法。我们需要通过Spring提供的代理类来产生代理对象，可以使用ProxyFactoryBean也可以使用自动代理。Spring AOP 的编程方式模块化了横向关注点的实现，提供了一个更好更快的软件开发方式。在软件结构日益扩大，结构日益复杂的今天，Spring AOP 将会发挥越来越重要的作用。</p>
<img src ="http://www.blogjava.net/liuwentao253/aggbug/95454.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-01-23 09:31 <a href="http://www.blogjava.net/liuwentao253/archive/2007/01/23/95454.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开源技术分析:AOP和Spring事务处理</title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/12/93386.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Fri, 12 Jan 2007 04:31:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/12/93386.html</guid><description><![CDATA[
		<strong>一.</strong>
		<b>. AOP</b>
		<br />　　<br />　　1. AOP是什么？<br />　　<br />　　AOP是OOP的延续，是Aspect Oriented Programming的缩写，意思是面向方面编程。AOP实际是GoF设计模式的延续，设计模式孜孜不倦追求的是调用者和被调用者之间的解耦，AOP可以说也是这种目标的一种实现。<br />　　<br />　　2. 切面意义何在？<br />　　<br />　　就可以在这层切面上进行统一的集中式权限管理。而业务逻辑组件则无需关心权限方面的问题。也就是说，通过切面，我们可以将系统中各个不同层次上的问题隔离开来，实现统一集约式处理。各切面只需集中于自己领域内的逻辑实现。这一方面使得开发逻辑更加清晰，专业化分工更加易于进行；另一方面，由于切面的隔离，降低了耦合性，我们就可以在不同的应用中将各个切面组合使用，从而使得代码可重用性大大增强。<br />　　<br />　　3. AOP应用范围<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">　　Authentication 权限<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Caching 缓存<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Context passing 内容传递<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Error handling 错误处理<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Lazy loading　懒加载<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Debugging　　调试<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　logging, tracing, profiling and monitoring　记录跟踪　优化　校准<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Performance optimization　性能优化<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Persistence　　持久化<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Resource pooling　资源池<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Synchronization　同步<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Transactions 事务</span></div><br />　<img src ="http://www.blogjava.net/liuwentao253/aggbug/93386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-01-12 12:31 <a href="http://www.blogjava.net/liuwentao253/archive/2007/01/12/93386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SpringAOP之HelloWorld</title><link>http://www.blogjava.net/liuwentao253/archive/2007/01/12/93372.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Fri, 12 Jan 2007 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/01/12/93372.html</guid><description><![CDATA[我们使用一个简单的例子来演示一下Spring中的AOP，这是一个log的例子，实际上log是一个对于AOP来说很不好的例子，这里我们只为说明Spring AOP的使用。<br />　　<br />　　<b>1.首先我们来创建一个自己的interceptor <br /></b><br />　　这个类必须继承org.aopalliance.intercept. MethodInterceptor接口。Spring的AOP框架就是参照aopalliance这个标准实现的，所以我们的MyInterceptor要继承这个标准中的接口。<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Object invoke(MethodInvocation methodInvocation) </span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> Throwable;</span></div><br />　　下面是我们的MyIntercptor：　　<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_56_741_Open_Image" onclick="this.style.display='none'; Codehighlighter1_56_741_Open_Text.style.display='none'; Codehighlighter1_56_741_Closed_Image.style.display='inline'; Codehighlighter1_56_741_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_56_741_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_56_741_Closed_Text.style.display='none'; Codehighlighter1_56_741_Open_Image.style.display='inline'; Codehighlighter1_56_741_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> MyInterceptor </span><span style="COLOR: #0000ff">implements</span><span style="COLOR: #000000"> MethodInterceptor </span><span id="Codehighlighter1_56_741_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_56_741_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">final</span><span style="COLOR: #000000"> Log logger </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> LogFactory.getLog(getClass());<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     <br /><img id="Codehighlighter1_194_739_Open_Image" onclick="this.style.display='none'; Codehighlighter1_194_739_Open_Text.style.display='none'; Codehighlighter1_194_739_Closed_Image.style.display='inline'; Codehighlighter1_194_739_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_194_739_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_194_739_Closed_Text.style.display='none'; Codehighlighter1_194_739_Open_Image.style.display='inline'; Codehighlighter1_194_739_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Object invoke(MethodInvocation methodInvocation) </span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> Throwable </span><span id="Codehighlighter1_194_739_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_194_739_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        logger.info(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Beginning method (1): </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        methodInvocation.getMethod().getDeclaringClass() </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">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        methodInvocation.getMethod().getName() </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">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000"> startTime </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> System.currentTimeMillis();<br /><img id="Codehighlighter1_400_469_Open_Image" onclick="this.style.display='none'; Codehighlighter1_400_469_Open_Text.style.display='none'; Codehighlighter1_400_469_Closed_Image.style.display='inline'; Codehighlighter1_400_469_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_400_469_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_400_469_Closed_Text.style.display='none'; Codehighlighter1_400_469_Open_Image.style.display='inline'; Codehighlighter1_400_469_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">try</span><span id="Codehighlighter1_400_469_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_400_469_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            Object result </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> methodInvocation.proceed();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> result;<br /><img id="Codehighlighter1_477_736_Open_Image" onclick="this.style.display='none'; Codehighlighter1_477_736_Open_Text.style.display='none'; Codehighlighter1_477_736_Closed_Image.style.display='inline'; Codehighlighter1_477_736_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_477_736_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_477_736_Closed_Text.style.display='none'; Codehighlighter1_477_736_Open_Image.style.display='inline'; Codehighlighter1_477_736_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        }</span></span><span style="COLOR: #0000ff">finally</span><span id="Codehighlighter1_477_736_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_477_736_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            logger.info(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Ending method (1): </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            methodInvocation.getMethod().getDeclaringClass() </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">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            methodInvocation.getMethod().getName() </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">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            logger.info(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Method invocation time (1): </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            (System.currentTimeMillis() </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> startTime) </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ms.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>　　<br />　　对于上面的代码需要说明的是下面两行代码：<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">　　Object result </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> methodInvocation.proceed();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> result;</span></div><br />　　整个程序的流程是这样的：<br />　　1，先是执行在Object result = methodInvocation.proceed();前面的代码；<br />　　2，接着执行Object result = methodInvocation.proceed();，它把执行控制权交给了interceptor stack(拦截器栈)内的下一个interceptor，如果没有了就交给真正的业务方法；<br />　　3，然后执行return result;之前的代码；<br />　　4，最后执行return result;，它把控制权交回它之上的interceptor，如果没有了就退出interceptor stack。<br />　　<br />　　<b>2.写出我们的业务对象及其接口</b><br />　　为了方便我们的业务接口只有一个hello方法：<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 id="Codehighlighter1_37_65_Open_Image" onclick="this.style.display='none'; Codehighlighter1_37_65_Open_Text.style.display='none'; Codehighlighter1_37_65_Closed_Image.style.display='inline'; Codehighlighter1_37_65_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_37_65_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_37_65_Closed_Text.style.display='none'; Codehighlighter1_37_65_Open_Image.style.display='inline'; Codehighlighter1_37_65_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">　　</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> BusinessInterface </span><span id="Codehighlighter1_37_65_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_37_65_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    　　</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> hello();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />　　}</span></span></div><br />　　 <br />　　业务对象的代码如下：<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 id="Codehighlighter1_65_144_Open_Image" onclick="this.style.display='none'; Codehighlighter1_65_144_Open_Text.style.display='none'; Codehighlighter1_65_144_Closed_Image.style.display='inline'; Codehighlighter1_65_144_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_65_144_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_144_Closed_Text.style.display='none'; Codehighlighter1_65_144_Open_Image.style.display='inline'; Codehighlighter1_65_144_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">　　</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> BusinessInterfaceImpl </span><span style="COLOR: #0000ff">implements</span><span style="COLOR: #000000"> BusinessInterface</span><span id="Codehighlighter1_65_144_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_65_144_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_90_140_Open_Image" onclick="this.style.display='none'; Codehighlighter1_90_140_Open_Text.style.display='none'; Codehighlighter1_90_140_Closed_Image.style.display='inline'; Codehighlighter1_90_140_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_90_140_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_90_140_Closed_Text.style.display='none'; Codehighlighter1_90_140_Open_Image.style.display='inline'; Codehighlighter1_90_140_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    　　</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> hello() </span><span id="Codehighlighter1_90_140_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 src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_90_140_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        　　System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hello Spring AOP.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    　　}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />　　}</span></span></div><br />　　 <br />　　<b>3.接下来，我们来看看如何使用我们的写的interceptor</b><br />　　我们把业务对象作为AOP的target：<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">businessTarget</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.rst.spring.testaop.BusinessInterfaceImpl</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>　　接着在bean定义中声明interceptor：<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">myInterceptor</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.rst.spring.testaop.MyInterceptor</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span></div><br />　　最后，我们来声明真正的业务对象，通过使用它的接口以及Spring的ProxyFactoryBean：<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">businessBean</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.springframework.aop.framework.ProxyFactoryBean</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><