天天看點

Spring AOP入門執行個體詳解

如果你正在研究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

繼續閱讀