spring Aop 关于arg-name的一些理解

时间:2024-05-22 17:32:10

spring aop中有些参数比较难以理解 比如说arg-names,下面先从简单说起:

Aop类

Java代码  spring Aop 关于arg-name的一些理解
  1. /** 
  2.  * 需要织入的类,及其方法。 
  3.  * @author ChdYan 
  4.  * @since jdk1.6 
  5.  */  
  6. public class TestAop {  
  7.   
  8.     /** 
  9.      * 在目标方法前织入的方法 
  10.      * @param i 测试参数 
  11.      * @param name 测试参数 
  12.      * @param p 测试参数 
  13.      */  
  14.     public void before(String name, int age, String address)  {  
  15.         System.out.println(name + "," + age + "," + address);  
  16.         System.out.println("--------------开始啦before------------");  
  17.     }  
  18.       
  19.     /** 
  20.      * 在目标方法返回前织入的方法 
  21.      * @param i 
  22.      * @param name 
  23.      * @param p 
  24.      */  
  25.     public void after(String name, int age, String address)  {  
  26.         System.out.println(name + "," + age + "," + address);  
  27.         System.out.println("--------------开始啦after------------");  
  28.     }  
  29.       
  30.     /** 
  31.      * 在目标方法前后织入的方法 
  32.      * @param pjp 
  33.      * @param name 
  34.      * @param age 
  35.      * @throws Throwable 
  36.      */  
  37.     public void around(ProceedingJoinPoint pjp) throws Throwable {  
  38.         System.out.println(Arrays.toString(pjp.getArgs()));  
  39.         System.out.println("--------------开始啦around------------");  
  40.         pjp.proceed(pjp.getArgs());  
  41.         System.out.println("--------------结束啦around------------");  
  42.     }  
  43.       
  44.       
  45.     /** 
  46.      * 在目标方法返回后后织入的方法 
  47.      * @param name 
  48.      */  
  49.     public void afterReturning(String name){  
  50.         System.out.println("======after Return==== " + name);  
  51.     }  
  52.       
  53.     /** 
  54.      * 在目标方法返回后后织入的方法 
  55.      * @param name 
  56.      */  
  57.     public void afterThrowing(Exception e){  
  58.         System.out.println("======after Return====e " + e);  
  59.     }  
  60.   
  61. }  

 befor、after里都有三个参数。下面看需要织入的类

Java代码  spring Aop 关于arg-name的一些理解
  1. /** 
  2.  * 简单测试类,测试织入增强。 
  3.  * @author ChdYan 
  4.  <a href="mailto:*@since">* @since</a> jdk1.6 
  5.  */  
  6. public class User {  
  7.       
  8.     private String username;  
  9.   
  10.     /** 
  11.      * 需要织入的方法 
  12.      * @param name 名字 
  13.      * @param age 姓名 
  14.      * @param address 地址 
  15.      * @return 用户名称 
  16.      */  
  17.     public String getUsername(String name, int age, String address) {  
  18.         System.out.println("------------调用方法开始:-------");  
  19.         System.out.println(name + "----" + age + "----" + address);  
  20.         System.out.println("------------调用方法结束:-------");  
  21.         return username;  
  22.     }  
  23.       
  24.     /** 
  25.      * 需要织入的方法 
  26.      * @param name 名称 
  27.      * @return 用户名称 
  28.      */  
  29.     public String getUsername(String name) {  
  30.         System.out.println("------------调用方法开始:-------");  
  31.         System.out.println(name + "----");  
  32.         System.out.println("------------调用方法结束:-------");  
  33.         if(1 == 1) {  
  34.             throw new RuntimeException();  
  35.         }  
  36.         return username;  
  37.     }  
  38.   
  39.     public void setUsername(String username) {  
  40.         this.username = username;  
  41.     }  
  42.       
  43.   
  44. }  

 

织入类比较简单,明白意思就行。

Xml代码  spring Aop 关于arg-name的一些理解
  1. <bean class="cn.g.model.User" id="user">  
  2.     <property name="username" value="zhangshan"></property>  
  3. </bean>  
  4. <bean id="aopTest" class="cn.g.aop.TestAop"></bean>  
  5. <aop:config proxy-target-class="true">  
  6.     <aop:pointcut expression="execution(* cn.g.model.*.get*(..)) and args(arg1, arg2, arg3)" id="acut"/>  
  7.     <aop:aspect ref="aopTest">  
  8.         <aop:before method="before" pointcut-ref="acut" arg-names="arg1, arg2, arg3"/>  
  9.         <aop:after method="after" pointcut-ref="acut" arg-names="arg1, arg2, arg3"/>  
  10.         <aop:around method="around" pointcut="execution(* cn.g.model.*.get*(..))"/>  
  11.         <aop:after-returning method="afterReturning" pointcut="execution(* cn.g.model.*.get*(..))" returning="arg" arg-names="arg"/>  
  12.         <aop:after-throwing method="afterThrowing" pointcut="execution(* cn.g.model.*.get*(..))"  throwing="arg" arg-names="arg"/>  
  13.     </aop:aspect>  
  14. </aop:config>  

 

expression="execution(* cn.g.model.*.get*(..)) and args(arg1, arg2, arg3)"  args在这里是作为织入方法的入参,所以其个数与类型需要与织入方法一致,并且与在<aop:before与<aop:after中的增强也要一致的,才能织入。主要原因是:1.方法前织入增强也只是知道方法入参,其他参数一概获取不到,那么只能用方法参数作为args的入参了。2.同样,方法后织入增强也是只知道方法的参数,其他一概不知。。

 

<aop:around 通知的入参 ProceedingJoinPoint pjp由spring自动注入,ProceedingJoinPoint pjp所含了所有的入参与目标方法等,所以不必增加像<aop:before中的arg-names和expression中也不必包含

 

 <aop:after-returning 中增强的入参只有一个,就是织入方法的返回值,类型、个数要一致,所以很好理解。

 

<aop:after-throwing  同  <aop:after-returning  一样,增强中也只有一个入参且就是抛出的异常,所以类型、个数要一致,这也比较好理解

 

 

Java代码  spring Aop 关于arg-name的一些理解
  1. /** 
  2.  * 测试类 
  3.  * @author ChdYan 
  4.  * @since jdk1.6 
  5.  */  
  6. public class TestAop {  
  7.     public static void main(String[] args) {  
  8.         ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");  
  9.         User user = ctx.getBean(User.class);  
  10.         System.out.println(user.getUsername("romico"25"china"));  
  11.         System.out.println(user.getUsername("romico"));  
  12.     }  
  13. }  

 

 最后结果如图

 

 
spring Aop 关于arg-name的一些理解
 

相关文章