`

转载:Spring Aop Advise方法(增强方法) 中获取目标方法的参数

 
阅读更多

转载自:http://jackyin5918.iteye.com/blog/1918076

 

Spring Aop Advise方法(增强方法) 中获取目标方法的参数

 

1. 概念 

   

   切面类: 一种特殊bean,通过aop配置,其中的方法(增强方法),会对目标bean的目标方法做一些增强处理

   (比如在目标方法之前或之后调用等).

   

   切入点(pointcut): 一种规则,普通bean中符合这种规则的方法,将成为上面切面类中所说的目标方法,接受切面类方法

   的特殊处理.

   

   增强方法(Advice),包括aop:befor,aop:after,aop:after-retuing,aop:around,aop:throwing等.

   

2. 配置片段:

     

Xml代码  收藏代码
  1. <!-- AOP测试的chinese -->  
  2.             <bean id="chinese_aop" class="test.aop.Chinese" />  
  3.             <!-- 定义一个普通bean,作为切面bean -->  
  4.             <bean id="accessArgAspect" class="test.aop.aspect.AccessArgAspect" />  
  5.             <!-- AOP配置  -->   
  6.             <aop:config>  
  7.               <!-- 配置切面aspect -->  
  8.               <aop:aspect id="aspect" ref="accessArgAspect">  
  9.                 <aop:after-returning   
  10.                   pointcut="execution(* test.aop.*.*(..))"   
  11.                   method="access"  
  12.                   returning="retval"  
  13.                   arg-names="time,food,retval"   
  14.                 />  
  15.               </aop:aspect>   
  16.             </aop:config>  

       

    上面的配置中:

    <bean id="chinese_aop" class="test.aop.Chinese" />

    配置了普通的bean,该bean中的一些方法

    即将满足切入点配置规则,接受切面类中增强方法(Advice)的增强处理.

    

    <bean id="accessArgAspect" class="test.aop.aspect.AccessArgAspect" /> 定义一个切面类,

    切面类可以是一个普通的bean.

    

    <aop:config>

      <!--配置切面aspect,通过ref关联到前面配置的作为切面类的bean-->

      <aop:aspect id="aspect" ref="accessArgAspect">

        <!-- 配置一种aop:after-returning增强处理-->

        <aop:after-returning

          <!-- 切入点 规则,符合这个规则的普通bean中的方法将接受增强处理 -->

          pointcut="execution(*test.aop.*.*(..)) and args(food,time,..)"  

          <!-- 切面类中,作为增强处理的方法的名称 -->

          method="access"

          <!-- 普通bean,接受增强处理方法的返回值,void的类型被视为null --> 

          returning="retval" 

          <!-- 切面类中增强方法的参数名,这个配置可以省略 -->

          arg-names="time,food,retval"

        />

        

      </aop:aspect>

    </aop:config>

    

3. 参数绑定

   切面类 方法(增强方法)获取 目标方法(普通bean中接受增强方法处理的方法) 参数的方式称为参数绑定.

   

   (1) 增强方法 不需要传递参数,则不需要参数绑定.

   

   (2) 增强方法中,只有一个JoinPoint类型的参数,使用这种参数,也不需要参数绑定.

       因为, JoinPoint类有一些方法可以获取目标方法的调用信息(包括参数信息),比如:

       Object[] getArgs(),返回在执行目标方法时传递的参数

       Signature getSignature(),获取 目标方法的签名

       Object getTarget():返回被植入 增强处理的目标对象

       Object getThis(): 返回AOP框架为目标对象生成的代理对象(Spring AOP通过动态代理实现)

       

       假如是aop:around类型的增强处理方法,可以使用ProceedingJoinPoint作为参数,

       ProceedingJoinPoint除了有上述的几个方法外,还有一个proceed()方法,替代目标方法执行.

       

   (3) 增强方法中,有普通类型的参数,

       比如public void access(Date time,String food, String retval)

       这种增强方法,必须要在pointcut中通过配置args 和 returning,保证参数正确绑定.

       (returning只针对aop:after-returning类型的增强处理,其他的可以省略)

       (即,增强方法中出现的参数名必须在pointcut配置中都得到明确的配置,否则报异常)

       pointcut="execution(*test.aop.*.*(..)) and args(food,time,..)"

       中args(food,time,..)中的food和time是参数名,来自切面类的增强方法,不能乱写,

       必须和切面类中增强方法的参数名称一致,在切面类的增强方法参数列表中必须能找到.

       因为在增强方法public void access(Date time,String food, String retval)中,time是Date类型的,

       food是String类型的,所以pointcut(切入点)定义中and args(food,time,..)符合and前面的规则的同时

       还要符合args(food,time,..)的规则.

       args(food,time,..)表是所有 第一个参数是String类型,第二个参数是Date类型的方法才能称为目标方法.

       .. 表示可以有第三个,第四个, ... , 第n个参数,但是至少有两个参数(String,Date)

       所以需要注意的有:

       a. 切面类中的增强方法参数,必须要在pointcut中有明确指定,比如

          public void access(Date time,String food, String retval)

          这个方法中三个参数food,和time通过args指定了,retval表示aop:after-returning定义的目标函数的返回值.

       b. 明确指定了参数后,AOP框架在运行时能正确绑定参数,因为:

          and args(food,time,..)表示 只对一类目标方法的调用做增强处理,这种目标方法是:在准备调用这种目标方法时,

          实际传递给它的参数为food和time所表示的类型(food和time必须在增强方法的参数列表中找到,这样就根据增强方法确定了food和time的类型).

          并且,传递参数的顺序也要是和args(food,time,..)中一致.这样在调用目标方法时,至少会按顺序传递food,time两个参数,

          AOP框架可以将这两个参数传递给 增强方法.

   

   (4) 增强方法中 有 JoinPoint和普通类型参数,

       则必须将JoinPoint类型的参数作为第一个参数,普通参数从第二个开始.

       其他的处理方式,按照上面(3)中仅含有普通参数的方式处理.

       

 主要代码;

Java代码  收藏代码
  1. package test.aop;  
  2.   
  3. import java.util.Date;  
  4.   
  5. /** 
  6.  *  
  7.  * 普通bean的接口 
  8.  * 
  9.  */  
  10. public interface Person  
  11. {  
  12.   String sayHello(String name);  
  13.   void eat(String food, Date time);  
  14.   void eat2(String food, Date time,String test);  
  15. }  

 

Java代码  收藏代码
  1. package test.aop;  
  2.   
  3. import java.util.Date;  
  4.   
  5. /** 
  6.  *  
  7.  *一个普通bean,eat方法和sayHello方法,是需要被切入,动态影响的 
  8.  * 
  9.  */  
  10. public class Chinese implements Person  
  11. {  
  12.   
  13.   @Override  
  14.   public void eat(String afood, Date atime)  
  15.   {  
  16.     System.out.println("正在吃: " + afood + ", 时间是: " + atime);  
  17.   }  
  18.   
  19.   @Override  
  20.   public String sayHello(String name)  
  21.   {  
  22.     return name + " Hello, Spring AOP.";  
  23.   }  
  24.     
  25.   public void eat2(String afood, Date atime,String test)  
  26.   {  
  27.     System.out.println("eat2 --------- 正在吃: " + afood + ", 时间是: " + atime + ", eat2里面的test= " + test);  
  28.   }  
  29.   
  30. }  

 

Java代码  收藏代码
  1. package test.aop.aspect;  
  2.   
  3. import java.util.Arrays;  
  4. import java.util.Date;  
  5.   
  6. import org.aspectj.lang.JoinPoint;  
  7.   
  8. /** 
  9.  *  
  10.  * 定义切面类,处理test.aop.Chinese.eat() 
  11.  * 
  12.  */  
  13. public class AccessArgAspect  
  14. {  
  15.     
  16.   //普通的 增强方法  
  17.   public void access(Date time,String food, String retval)  
  18.   {  
  19.     System.out.println("");  
  20.       
  21.     System.out.println("目标方法中 String 参数为: " + food);  
  22.     System.out.println("目标方法中 String 参数为: " + time);  
  23.     System.out.println("目标方法 返回值: " + retval);  
  24.       
  25.     System.out.println("模拟记录日志...");  
  26.       
  27.   }  
  28.     
  29.   /** 
  30.    * 第一个参数为JoinPoint类型的增强方法,JoinPoint必须为第一个参数 
  31.    * @param jp 
  32.    * @param time 
  33.    * @param food 
  34.    * @param retval 
  35.    */  
  36.   public void accessWithJoinPoint(JoinPoint jp,Date time,String food)  
  37.   {  
  38.     System.out.println("");  
  39.     System.out.println("JoinPoint.getArgs()获取参数列表:" + Arrays.toString(jp.getArgs()));  
  40.       
  41.     System.out.println("JoinPoint jp ---- 目标方法中 String 参数为: " + food);  
  42.     System.out.println("JoinPoint jp ---- 目标方法中 String 参数为: " + time);  
  43.       
  44.     System.out.println("JoinPoint jp ---- 模拟记录日志...");  
  45.       
  46.   }  
  47. }  

 

Java代码  收藏代码
  1. package test.aop;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import org.springframework.context.ApplicationContext;  
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  7.   
  8. /** 
  9.  *  
  10.  * AOP客户端测试类 
  11.  * 
  12.  */  
  13. public class TestClient  
  14. {  
  15.   public static void main(String[] args)  
  16.   {  
  17.     ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");  
  18.     System.out.println(ctx);  
  19.       
  20.     Person person = ctx.getBean("chinese_aop",Person.class);  
  21.       
  22.     person.sayHello("jack");  
  23.       
  24.     person.eat("米饭",new Date());  
  25.       
  26.     person.eat2("米饭",new Date(),"test");  
  27.   }  
  28. }  

 

Xml代码  收藏代码
  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.         xmlns:aop="http://www.springframework.org/schema/aop"  
  5.         xsi:schemaLocation="http://www.springframework.org/schema/beans    
  6.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  7.             http://www.springframework.org/schema/aop   
  8.             http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
  9.             http://www.springframework.org/schema/tx   
  10.             http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">   
  11.               
  12.             <!-- 小试牛刀 property使用 name,value-->  
  13.             <bean id="personService" class="test.spring.PersonService">  
  14.               <property name="name" value="wawa"></property>  
  15.             </bean>  
  16.               
  17.             <!--   
  18.                   设值注入  
  19.                 property使用 name,ref ,  
  20.                 ref也是一个bean的id,ref 可以在stoneAxe和steelAxe之间随意切换,而不用修改java代码   
  21.             -->  
  22.             <bean id="chinese" class="test.ioc.setter.Chinese">  
  23.               <property name="axe" ref="steelAxe"></property>  
  24.             </bean>  
  25.             <bean id="stoneAxe" class="test.ioc.setter.StoneAxe" />   
  26.             <bean id="steelAxe" class="test.ioc.setter.SteelAxe" />   
  27.               
  28.             <!--   
  29.                 构造注入  
  30.                 constructor-arg标签,ref ,  
  31.                 ref也是一个bean的id,ref 可以在stoneAxe和steelAxe之间随意切换,而不用修改java代码  
  32.                 constructor-arg 也可以配置value,表示传递给构造函数的是一个 普通的值,而不是另一个bean   
  33.             -->  
  34.             <bean id="chinese1" class="test.ioc.constructor.Chinese">  
  35.               <constructor-arg ref="steelAxe" />   
  36.             </bean>  
  37.               
  38.             <!-- 国际化 -->  
  39.            <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">  
  40.               <property name="basenames" >  
  41.                 <list>  
  42.                   <!-- 这里的value可带路径   -->  
  43.                   <value>message</value>  
  44.                 </list>  
  45.               </property>   
  46.             </bean>  
  47.               
  48.             <!--   
  49.               ApplicationContext的事件机制   
  50.                 在Spring中配置了实现ApplicationListener接口的Bean,  
  51.               Spring容器就会把这个Bean当成容器事件的监听器  
  52.             -->  
  53.             <bean class="test.springevent.EmainNotifier" />   
  54.               
  55.             <!-- bean中获取 ApplicationContext引用-->  
  56.             <bean name="beangetappcontext" class="test.bean.get.appcontext.BeanGetAppContext" />  
  57.               
  58.             <!-- AOP测试的chinese -->  
  59.             <bean id="chinese_aop" class="test.aop.Chinese" />  
  60.             <!-- 定义一个普通bean,作为切面bean -->  
  61.             <bean id="accessArgAspect" class="test.aop.aspect.AccessArgAspect" />  
  62.             <!-- AOP配置  -->   
  63.             <aop:config>  
  64.               <!-- 配置切面aspect -->  
  65.               <aop:aspect id="aspect" ref="accessArgAspect">  
  66.                 <aop:after-returning   
  67.                   pointcut="execution(* test.aop.*.*(..)) and args(food,time,..)"   
  68.                   method="access"  
  69.                   returning="retval"  
  70.                   arg-names="time,food,retval"   
  71.                 />  
  72.                   
  73.                 <aop:before   
  74.                   pointcut="execution(* test.aop.*.*(..)) and args(food,time,..)"   
  75.                   method="accessWithJoinPoint"  
  76.                 />  
  77.                   
  78.               </aop:aspect>   
  79.             </aop:config>  
  80.                
  81. </beans>   

 

工程文件注:

 

使用Spring 3.2.0的所有ja包,

3.2.0的srping包,做AOP需要依赖(Spring 3.2.0中去除了依赖包,需要自己找)

com.springsource.org.aopalliance-1.0.0.jar,下载地址http://ebr.springsource.com/repository/app/bundle/version/detail?name=org.springframework.aop&version=3.2.0.RELEASE

还有,3.0.2的com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar包,

下载3.0.2版本的依赖包以后,找

spring-framework-3.0.2.RELEASE-dependencies (1)\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE这个目录里面有      

          

附件中工程已包含所有需要的jar包

         

分享到:
评论

相关推荐

    Spring Aop Advise方法(增强方法) 中获取目标方法的参数

    这篇博客文章“Spring Aop Advise方法(增强方法) 中获取目标方法的参数”可能详细解释了如何在Advise中获取被拦截方法的参数。为了深入理解这个主题,我们需要探讨以下几个关键知识点: 1. **AOP的基本概念**: - ...

    第四章:Spring AOP API 设计模式1

    11. **模板方法模式(Template Method)**:在Spring AOP中,模板方法模式可能体现在一些基类中,定义了操作的基本步骤,并允许子类在特定步骤中进行扩展。 12. **责任链模式(Chain of Responsibility)**:Spring...

    Spring基础:Spring AOP简单使用

    在Spring中,AOP通过代理模式实现,可以分为JDK动态代理和CGLIB代理两种方式。 1. **AOP概念** - **切面(Aspect)**:切面是关注点的模块化,比如日志、安全检查等,它将分散在代码各处的相同关注点集中在一起。 ...

    在自定义spring aop中使用el获取拦截方法的变量值。

    标题中的“在自定义Spring AOP中使用EL获取拦截方法的变量值”指的是在Spring的面向切面编程(AOP)中,通过Expression Language(EL,表达式语言)来访问被拦截方法的局部变量值。这通常涉及到Spring的代理机制、...

    spring-aop-5.0.10.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.0.10.RELEASE.jar; 赠送原API文档:spring-aop-5.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.10.RELEASE....

    基于java的企业级应用开发:Spring AOP简介.ppt

    **Spring AOP 简介** 面向切面编程(AOP),全称为 Aspect-Oriented Programming,是一种编程范式,旨在解决传统面向对象编程(OOP)中的代码重复和分散问题。在OOP中,诸如事务管理、日志记录等功能往往会分散在多...

    hualinux spring 3.15:Spring AOP.pdf

    根据提供的文件内容,可以提取出以下知识点: ...文档中提到的实践示例,例如前置通知、后置通知、返回通知、异常通知和环绕通知的具体编码实现,都是通过具体的代码示例来说明如何在Spring中应用AspectJ进行AOP编程。

    Spring AOP面向方面编程原理:AOP概念

    ### Spring AOP面向方面编程原理:AOP概念详解 #### 一、引言 随着软件系统的日益复杂,传统的面向对象编程(OOP)逐渐暴露出难以应对某些横切关注点(cross-cutting concerns)的问题。为了解决这一挑战,面向方面编程...

    Java利用spring aop进行监测方法执行耗时

    使用 Spring AOP 进行方法耗时监测的好处有以下几点: 1. 代码实现简单,易于维护:使用 Spring AOP 可以将耗时监测的逻辑与业务逻辑进行解耦,避免业务逻辑代码的冗余和代码维护难度的提高。 2. 安全性高:使用 ...

    第二章:Spring AOP 基础1

    在本章"Spring AOP 基础1"中,我们主要探讨了Spring AOP(面向切面编程)的核心概念和实现方式。AOP是一种编程范式,它允许程序员定义"切面",这些切面封装了跨越多个对象的横切关注点,如日志、事务管理等。以下是...

    第五章:Spring AOP 在 Spring Framework 内部应用1

    Spring AOP,即Aspect Oriented Programming(面向切面编程),是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下对程序进行功能增强的技术。本章主要探讨了Spring AOP在Spring框架内部的多种应用,...

    spring-aop-5.2.0.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.2.0.RELEASE.jar; 赠送原API文档:spring-aop-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.2.0.RELEASE.pom;...

    第三章:Spring AOP API 设计与实现1

    Spring AOP API 设计与实现是Spring框架的重要组成部分,它提供了面向切面编程的能力,使得开发者可以在不修改源代码的情况下,对程序进行横切关注点的处理,如日志记录、事务管理等。本章主要涵盖了Spring AOP的多...

    AspectJ in Action: Enterprise AOP with Spring Applications

    ### AspectJ in Action: Enterprise AOP with Spring Applications #### 关键知识点概述 1. **Spring-AspectJ集成:**本书重点介绍了Spring框架与AspectJ相结合的技术优势及其在企业级应用中的强大功能。 2. **...

    spring aop 学习笔记

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和抽象化的方法来处理系统中的交叉关注点,如日志、事务管理、安全性等。本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际...

    spring aop jar 包

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...

    Spring源码最难问题:当Spring AOP遇上循环依赖.docx

    在Spring中,bean的实例化过程中,会先尝试从三级缓存中获取bean,这也是Spring解决循环依赖的开始。在AbstractBeanFactory的doGetBean方法中,可以看到Spring是如何实现三级缓存的。 首先,Spring会尝试从一级缓存...

    spring-aop实例

    6. **引入(Introduction)**:Spring AOP允许在现有类中添加新的方法或属性,这称为类型引入。这可以用于向旧的非AOP类添加新行为,例如添加日志或事务支持。 7. **配置方式**:Spring AOP可以通过XML配置、注解...

    spring-aop-5.0.8.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.0.8.RELEASE.jar; 赠送原API文档:spring-aop-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.8.RELEASE.pom;...

    springboot+aspect实现springaop拦截指定方法.zip

    SpringBoot结合AspectJ实现SpringAOP拦截指定方法的知识点涵盖了多个方面,这包括Spring AOP的基本概念、SpringBoot的应用、切点(Pointcut)与通知(Advice)的定义、自定义注解以及AspectJ的使用。以下是这些知识...

Global site tag (gtag.js) - Google Analytics