spring aspectj 切入点表达式详解

1 切入点表达式

  

  切人点表达式可以按照 修饰注解和修饰和非注解分成2类,带有@的是匹配注解的,没有代@的是匹配非注解的

  within 用于限定类型,args 用于限定参数,target 指的限定类型和子类,this 指的调用者类型

  

 

  1 execution

    匹配 指定修饰符 指定返回值类型 指定包 指定类名 指定方法名 指定参数 指定申明异常   的方法

   

    例子1:execution(* com.lomi.aspectj.Fan.*(..))  表示  Fan和他子类 下面的所有方法

    例子2:execution(* com.lomi..Fan.*(..))    表示 com.lomi包和子包下面 Fan和他子类 下面的所有方法

    例子3:execution(String com.lomi.aspectj.Fan.*(..))   表示 Fan和他子类 下面的所有方法 并且这个方法返回值是 String

    例子4:execution(public String com.lomi.aspectj.Fan.*(..)) 表示 Fan和他子类 下面的所有方法 并且这个方法返回值是 String,并且权限修饰符 是 public

    例子5: execution(protected * com.lomi.aspectj.Fan.*(..))  需要 是 protected  的方法

    例子6: execution(protected * com.lomi.aspectj.Fan.*(..)) throws IllegalArgumentException) 指明声明的异常

    例子7:不能这么写 execution(* String com.lomi.aspectj.Fan.*(..))  不指定访问修饰符只指定返回值 只能写成  execution( String com.lomi.aspectj.Fan.*(..))

    例子8:不能这么写 execution(* * com.lomi.aspectj.Fan.*(..))  不能这么写 ,只能写成 execution( * com.lomi.aspectj.Fan.*(..))

    

    备注1: execute 功能强大,读的时候可以从方法后面向前面读,会匹配到子类,上面例子2,靠近(..)的*是方法,方法前面是类名,在前面就是包名

    备注2:包权限怎么写?只能通过不等于排除吗?

    备注3: 权限修饰符 private 可以写,但是 自身调用无效,反射修改可见性以后,调用也无效,存在的意思是啥?

      备注4: 权限修饰符和返回值的写法

           同时都限定,public String 格式

        只有权限修饰符 不限定返回值, 写成 public * 格式

        只有 返回值限定不限制 修饰符,修饰符位置必须啥都不写 只能写成

        两个都不限定的时候,只能写 一个* 表示都不限定

    备注5:只有execution 才能写 修饰符,返回值,参数,别的只能写 类型或者参数,不能写其他

  

  2 within  只能写明确的类型

    匹配指定类型 ,不包含子类型,只有自身( 不能指定具体那个方法,不能指定方法修饰符,返回值,参数 )

    例子: whin( com.lomi.Uservice )

 

  3 args    只能写参数

    匹配方法参数满足指定条件

     例子1:args()

     例子2:args(..)

               例子3:args(String,..)

              例子4:args(..,String)

              例子5:args(Object,String,Object)

  4 target  只能写明确的类型

    动态匹配 方法定义在那个类里面的,包含子类型(运行时匹配)( 不能指定具体那个方法,不能指定方法修饰符,返回值,参数 )

    例子:target  ( com.lomi.Uservice )

 

  5 this  只能写明确的类型

     this 指向是 代理对象的类型判断, 和 target 的区别在于 target 是代理目标对象的类型判断( 使用 cglib 代理的时候 this 和 tager 类型判断结果是一样的,使用 jdk 动态代理的时候 this 不能匹配代实现类的类型)

     

     备注:jdk 动态代理的 的代理类 instanceof 实现类 返回 false , instanceof 代理接口 返回 true。

     备注:cglib 动态代理的 的代理类 instanceof 实现类 返回 true, instanceof 代理接口 也返回 true。

    

 

  ---------------------------------------------------------@开头的都是描述注解,也是一样只能写确定的注解类型-----------------------------------------------

  6 @annotation

    匹配  带有指定注解的 方法(指定方法上面有指定注解)

  

  7 @within

    匹配 带有指定注解的类(指的是这个类上面有指定的注解)

 

  8 @args

    匹配 参数里面带有指定注解的 方法 (匹配参数带有的注解)

 

  9 @target

    匹配 带有间接指定注解的类 (父类上写了注解并且这个注解带有继承的源注解)好像和引介增强有关系

 

  

 

 

 

2 通配符

  1 * 

    表示指定位置的任意值(可以是 包名,类名,方法名,参数类型 , 方法返回值,方法限定符)

  

  2 ..

   表示 所有子包 或者 任意多个参数

  

  3 +

    表示 指定类和子类,感觉只有 within 才有效果,within 默认是确定类型,不包括子类,别的都包含当前类型和子类型

    within(com.lomi.aspectj.WindProducer+) 等价于 target(com.lomi.aspectj.WindProducer)

 

 

3 多个切人点表达式可以通过   &&   ||    !  来实现任意的组合,并且官方建议尽量使用超过一个的切人点表达式来确定 一个切人点,据说这样效率比较高。

 

  例如  "within(com.lomi.UserService)&&args(String)" 

  UserService里面 只有一个 String参数的 方法

 

 

4 aspectj 5种连接点

 

  1.@Before(前置增强)


  2.@After(后置增强)


  3.@AfterReturning(返回增强)


  4.@AfterThrowing(异常增强)


  5.@Around(环绕增强)

  

5 引介增强

  通过  DelegatingIntroductionInterceptor类 在不修改源码,只修改xml配置文件 就能做到 给指定类添加增强方法,和普通代理的区别在于普通代理只能给方法增强,引介增强可以添加新的拓展方法或者属性。

 下面的配置 给  target 动态的添加了 controlAdvice 的增强,forumService 可以强制装换成 目标类和增强类接口

<bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"
          p:interfaces="com.testApi.yinZhiAdvice.Monitor"        //拓展方法的接口定义,forumServer可以强制转成这个接口类型,也可以转换成target类型
          p:interceptorNames="controlAdvice"             //增强逻辑类,里面写着增强逻辑
          p:target-ref="target"                    //目标类,也就是被增强的类
          p:proxyTargetClass="true"/>

  

 

posted on 2022-07-16 14:44  zhangyukun  阅读(349)  评论(0编辑  收藏  举报

导航