Spring aop--几种不同的使用方式

最近听老师讲关于AOP关于容器的课,突然觉得之前对aop的理解都不是很到位,先不说理解就是应用都很少,最近也写了几篇关于AOP的博客,都是一些简单的demo,今天在这里再说一下关于Spring AOP的几种实现方式。

        我们经常会用到的有如下几种

        1、基于代理的AOP

        2、纯简单java对象切面

        3@Aspect注解形式的

        4、注入形式的Aspcet切面

下面我们就一个一个来应用吧.

下面先写一下几个基本的类。

接口类:

 

[java]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 定义一个接口 
  3.  * @author 陈丽娜 
  4.  * @version 2015年5月31日上午9:16:50 
  5.  */  
  6. public interface Sleepable {  
  7.   
  8.     /** 
  9.      * 睡觉方法 
  10.      * @author 陈丽娜 
  11.      * @version 2015年5月31日上午9:17:14 
  12.      */  
  13.     void sleep();  
  14. }  

 

实现类:

 

[java]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 陈丽娜 本人实现睡觉接口 
  3.  * @author 陈丽娜 
  4.  * @version 2015年5月31日下午4:51:43 
  5.  */  
  6. public class ChenLliNa implements Sleepable {  
  7.   
  8.     @Override  
  9.     public void sleep() {  
  10.         // TODO Auto-generated method stub  
  11.         System.out.println("乖,该睡觉了!");  
  12.     }  
  13. }  



 

增强类:

 

[java]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 定义一个睡眠的增强 同时实现前置 和后置 
  3.  * @author 陈丽娜 
  4.  * @version 2015年5月31日上午9:24:43 
  5.  */  
  6. public class SleepHelper implements MethodBeforeAdvice, AfterReturningAdvice {  
  7.   
  8.     @Override  
  9.     public void afterReturning(Object returnValue, Method method,  
  10.             Object[] args, Object target) throws Throwable {  
  11.          System.out.println("睡觉前要敷面膜");  
  12.     }  
  13.   
  14.     @Override  
  15.     public void before(Method method, Object[] args, Object target)  
  16.             throws Throwable {  
  17.         System.out.println("睡觉后要做美梦");  
  18.     }  
  19.   
  20. }  

 

一、基于代理的AOP

 

  

[java]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <!-- 创建一个增强 advice -->  
  2.     <bean id ="sleepHelper" class="com.tgb.springaop.aspect.SleepHelper"/>  
  3.   
  4.     <bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>  
  5.     <!-- 定义切点   匹配所有的sleep方法-->  
  6.     <bean id ="sleepPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">  
  7.            <property name="pattern" value=".*sleep"></property>  
  8.     </bean>  
  9.       
  10.     <!-- 切面    增强+切点结合 -->  
  11.     <bean id="sleepHelperAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">  
  12.          <property name="advice" ref="sleepHelper"/>  
  13.          <property name="pointcut" ref="sleepPointcut"/>  
  14.     </bean>  
  15.       
  16.     <!-- 定义代理对象 -->  
  17.     <bean id="linaProxy" class="org.springframework.aop.framework.ProxyFactoryBean">  
  18.             <property name="target" ref="lina"/>  
  19.             <property name="interceptorNames" value="sleepHelperAdvisor"/>  
  20.             <!-- <property name="proxyInterfaces" value="com.tgb.springaop.service.Sleepable"/> -->  
  21.     </bean>  

 

如配置文件中:

pattern属性指定了正则表达式,他匹配所有的sleep方法

使用org.springframework.aop.support.DefaultPointcutAdvisor的目的是为了使切点和增强结合起来形成一个完整的切面

最后配置完后通过org.springframework.aop.framework.ProxyFactoryBean产生一个最终的代理对象。

 

二、纯简单java对象切面

纯简单java对象切面这话怎么说呢,在我看来就是相对于第一种配置,不需要使用代理,,而是通过spring内部机制去自动扫描,这时候我们的配置文件就该如下修改:

 

[java]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <!-- 创建一个增强 advice -->  
  2. <bean id ="sleepHelper" class="com.tgb.springaop.aspect.SleepHelper"/>  
  3. <!-- 目标类 -->  
  4. <bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>  
  5.   
  6. <!--  配置切点和通知-->  
  7. <bean id ="sleepAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  
  8.      <property name="advice" ref="sleepHelper"></property>  
  9.      <property name="pattern" value=".*sleep"/>  
  10. </bean>  
  11.   
  12. <!-- 自动代理配置 -->  
  13. <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>  

 

是不是相对于第一种简单了许多,不用再去配置代理了。

 

三、@Aspect注解形式

根据我们的经验也知道,注解的形式相对于配置文件是简单一些的,这时候需要在已有的方法或类上家注解:

 

[java]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 通过注解的方式 添加增强 
  3.  * @author 陈丽娜 
  4.  * @version 2015年5月31日上午10:26:13 
  5.  */  
  6. @Aspect  
  7. @Component  
  8. public class SleepHelper03 {      
  9.       
  10.     /*@Pointcut("execution(* com.tgb.springaop.service.impl..*(..))")*/  
  11.     @Pointcut("execution(* *.sleep(..))")  
  12.     public void sleeppoint(){}  
  13.       
  14.     @Before("sleeppoint()")  
  15.     public void beforeSleep(){  
  16.         System.out.println("睡觉前要敷面膜");  
  17.     }  
  18.       
  19.     @AfterReturning("sleeppoint()")  
  20.     public void afterSleep(){  
  21.         System.out.println("睡觉后要做美梦");  
  22.     }  



 

配置文件中只需写:

 

[html]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <!--扫描包 -->  
  2.      <context:component-scan base-package="com.tgb" annotation-config="true"/>   
  3.      <!-- ASPECTJ注解 -->  
  4.      <aop:aspectj-autoproxy  proxy-target-class="true" />    
  5.        
  6.      <!-- 目标类 -->  
  7.       <bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>   



 

 

四、注入形式的Aspcet切面

个人感觉这个是最简单的也是最常用的,也是最灵活的。配置文件如下:

 

[html]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <!-- 目标类 -->  
  2.     <bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>  
  3.     <bean id ="sleepHelper" class="com.tgb.springaop.aspect.SleepHelper02"/>  
  4.       
  5.     <aop:config>  
  6.         <aop:aspect ref="sleepHelper">  
  7.              <aop:before method="beforeSleep" pointcut="execution(* *.sleep(..))"/>  
  8.              <aop:after method="afterSleep" pointcut="execution(* *.sleep(..))"/>  
  9.         </aop:aspect>  
  10.     </aop:config>  



 

配置文件中提到的SleepHelper02类如下:

 

[java]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 通过注解的方式 添加增强 
  3.  * @author 陈丽娜 
  4.  * @version 2015年5月31日上午10:26:13 
  5.  */  
  6.   
  7. public class SleepHelper02 {  
  8.     public void beforeSleep(){  
  9.         System.out.println("睡觉前要敷面膜");  
  10.     }  
  11.     public void afterSleep(){  
  12.         System.out.println("睡觉后要做美梦");  
  13.     }  
  14. }  

 

 

是不是看上去都很简单呀,这样是不是大家都会使用spring aop了?!

 

关于如何调用,这里写了几个测试类,可以看一下,基本都一样:

 

[java]   view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 配置文件 spring_aop.xml  通过代理 
  3.  * @author 陈丽娜 
  4.  * @version 2015年5月31日上午10:09:10 
  5.  */  
  6. @Test  
  7. public void test(){  
  8.     ApplicationContext ct = new ClassPathXmlApplicationContext("spring_aop.xml");  
  9.       
  10.     Sleepable sleeper =(Sleepable) ct.getBean("linaProxy");  
  11.       
  12.     sleeper.sleep();  
  13. }  
  14.   
  15. /** 
  16.  * 配置文件 spring_aop_01.xml   简答的java对象 
  17.  * @author 陈丽娜 
  18.  * @version 2015年5月31日上午10:09:37 
  19.  */  
  20. @Test  
  21. public void test01(){  
  22.     ApplicationContext ct = new ClassPathXmlApplicationContext("spring_aop_01.xml");  
  23.       
  24.     Sleepable sleeper = (Sleepable)ct.getBean("lina");  
  25.       
  26.     sleeper.sleep();  
  27. }  
  28.   
  29. /** 
  30.  * 配置文件 spring_aop_03.xml  通过aspect注解 
  31.  * @author 陈丽娜 
  32.  * @version 2015年5月31日上午10:09:37 
  33.  */  
  34. @Test  
  35. public void test03(){  
  36.     ApplicationContext ct = new ClassPathXmlApplicationContext("spring_aop_03.xml");  
  37.       
  38.        Sleepable sleeper = (Sleepable)ct.getBean("lina");  
  39.       
  40.     sleeper.sleep();  
  41. }  
  42. /** 
  43.  * 配置文件 spring_aop_02.xml  通过apsect配置文件 
  44.  * @author 陈丽娜 
  45.  * @version 2015年5月31日上午10:09:37 
  46.  */  
  47. @Test  
  48. public void test02(){  
  49.     ApplicationContext ct = new ClassPathXmlApplicationContext("spring_aop_02.xml");  
  50.       
  51.     Sleepable sleeper = (Sleepable)ct.getBean("lina");  
  52.       
  53.     sleeper.sleep();  
  54. }  

猜你喜欢

转载自xuyunti.iteye.com/blog/2273600
今日推荐