首页 > 其他分享 >Spring AOP中@Pointcut切入点表达式详解

Spring AOP中@Pointcut切入点表达式详解

时间:2023-01-20 10:01:32浏览次数:47  
标签:匹配 Spring args bean Pointcut AOP 注解 方法

目录

一、瞅一眼标准的AspectJ Aop的pointcut的表达式

二、SpringAop的十一种AOP表达式

三、演示使用

1、execution:

2、within:

3、this:

4、target:

5、args:

6、@target:

7、@args:

8、@within:

9、@annotation:

10、reference pointcut:

11、bean:

四、类型匹配语法

五、表达式的组合


一、瞅一眼标准的AspectJ Aop的pointcut的表达式

标准的AspectJ Aop的pointcut的表达式类型是很丰富的

见org.aspectj.weaver.tools.PointcutPrimitive
这个枚举类:

二、SpringAop的十一种AOP表达式

SpringAop只支持标准的AspectJ Aop的pointcut的表达式类型其中的10种,外加Spring Aop自己扩充的一种一共是11(10+1)种类型的表达式,分别如下。

1.execution:一般用于指定方法的执行,用的最多。
2.within:指定某些类型的全部方法执行,也可用来指定一个包。
3.this:Spring Aop是基于动态代理的,生成的bean也是一个代理对象,this就是这个代理对象,当这个对象可以转换为指定的类型时,对应的切入点就是它了,Spring Aop将生效。
target:当被代理的对象可以转换为指定的类型时,对应的切入点就是它了,Spring Aop将生效。

4.reference pointcut:(经常使用)表示引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持
5.args:当执行的方法的参数是指定类型时生效。
6.@args:当执行的方法参数类型上拥有指定的注解时生效。
7.@within:与@target类似,看官方文档和网上的说法都是@within只需要目标对象的类或者8.父类上有指定的注解,则@within会生效,而@target则是必须是目标对象的类上有指定的注解。而根据笔者的测试这两者都是只要目标类或父类上有指定的注解即可。
9.@annotation:当执行的方法上拥有指定的注解时生效。
10.@target:当代理的目标对象上拥有指定的注解时生效。
11.bean:当调用的方法是指定的bean的方法时生效。(Spring AOP自己扩展支持的)

注意Pointcut定义时,还可以使用&&、||、! 这三个运算。进行逻辑运算。可以把各种条件组合起来使用

三、演示使用

1、execution:

execution是使用的最多的一种Pointcut表达式,用于切方法。

  1. //表示匹配所有方法
  2. 1)execution(* *(..))
  3. //表示匹配com.lasse.UserService中所有的公有方法
  4. 2)execution(public * com.lasse.UserService.*(..))
  5. //表示匹配com.fsx.run包及其子包下的所有方法
  6. 3)execution(* com.lasse..*.*(..))

当我们的切面很多的时候,我们可以把所有的切面放到单独的一个类去,进行统一管理,比如下面:

  1. //集中管理所有的切入点表达式
  2. public class Pointcuts {
  3. @Pointcut("execution(* *Message(..))")
  4. public void logMessage(){}
  5. 。。。
  6. }

引用方式

  1. @Before("com.lasse.Pointcuts.logMessage()")
  2. public void before(JoinPoint joinPoint) {
  3. System.out.println("do something");
  4. }

2、within:

within是用来指定类型的,指定类型中的所有方法将被拦截。不拦截其子类,所以切接口没用。

  1. //此处只能写实现类
  2. @Pointcut("within(com.lasse.service.impl.AServiceImpl)")
  3. public void pointCut() {
  4. }
  5. //匹配包以及子包内的所有类
  6. @Pointcut("within(com.lasse.service..*)")
  7. public void pointCut() {
  8. }

3、this:

Spring Aop是基于代理的,this就表示代理对象。this类型的Pointcut表达式的语法是this(type),当生成的代理对象可以转换为type指定的类型时则表示匹配。基于JDK接口的代理和基于CGLIB的代理生成的代理对象是不一样的。

  1. // 拦截到AService所有的子类的所有外部调用方法
  2. @Pointcut("this(com.lasse.service.AService*)")
  3. public void pointCut() {
  4. }

4、target:

Spring Aop是基于代理的,target则表示被代理的目标对象。当被代理的目标对象可以被转换为指定的类型时则表示匹配。
注意:和上面不一样,这里是target,因此如果要切入,只能写实现类了

  1. @Pointcut("target(com.lasse.service.impl.AServiceImpl)")
  2. public void pointCut() {
  3. }

5、args:

args用来匹配方法参数的。

    1、“args()”匹配任何不带参数的方法。
    2、“args(java.lang.String)”匹配任何只带一个参数,而且这个参数的类型是String的方法。
    3、“args(…)”带任意参数的方法。
    4、“args(java.lang.String,…)”匹配带任意个参数,但是第一个参数的类型是String的方法。
    5、“args(…,java.lang.String)”匹配带任意个参数,但是最后一个参数的类型是String的方法。
 

  1. @Pointcut("args()")
  2. public void pointCut() {
  3. }

6、@target:

@target匹配当被代理的目标对象对应的类型及其父类型上拥有指定的注解时。

  1. //能够切入类上(非方法上)标准了@MyAnno注解的所有外部调用方法
  2. @Pointcut("@target(com.lasse.anno.MyAnno)")
  3. public void pointCut() {
  4. }

7、@args:

@args匹配被调用的方法上含有参数,且对应的参数类型上拥有指定的注解的情况。
例如:

  1. // 匹配**方法参数类型上**拥有MyAnno注解的方法调用。
  2. //如我们有一个方法add(MyParam param)接收一个MyParam类型的参数,而MyParam这个类是拥有注解MyAnno的,则它可以被Pointcut表达式匹配上
  3. @Pointcut("@args(com.lasse.anno.MyAnno)")
  4. public void pointCut() {
  5. }

8、@within:

@within用于匹配被代理的目标对象对应的类型或其父类型拥有指定的注解的情况,但只有在调用拥有指定注解的类上的方法时才匹配。

“@within(com.fsx.run.anno.MyAnno)”匹配被调用的方法声明的类上拥有MyAnno注解的情况。比如有一个ClassA上使用了注解MyAnno标注,并且定义了一个方法a(),那么在调用ClassA.a()方法时将匹配该Pointcut;如果有一个ClassB上没有MyAnno注解,但是它继承自ClassA,同时它上面定义了一个方法b(),那么在调用ClassB().b()方法时不会匹配该Pointcut,但是在调用ClassB().a()时将匹配该方法调用,因为a()是定义在父类型ClassA上的,且ClassA上使用了MyAnno注解。但是如果子类ClassB覆写了父类ClassA的a()方法,则调用ClassB.a()方法时也不匹配该Pointcut。

9、@annotation:

使用得也比较多

@annotation用于匹配方法上拥有指定注解的情况。

  1. // 可以匹配所有方法上标有此注解的方法
  2. @Pointcut("@annotation(com.lasse.anno.MyAnno)")
  3. public void pointCut() {
  4. }
  5. //或者:非常方便的获取到方法上面的注解
  6. @Before("@annotation(myAnno)")
  7. public void doBefore(JoinPoint joinPoint, MyAnno myAnno) {
  8. System.out.println(myAnno); //@com.lasse.anno.MyAnno()
  9. System.out.println("AOP Before Advice...");
  10. }

10、reference pointcut:

切入点引用(使用得非常多)

  1. @Aspect
  2. public class HelloAspect {
  3. @Pointcut("execution(* com.lasse.service.*.*(..)) ")
  4. public void point() {
  5. }
  6. // 这个就是一个`reference pointcut` 甚至还可以这样 @Before("point1() && point2()")
  7. @Before("point()")
  8. public void before() {
  9. System.out.println("this is from HelloAspect#before...");
  10. }
  11. }

11、bean:

这是Spring增加的一种方法,spring独有

bean用于匹配当调用的是指定的Spring的某个bean的方法时。
1、“bean(abc)”匹配Spring Bean容器中id或name为abc的bean的方法调用。
2、“bean(user*)”匹配所有id或name为以user开头的bean的方法调用。
 

  1. // 这个就能切入到AServiceImpl类的所有的外部调用的方法里
  2. @Pointcut("bean(AServiceImpl)")
  3. public void pointCut() {
  4. }

四、类型匹配语法

1、*:匹配任何数量字符;
2、…:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
3、+:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。

五、表达式的组合

表达式的组合其实就是对应的表达式的逻辑运算,与、或、非。可以通过它们把多个表达式组合在一起。
1、“bean(userService) && args()”匹配id或name为userService的bean的所有无参方法。
2、“bean(userService) || @annotation(MyAnnotation)”匹配id或name为userService的bean的方法调用,或者是方法上使用了MyAnnotation注解的方法调用。
3、“bean(userService) && !args()”匹配id或name为userService的bean的所有有参方法调用。

标签:匹配,Spring,args,bean,Pointcut,AOP,注解,方法
From: https://www.cnblogs.com/mihutao/p/17062449.html

相关文章

  • SpringCloud Sleuth链路追踪
    1、概要一般的,一个分布式服务跟踪系统,主要有三部分:数据收集数据存储数据展示然而这三个部分其实不都是由SpringCloudSleuth(下面我简称为Sleuth)完成的,Sleuth负责数......
  • 学习笔记——@PathVariable注解基本使用;@PathVariable注解属性;REST风格CRUD概述;实现PU
    2023-01-19一、@PathVariable注解基本使用1、获取URL中占位符2、占位符语法:{}3、实例代码:@RequestMapping("testPathVariable/{empId}")publicStringtestPath......
  • day06-Spring管理Bean-IOC-04
    Spring管理Bean-IOC-043.基于注解配置bean3.1基本使用3.1.1说明基本说明:基于注解的方式配置bean,主要是项目开发中的组件,比如Controller,Service和Dao组件的注解形式有:......
  • 42-Springboot整合HignLevelClient----构建复杂检索
    @Test voidsearchTest()throwsIOException{ SearchRequestsearchRequest=newSearchRequest(); //1、指定索引 searchRequest.indices("bank"); //2.1、......
  • SpringMVC异常处理
    简介系统中异常包括:编译时异常和运行时异常RuntimeException;编译异常就是检查异常,需要捕获;运行时异常可以捕获也可以不捕获。 异常处理思路在springmvc中,异常处理的......
  • Spring Security XML示例
    SpringSecurityXML示例在本教程中,我们将使用SpringMVC 框架实现 SpringSecurity。所有示例都是SpringMVC,并且是使用Maven项目创建的。我们使用的是 SpringSecur......
  • SpringCloud Stream消息驱动
    简单搭建,没有技术含量,Demo可用1、介绍①产生原因RabbitMQ、RocketMQ、Kafka、ActiveMQ在一个项目中,可能存在多种不同的MQ,在不同的MQ中,切换维护开发都很麻烦。如果你......
  • Spring security模块
    在SpringSecurity3.0中,"安全性"模块分为单独的jar文件。目的是根据jar文件的功能进行划分,以便开发人员可以根据其要求进行集成。这还有助于将所需的依赖项设置为maven项......
  • 基于springboot的景区旅游信息管理系统(源代码+数据库)
    基于springboot的景区旅游信息管理系统(源代码+数据库)一、系统介绍本项目分为管理员与普通用户两种角色用户登录前台功能:旅游路线、旅游景点、旅游酒店、旅游车票、......
  • springboot整合minio
    代码参考GitHub地址安装minio1、进入官网:https://min.io/我目前安装的是版本是:在cmd窗口中,命令行进行minio.exe所在的文件夹,输入如下命令server后面的地址是你......