Spring自动代理

转载自:http://bolide74.iteye.com/blog/1049935

这是《Spring温故知新》系列的第一部基础部分的最后一篇,简单的介绍一下Spring的自动代理。 

我一直都用机器人打招呼这个小应用来做举例,可能大家感觉用了前一篇的CGLIB代理以后就已经是非常方便了。但是事实上如果是真正大型的企业应用来说这还远远不够方便。 

不管是动态代理还是CGLIB代理,它们在使用之前都必须先给每个Action建立相应的代理bean。小应用可能还看不出区别,但是一旦Action的熟练达到几十个甚至几百上千个的时候,这个工作量就要令人崩溃了。 

Spring的自动代理就是为了解决这个问题而存在的。那么我们用一个简单的例子来学习怎么样实现动态代理,看完你就会觉得非常简单。 

依然先是WallE类,没有任何变化: 

Java代码   收藏代码
  1. package com.iteye.bolide74.action;  
  2.   
  3. public class WallE {  
  4.     public String name;  
  5.   
  6.     public String getName() {  
  7.         return name;  
  8.     }  
  9.   
  10.     public void setName(String name) {  
  11.         this.name = name;  
  12.     }  
  13.   
  14.     public void say(String msg) {  
  15.         System.out.println("到达邻居家,对邻居说:" + msg + ",我是" + this.name);  
  16.     }  
  17.   
  18.     public void clean() {  
  19.         System.out.println("开始进行垃圾回收程序");  
  20.     }  
  21. }  



然后是GetGift和GiveGift类,也跟前一篇一样没有变化: 

Java代码   收藏代码
  1. package com.iteye.bolide74.action;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import org.springframework.aop.MethodBeforeAdvice;  
  6.   
  7. public class GetGift implements MethodBeforeAdvice {  
  8.   
  9.     @Override  
  10.     public void before(Method arg0, Object[] arg1, Object arg2)  
  11.             throws Throwable {  
  12.         System.out.println("获取了一个礼物!");  
  13.     }  
  14. }  
Java代码   收藏代码
  1. package com.iteye.bolide74.action;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import org.springframework.aop.AfterReturningAdvice;  
  6.   
  7. public class GiveGift implements AfterReturningAdvice {  
  8.   
  9.     @Override  
  10.     public void afterReturning(Object arg0, Method arg1, Object[] arg2,  
  11.             Object arg3) throws Throwable {  
  12.         System.out.println("赠予了一个礼物!");  
  13.     }  
  14.   
  15. }  



最后就是最关键的config.xml: 

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">  
  3. <beans>  
  4.     <!-- 这个就是自动代理的关键,加入这个bean就代表了开启自动代理 -->  
  5.     <bean id="autoProxyCreator"  
  6.         class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />  
  7.           
  8.     <bean id="wallE" class="com.iteye.bolide74.action.WallE">  
  9.         <property name="name" value="Wall-E" />  
  10.     </bean>  
  11.     <bean id="getGift" class="com.iteye.bolide74.action.GetGift" />  
  12.     <bean id="giveGift" class="com.iteye.bolide74.action.GiveGift" />  
  13.       
  14.     <!-- 这里还是老样子,配置两个Advisor -->  
  15.     <bean id="getGiftAdvisor"  
  16.         class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  
  17.         <property name="advice">  
  18.             <ref bean="getGift" />  
  19.         </property>  
  20.         <property name="patterns">  
  21.             <list>  
  22.                 <value>.*say.*</value>  
  23.             </list>  
  24.         </property>  
  25.     </bean>  
  26.     <bean id="giveGiftAdvisor"  
  27.         class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  
  28.         <property name="advice">  
  29.             <ref bean="giveGift" />  
  30.         </property>  
  31.         <property name="patterns">  
  32.             <list>  
  33.                 <value>.*say.*</value>  
  34.             </list>  
  35.         </property>         
  36.     </bean>  
  37.     <!-- 大家可以注意到,原先实现ProxyFactoryBean的代理bean已经没有了,只需要以上的Adivsor就可以 -->  
  38. </beans>  



应用代码: 

Java代码   收藏代码
  1. package com.iteye.bolide74.tester;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. import com.iteye.bolide74.action.WallE;  
  7.   
  8. public class GiftBySpringTester {  
  9.     public static void main(String[] args) {  
  10.         ApplicationContext actx = new ClassPathXmlApplicationContext(  
  11.                 "config.xml");  
  12.         //注意:这里的getBean是wallE这个bean了,因为已经没有了代理bean  
  13.         WallE wallE = (WallE) actx.getBean("wallE");  
  14.         wallE.say("你好,Spring自动代理向你问候");  
  15.         System.out.println();  
  16.         wallE.clean();  
  17.     }  
  18. }  




运行结果: 

引用
获取了一个礼物! 
到达邻居家,对邻居说:你好,Spring自动代理向你问候,我是Wall-E 
赠予了一个礼物! 

开始进行垃圾回收程序





大家可以看到这就是最终使用了CGLIB代理和自动代理的机器人打招呼送礼物应用,我们可以对比一下最前面没有使用Spring框架时的代码,我们会发现除了在应用代码中可以看到Spring的痕迹以外,几乎都和平时写的普通代码没区别,这就是Spring的一大特点,低耦合! 


猜你喜欢

转载自xvshell.iteye.com/blog/2363444