经典的基于ProxyBeanFactory的Spring AOP

来源:互联网 发布:微博域名格式 编辑:程序博客网 时间:2024/06/16 16:28
我们知道,要使用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>