随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

 

execution:匹配方法执行连接点

 

modifiers-pattern:访问权限符(可以不写)

ret-type-pattern:方法返回值(没有就是void)【*:代表所有的返回值】

declaring-type-pattern:包名.类名【*:代表任何包名或类名】【..:代表任何子包】

name-pattern:方法名称【*:代表任何方法名】

param-pattern:方法参数【..:代表任何参数】

throws-pattern:异常(可以不写)

 

?:可选(可写可不写)

 

例如:

切入的是cn.cdulm.service.impl包下的UserServiceImpl类中的select()方法:

表达式应该是:

execution(public cn.cdulm.entity.User cn.cdulm.service.impl.UserServiceImpl.add(Integer))

如果返回值是jdk本身的,比如Integer,那么直接写Integer就行了,不用写完整的限定名。

但是如果是自定义的类,比如自定义的User类,那么在返回值中就必须写包名.User。

:方法的参数中同理。

 

还有其它的匹配方式:

within:只能匹配类这级,只能指定类,类下面的某个具体的方法无法指定

this:在bean引用(Spring AOP代理)是给定类型的实例的情况下,限制匹配连接点(使用Spring AOP时方法的执行)。

target:限制匹配到连接点(使用Spring AOP时方法的执行),其中目标对象(正在代理的应用程序对象)是给定类型的实例。

args:限制与连接点的匹配(使用Spring AOP时方法的执行),其中变量是给定类型的实例。AOP) where the arguments are instances of the giventypes.

@target:限制与连接点的匹配(使用Spring AOP时方法的执行),其中执行对象的类具有给定类型的注解

@args:限制匹配连接点(使用Spring AOP时方法的执行),其中传递的实际参数的运行时类型具有给定类型的注解。

@within:限制与具有给定注解的类型中的连接点匹配(使用Spring AOP时在具有给定注解的类型中声明的方法的执行)。

@annotation:限制匹配连接点(在Spring AOP中执行的方法具有给定的注解)。

比如自定义一个范围为class的注解@Fun,然后使用@annotation(java.lang.Fun),就是匹配所有添加了@Fun注解的方法。

需要注意的是像@Override这类注解是只生效与java文件的,是无法使用@annotation()来匹配的。

 

 

更多例子查看中文文档:

https://github.com/DocsHome/spring-docs/blob/master/pages/core/aop.md#aop

 

合并切点表达式:

您可以使用 &&、||、! 等符号进行合并操作。也可以通过名字来指向切点表达式。

 

 

通知方法的执行顺序:

1、正常执行:@Before--->@After--->@AfterReturning
2、异常执行:@Before--->@After--->@AfterThrowing

 

表达式的抽取:

    @Pointcut("execution(* cn.cdulm.service.impl.*.*(..))")
    public void pointcut(){}

定义一个方法,将表达式通过@Pointcut注入,那么后面的表达式只需要填入方法就行了:

// 前置通知
    @Before("pointcut()")
    public void before(){
        System.out.println("前置通知");
    }
    // 后置通知
    @After("pointcut()")
    public void after(){
        System.out.println("后置通知");
    }
    // 后置异常通知
    @AfterThrowing("pointcut()")
    public void afterThrowing(){
        System.out.println("后置异常通知");
    }

    // 后置返回通知
    @AfterReturning("pointcut()")
    public void afterReturning(){
        System.out.println("后置返回通知");
    }

 

posted on 2022-06-01 17:16  时间完全不够用啊  阅读(179)  评论(0编辑  收藏  举报