如果你正在研究Spring的AOP,那麼我想這篇文章可以為你的入門提供一點點幫助!
我想研究Spring AOP之前應該研究一下Java的動态代理和反射機制,了解這兩個概念和用法也是了解
Spring架構的基礎,因為Spring架構裡面大量的使用了動态代理和反射機制。
當然,本文主要是講解Spring的AOP,下面就開始走入正題!
AOP(面向切面程式設計),可千萬不要認為隻有Spring裡面才有AOP的概念,因為你可以在很多地方發現AOP的身影。如果你知道Servlet裡面的過濾器是怎麼一回事,那麼你就可以了解面向切面程式設計了,了解起來不是很難,怕還是了解不了,就再舉一個例子,比如你去火車站,門口會有一個物品檢測,人們隻要把東西放在機器裡面過一下就可以檢測了,檢測機器可以了解為隻有一台,物品是很多,隻要物品經過了檢查機器就會自動的去檢查,這就是面向切面!可以了解檢查機器是一個檢查物品的公共的類,隻要物品經過就會檢查,物品裡面不需要這個功能,這個是在經過的時候自動加上去的!
也許例子舉得不是很好,不知道現在有沒有了解面向切面程式設計!
為了很好的了解,我拿出一個簡單的配置檔案的例子來,這樣也可以友善講解和大家的了解!
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- 【 基本配置檔案 】 -->
<bean id="proxybean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.bling.spring.aop.BuyInterface</value>
</property>
<property name="target">
<ref local="targetbean"/>
</property>
<property name="interceptorNames">
<list>
<value>beforeadvisor</value>
<value>afteradvisor</value>
</list>
</property>
</bean>
<!-- 【 類 】 -->
<bean id="targetbean" class="org.bling.spring.aop.BuyInterfaceImpl"></bean>
<!-- 【 Advisor 】 -->
<bean id="beforeadvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="beforeadvice"/>
</property>
<property name="pattern">
<value>org\.bling\.spring\.aop\.BuyInterface\.buy</value>
</property>
</bean>
<bean id="afteradvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="afteradvice"/>
</property>
<property name="pattern">
<value>org\.bling\.spring\.aop\.BuyInterface\.buy</value>
</property>
</bean>
<!-- 【 Advice 】 -->
<bean id="beforeadvice" class="org.bling.spring.aop.Before"></bean>
<bean id="afteradvice" class="org.bling.spring.aop.After"></bean>
</beans>
上面是一個很簡單的配置檔案的例子,有四個注釋,我們首先看最下面一個【 Advice 】(翻譯為通知),這就是我們自己定義的通知,就比如是上面例子裡面的檢查機器,類名為了友善了解取名為Before(了解為入門的檢查機器)和After(這裡我加了一個出門的時候的一個檢查機器,按需要可以自己要還是不要),類名自己定義,但是要注意,Before.java這個類既然是在入門之前檢查,那麼在Spring架構中使用就要實作它給我提供的一個org.springframework.aop.MethodBeforeAdvice接口,可以了解為這是Spring的規定,當然After.java這個類也是要實作一個org.springframework.aop.AfterReturningAdvice接口,這樣Spring架構就認識了我們自定義的這兩個類,在實作接口的同時肯定會有接口定義的方法要被實作,是以Before.java裡面會有一個public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable方法,After.java裡面有一個public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable方法,這是必須實作的!這樣,我們的通知就寫完了!
下面看【 Advisor 】,這個地方是将我們自定義的通知交給Spring的一個類,這個類是org.springframework.aop.support.RegexpMethodPointcutAdvisor,這個了解為是一個切點,其實也就是切點(Pointcut)的概念,将我們定義的通知注入進去,因為這個類有一個advice屬性,說的深一點,可以了解為這個advice屬性的定義是一個至少繼承了我們兩個通知方法接口的一個接口,這裡自己好好的了解一下!這個類裡面還有一個屬性pattern,知道正規表達式的應該不難了解他的寫法,這裡是告訴Spring,我們這個通知要給哪個接口裡面的哪個方法進行通知,注意點是要轉義的(\.)!再次強調寫到方法名!
注冊完我們的自定義通知就要看看【 類 】了,這個類就是我們要進行通知的一個類,隻是簡單的在Spring架構裡面注冊了一下,這個類沒有什麼特别的,就是實作了一個自定義的接口,因為Spring架構提倡面向接口程式設計。
下面繼續,就剩下最後一個【 基本配置檔案 】,這個裡面就是真正實作了面向切面的部分,這個bean的ID自己定義,但是class="org.springframework.aop.framework.ProxyFactoryBean",他的裡面有幾個屬性,這裡就是列出了本例中用到的幾個,其他的以後深入了繼續講解,首先看proxyInterfaces屬性,這個是聲明我們被通知的類實作的接口,因為這裡是一個接口,因為隻有一個bean要被通知,多個接口請使用list,當然一個也可以使用list,繼續看target屬性,這個是将我們的目标bean注入進去,繼續interceptorNames屬性,這裡就是我們的通知了,這裡我加了兩個通知,一個是之前,一個是之後!
這樣我們的第一個Spring的AOP執行個體就是完成了!
下面給出各個類完整的代碼,以供大家參考,配置檔案代碼上面就是,不再重複!
**************************Before.java*********提前通知******************
package org.bling.spring.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class Before implements MethodBeforeAdvice {
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("你好,歡迎光臨!");
}
}
***************************After.java************之後通知*************
package org.bling.spring.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class After implements AfterReturningAdvice{
public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
throws Throwable {
System.out.println("歡迎下次光臨!");
}
}
***************************Buy.java*******接口**************************
package org.bling.spring.aop;
public interface BuyInterface {
public void buy();
}
*******************BuyInterfaceImpl.java*******接口實作類****************
package org.bling.spring.aop;
public class BuyInterfaceImpl implements BuyInterface {
public void buy() {
System.out.println("去商店買了一個東西!");
}
}
**********************MainTest.java*****運作測試類************
package org.bling.spring.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MainTest {
public static void main(String[] args) {
ApplicationContext ac = new FileSystemXmlApplicationContext("src/applicationContext.xml");
BuyInterface buy = (BuyInterface)ac.getBean("proxybean");
buy.buy();
}
}
http://www.cnblogs.com/pricks/archive/2010/05/26/1744468.html