AOP及其在Spring中的應用(二)

li_xiao_ming發表於2012-12-18

 Spring中AOP的實現就是通過動態代理來實現的。動態代理的實現在上篇blog中已經涉及。Spring中目前最為實用的AOP應用,非用其實現的事務管理機制莫屬。也正是這一點,使得Spring AOP大方異彩。
那麼我們繼續圍繞上節的例子來探討一下Spring中AOP機制的應用與開發。

  首先,看看AOP中幾個基本的概念對應在AOP中的實現:
? 切點(PointCut)
  一系列連線點的集合,它指明處理方式(Advice)將在何時被觸發。
  對於我們開發而言,“何時觸發”的條件大多是面向Bean的方法進行制定。像Spring的配置化事務管理時針對方法名稱可進行PointCut設定,從而指定對所有以宣告字元開頭的方法進行基於AOP的事務管理。那麼同樣,對於我們自己實現的AOP元件而言,我們也可以以方法名作為觸發判定條件。
我們可以通過在XML配置檔案中配置以下節點,為我們的元件設定觸發條件。
<bean id="myPointcutAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="MyInterceptor" />
</property>
<property name="patterns">
<list>
<value>.*save.*</value>
<value>.*do.*</value>
</list>
</property>
</bean>

  上面我們針對MyInterceptor設定了一個基於方法名的觸發條件,也就是說,當目標類的指定方法執行時,MyInterceptor即被觸發。
  ? 處理方式(Advice)
  也就是說要實現一個Interceptor,以供在連線點時觸發。Spring中採用了AOP聯盟(AOP Alliance)的通用AOP介面(介面定義位aopalliance.jar)。這裡我們採用aopalliance.jar中定義的MethodInterceptor作為我們的Advice實現介面。那麼我們上節例子中的處理方式應實現為如下Interceptor:
package test.aop.spring;
import java.util.logging.Logger;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
* @author xkf
**/
public class LockInterceptor implements MethodInterceptor {
private Logger logger = Logger.getLogger(this.getClass().getName());
public Object invoke(MethodInvocation invocation) throws Throwable {
// TODO Auto-generated method stub
lock();
Object ret= invocation.proceed();
unlock();
return ret;
}
private void lock(){
logger.info("lock domain object...");
}
private void unlock(){
logger.info("unlock domain object...");
}
}
  實現後,對應的Interceptor實現類在配置檔案中的體現如下:
  <bean id="MyInterceptor" class="test.aop.spring.LockInterceptor"/>
  最後,我們還需要定義一個Spring AOP ProxyFactory用於載入執行AOP元件,並且需要將Advice通過IOC的方式注入到介面以及實現類。
  對應的配置檔案應如下配置從而實現這些內容:
<bean id="myAOPProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>test.aop.spring.DomainObjDAO</value>
</property>
<property name="target">
<ref local="impl" />
</property>
<property name="interceptorNames">
<value>myPointcutAdvisor</value>
</property>
</bean>
<bean id="impl" class="test.aop.spring.DomainObjDAOImpl"/>
萬事大吉!寫一個TestCase來看一下執行結果:
package test.aop.spring;

import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
* @author xkf
*/
public class SpringTestCase extends TestCase {
DomainObjDAO test=null;

protected void setUp() throws Exception {
super.setUp();
ApplicationContext ctx=new FileSystemXmlApplicationContext("test/Bean.xml");
test = (DomainObjDAO) ctx.getBean("myAOPProxy");
}

protected void tearDown() throws Exception {
super.tearDown();
}
public void testSave(){
test.save();
}
}
執行結果如下:
資訊: Creating shared instance of singleton bean ''MyInterceptor''
2004-12-7 23:50:11 test.aop.spring.LockInterceptor lock
資訊: lock domain object...
saving domain object......
2004-12-7 23:50:11 test.aop.spring.LockInterceptor unlock
資訊: unlock domain object...

  OK!至此,我們已經探討了AOP動態代理的實現以及其在Spring中的應用,接下來的Blog中我將會關注Spring中事務以及持久化的實現。

相關文章