經典的基於ProxyBeanFactory的Spring AOP

我們知道,要使用JDK的動態代理,目標類需要實現至少一個接口,下面定義了一個接口:
[java] view plain copy
 print?
  1. package com.zzj.aop;  
  2.   
  3. public interface Animal {  
  4.     public void eat();  
  5. }  
目標類:
[java] view plain copy
 print?
  1. package com.zzj.aop;  
  2.   
  3. public class Human implements Animal {  
  4.   
  5.     @Override  
  6.     public void eat() {  
  7.         System.out.println("eat...");  
  8.     }  
  9.   
  10. }  
前置通知:
[java] view plain copy
 print?
  1. package com.zzj.aop;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import org.springframework.aop.MethodBeforeAdvice;  
  6.   
  7. public class MethodBefore implements MethodBeforeAdvice {  
  8.   
  9.     public void before(Method arg0, Object[] arg1, Object arg2)  
  10.             throws Throwable {  
  11.         System.out.println("before...");  
  12.     }  
  13.   
  14. }  
後置通知:
[java] view plain copy
 print?
  1. package com.zzj.aop;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import org.springframework.aop.AfterReturningAdvice;  
  6.   
  7.   
  8. public class MethodAfter implements AfterReturningAdvice {  
  9.   
  10.     public void afterReturning(Object arg0, Method arg1, Object[] arg2,  
  11.             Object arg3) throws Throwable {  
  12.         System.out.println("after...");  
  13.     }  
  14.   
  15. }  
spring配置文件:
[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.            http://www.springframework.org/schema/beans/spring-beans.xsd">  
  6.        <!-- 定義目標對象 -->  
  7.        <bean id="human" class="com.zzj.aop.Human"></bean>  
  8.        <!-- 定義通知 -->  
  9.        <bean id="before" class="com.zzj.aop.MethodBefore"></bean>  
  10.        <bean id="after" class="com.zzj.aop.MethodAfter"></bean>  
  11.        <!-- 定義代理對象 -->  
  12.        <bean id="humanProxy" class="org.springframework.aop.framework.ProxyFactoryBean">  
  13.             <!-- 指定代理接口 -->  
  14.             <property name="interfaces">  
  15.                 <list>  
  16.                     <value>com.zzj.aop.Animal</value>  
  17.                 </list>  
  18.             </property>  
  19.             <!-- 指定目標對象  -->  
  20.             <property name="target" ref="human"></property>  
  21.             <!-- 指定攔截器(通知) -->  
  22.             <property name="interceptorNames">  
  23.                 <list>  
  24.                     <value>after</value>  
  25.                     <value>before</value>  
  26.                 </list>  
  27.             </property>  
  28.        </bean>  
  29.          
  30. </beans>  
測試:
[java] view plain copy
 print?
  1. package com.zzj.aop;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class Test {  
  7.   
  8.     /** 
  9.      * @param args 
  10.      */  
  11.     public static void main(String[] args) {  
  12.         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
  13.         Animal animal = (Animal) context.getBean("humanProxy");  
  14.         animal.eat();  
  15.   
  16.     }  
  17.   
  18. }  
輸出:
[plain] view plain copy
 print?
  1. before...  
  2. eat...  
  3. after...  
特別注意:只有調用在接口裏聲明的方法纔會經過代理。ProxyFactoryBean爲目標對象創建了一個代理對象,並在IOC容器裏註冊了它。默認情況下,ProxyFactoryBean自動偵測並且代理目標對象所實現的所有接口,所以,如果想代理目標對象的所有接口,可以不必顯示地指定這些接口。代理Bean可如下配置:
[html] view plain copy
 print?
  1. <bean id="humanProxy" class="org.springframework.aop.framework.ProxyFactoryBean">  
  2.             <!-- 指定目標對象  -->  
  3.             <property name="target" ref="human"></property>  
  4.             <!-- 指定攔截器(通知) -->  
  5.             <property name="interceptorNames">  
  6.                 <list>  
  7.                     <value>after</value>  
  8.                     <value>before</value>  
  9.                 </list>  
  10.             </property>  
  11. </bean>  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章