【Spring】AOP切点表达式

news2024/12/27 11:17:19

文章目录

  • 1、语法
  • 2、通配符
  • 3、execution
  • 4、within
  • 5、@annotation
  • 6、args
  • 7、@args
  • 8、bean
  • 9、this
  • 10、target
  • 11、@target
  • 12、@within
  • 13、表达式组合
  • 14、补充

在这里插入图片描述

1、语法

动作关键词(访问修饰符 返回值 包名.类/接口名 .方法名(参数)异常名)

举例:

execution(public User com.llg.service.Uservice.findById(int))
  • 动作关键字:描述切入点的行为动作,execution即执行到指定切入点
  • 方法修饰符:public、private等可以省略
  • 返回值
  • 包名
  • 类/接口名
  • 参数
  • 异常名:方法定义中抛出指定异常,可以省略

2、通配符

使用通配符来描述切入点,提高效率:

  • * 代表单个独立的任意符号,可以独立出现,也可做为前缀或后缀匹配符。
execution(public * com.llg.*.UserService.find* (*))

以上代表匹配com.llg包下得任意包中得UserService类或接口中所有find开头得带有一个参数(注意不是无参数)、返回类型任意的public方法

  • . .即多个连续的任意符号,可独立出现,常用于简化包名与参数的书写
execution(public User com..UserService.findById(..))

以上代表匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法 (形参个数无所谓)

  • + 用于专门用于匹配子类类型
execution(* *..*Service+.*(..))

3、execution

最常用,表达式中是一个方法。举例:

  • 匹配所有的不带参数的add()方法
execution(* add())
  • 匹配所有抛出Exception的方法
execution(* *(..) throws Exception)

写个简单的完整例子:

//通知类
@Component
@Aspect
public class CutAdvice {


    @Pointcut("execution(* *..MyService.myExecution(..))")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void beforeSome(){
        System.out.println("前置AOP成功");
    }
}
//即将匹配到被增强的切点方法
@Service
public class MyService {
    public void myExecution(){

        System.out.println("execution ...");
    }
}

调用下这个切点方法,看到AOP增强成功:

在这里插入图片描述

4、within

根据一个类来匹配,这个类中的所有方法将被匹配为切点,并被拦截增强。

  • 匹配UserServiceImpl类对应对象的所有方法外部调用,而且这个对象只能是UserServiceImpl类型,不能是其子类型
within(com.llg.service.UserServiceImpl)
  • 匹配com.llg包及其子包下面所有的类的所有方法的外部调用
within(com.elim..*)

写个例子展示下效果:

//通知类
@Component
@Aspect
public class CutAdvice {


    @Pointcut("within(cn.llg.user.service.MyService)")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void beforeSome(){
        System.out.println("MyService中的方法即将被调用,前置AOP成功");
    }
}
//即将匹配到的类
@Service
public class MyService {

    public void methodOne(){
        System.out.println("MyService类中的methodOne方法");
    }

    public void methodTwo(){
        System.out.println("MyService类中的methodTwo方法");
    }
}

调用MyService类中的两个方法,看到这两个方法均被增强:

在这里插入图片描述

5、@annotation

根据注解来匹配,用于匹配方法上拥有指定注解的情况

  • 匹配所有的方法上拥有MyAnnotation注解的方法
@annotation(com.llg.service.MyAnnotation)

按注解匹配切点,还可以通知类中获取注解的属性,贴个例子:

@Component
@Aspect
public class RedisAdvice {

    @Pointcut("@annotation(org.springframework.cache.annotation.Cacheable)")
    public void redisCut(){

    }
    

    //Cacheable redisInfo
    @Around("redisCut() &&@annotation(redisInfo)")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint,Cacheable redisInfo) throws Throwable {
        //获取属性
        StringBuilder redisKey = new StringBuilder(redisInfo.key()).append("::").append(redisInfo.value()[0]);

        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        String methodName = signature.getName();
        // ....
        Object ret = proceedingJoinPoint.proceed();
        return ret;
	}

}

获取切点表达式注解的属性,跳这篇【用AOP拦截注解并获取注解属性值】

6、args

按方法的参数匹配,即增强形参符合表达式的方法

  • 匹配并增强任何不带参数的方法
args()
  • 匹配并增强带任意个参数的方法(等于是全员增强了)
args(..)
  • 匹配并增强只有一个形参,且类型为String的方法
args(java.lang.String)
  • 匹配并增强形参有任意个,但第一个类型为String的方法
args(java.lang.String,..)
  • 匹配并增强形参有任意个,但最后一个参数为String类型的方法
args(..,java.lang.String)

7、@args

按参数的类型的类上的注解匹配,当某方法的形参类型的类上有指定的注解,则匹配成功。

@args(com.sun.MyAnnotation)

当有个方法method(MyParam param),它形参的类型为MyParam,MyParam类上有@MyAnnotation注解时匹配成功,增强method方法

8、bean

按bean去匹配,只要是这个bean在调用的方法,就做AOP增强

  • 匹配Spring Bean容器中id或name为myBean的bean,并增强它调用的所有方法
bean(myBean)
  • 匹配所有id或name为以user开头的bean,并增强它调用的所有方法
bean(user*)

9、this

Spring AOP基于代理实现,先看下整个流程:

在这里插入图片描述

即,Spring容器初始化Bena时,发现bean对应的类中有切点时,就不再创建原始对象了,而是创建这个类的对象的代理对象,切点表达式中的this就是指这个代理对象。

语法:this(type)

当生成的代理对象,可以转型为type这个类型时,匹配成功

this(com.service.IUserService)

匹配生成的代理对象是IUserService类型的所有方法的外部调用

10、target

和this相反,被代理的目标对象可以被转换为指定的类型时,匹配成功。

target(com.service.IUserService)

匹配被代理的目标对象能够转换为IUserService类型的所有方法的外部调用

11、@target

和args、@args类似,当被代理的目标对象对应的类型及其父类型上拥有指定的注解时,匹配成功

@target(com.sun.MyAnnotation)

被代理的目标对象对应的类型上拥有MyAnnotation注解时,匹配成功

12、@within

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

@within(com.spring.service.MyAnnotation)

举个例子:

@MyAnnotation
class A {
	
	void method a();
}

B类集成A类,且有做为子类特有的方法B

class B {
	
	void method b();
}

此时,

new A().a()  匹配
new B().b()  不匹配
new B().a()	 匹配
子类B重写方法a后再调用:
new B().a()  不匹配

后面这几个没测过,应该用到的场景不多。

13、表达式组合

上面的一个个表达式,可以通过逻辑运算符或与非连接起来,以实现匹配到更复杂的增强需求。

  • 匹配id或name为userService的bean调用的方法,这个方法必须无参
bean(userService) && args()
  • 匹配id或name为userService的bean调用的方法,这个方法必须至少有一个形参
bean(userService) && !args()
  • 匹配id或name为userService的bean调用的方法,或者使用了@MyAnnotation这个注解的方法
bean(userService) || @annotation(MyAnnotation)

14、补充

开发中不一定要严格按下面的标准流程,先定义一个无意义无返回值的切点定义类,再写一个新方法来写增强的功能。

@Component
@Aspect
public class CutAdvice {

	//先定义一个无意义无返回值的切点定义类
    @Pointcut("execution(* *..MyService.myExecution(..))")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void beforeSome(){
        System.out.println("前置AOP成功");
    }
}

直接将切点方法或者切点表达式写到五种通知类型的注解中也行:

//直接写切点
@Before("com.llg.service.Uservice.findById()")
public void beforeSome() {
	System.out.println("AOP前置");
}

也可直接跟切点表达式

/**
 * 所有的add方法执行时
 */
@Before("execution(* add())")
public void beforeExecution() {
	System.out.println("AOP前置.....");
}


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/832848.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

frida学习及使用

文章目录 安装frida安装python3.7设置环境变量安装pycharm和nodejs 使用frida将frida-server push到手机设备中端口转发安装apk使用jadx查看java代码运行frida-server frida源码阅读frida hook方法Frida Java层hoookJavaHook.javaJavaHook.js Frida native层hook 一NativeHook.…

【Leetcode】(自食用)找到消失的数字

step by step. 题目: 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。 示例 1: 输入:nums [4,3,2,7,8,2,3,1] 输…

模板方法模式——定义算法的框架

1、简介 1.1、概述 模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中。在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法…

js沙箱逃逸

目录 一、什么是沙箱(sandbox) 二、沙箱技术的实现 & node.js 2.1简单沙箱程序示例 2.2this.tostring S1: S2: 三、arguments.callee.caller 一、什么是沙箱(sandbox) 在计算机安全性方面,沙箱(沙盒、sanbox&#xff…

【【萌新的STM32学习-4】】

萌新的STM32学习-4 STM32系统框架 1.1 Cortex M 内核& 芯片 F1有四个驱动单元 四个被动单元 AHB 高级高性能总线 APB 高级外围总线 部分系统结构 最上面的ICode 总线直接连接到了内部Flash 不需要通过总线矩阵 . D Code 总线(D - Bus) 这是Cort…

Kubernetes高可用集群二进制部署(五)kubelet、kube-proxy、Calico、CoreDNS

Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署(一)主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署(二)ETCD集群部署 Kubernetes高可用集群二进制部署(三)部署…

Delphi Enterprise Crack

Delphi Enterprise Crack Delphi帮助您使用Object Pascal为Windows、Mac、Mobile、IoT和Linux构建和更新数据丰富、超连接、可视化的应用程序。Delphi Enterprise适合开发团队构建客户端/服务器或多层应用程序、REST服务等。 Delphi功能 单一代码库-用更少的编码工作为所有主要…

MySQL 详细学习教程【万字长文, 建议收藏】

目录 1. Mysql入门1.1 Mysql5.7 安装配置1.2 命令行连接到Mysql1.3 图形化软件1.3.1 Navicat1.3.2 SQLyog 1.4 数据库三层结构 2. Java操作数据库、表2.1 创建数据库2.2 查询数据库2.3 备份恢复数据库2.4 创建表2.5 修改表 3 CRUD3.1 insert插入3.2 update修改3.3 delete修改3.…

一篇文章搞定《LeakCanary源码详解(全)》

一篇文章搞定《LeakCanary源码解析》 前言LeakCanary和LeakCanary2区别LeakCanary的快速使用第一步:添加依赖第二步:初始化LeakCanary第三步:运行应用程序并监测内存泄漏 LeakCanary基础铺垫四大引用WeakReference和ReferenceQueueRefercence…

【Spring】(二)从零开始的 Spring 项目搭建与使用

文章目录 前言一、Spring 项目的创建1.1 创建 Maven 项目1.2 添加 Spring 框架支持1.3 添加启动类 二、储存 Bean 对象2.1 创建 Bean2.1 将 Bean 注册到 Spring 容器 三、获取并使用 Bean 对象3.1 获取Spring 上下文3.2 ApplicationContext 和 BeanFactory 的区别3.3 获取指定的…

2023-02-03——2023-08-03,半年以来与客服交流的记录【CSND 文章撰写 网站使用求解】客服咨询交流记录(长期更新ing)

这世界上久处不厌,都是因为用心。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌟[3] 2022年度博客之星人工智能领域TOP4🌟 🏅[4] 阿里云社区特邀专家博主🏅 🏆

Cesium 实战教程 - 调整 3dtiles 倾斜摄影大小

Cesium 实战教程 - 调整 3dtiles 倾斜摄影大小 核心代码完整代码在线示例 之前由于误解遇到一个特殊的需求:想要把三维球上叠加倾斜摄影进行自由放大缩小,跟随地图的缩放进行缩放。 后来经过搜索、尝试,终于实现了需求。 但是,后…

什么是强化学习?

📝什么是强化学习? 1. 📝监督,非监督,强化2. 📝非 i.i.d3. 📝强化学习基本形式4. 📝马尔可夫过程 🌟 强化学习(Reinforcement Learning,RL&#x…

windows安装kafka配置SASL-PLAIN安全认证

目录 1.Windows安装zookeeper: 1.1下载zookeeper 1.2 解压之后如图二 1.3创建日志文件 1.4复制 “zoo_sample.cfg” 文件 1.5更改 “zoo.cfg” 配置 1.6新建zk_server_jaas.conf 1.7修改zkEnv.cmd 1.8导入相关jar 1.9以上配置就配好啦,接下来启…

小红书博主排名丨狂揽近百万粉丝,女性议题成“爆款制造机”?

从上野千鹤子和北大女生的对谈,到电影《消失的她》,再到引爆“粉色狂潮”的电影《芭比》,近年来,女性话题、两性情感话题成为社会热门议题。“踩过恋爱所有坑,想给姑娘撑把伞”,近期,小红书博主…

2023年华数杯数学建模B题思路代码分析 - 不透明制品最优配色方案设计

# 1 赛题 B 题 不透明制品最优配色方案设计 日常生活中五彩缤纷的不透明有色制品是由着色剂染色而成。因此,不透明 制品的配色对其外观美观度和市场竞争力起着重要作用。然而,传统的人工配色 存在一定的局限性,如主观性强、效率低下等。因此…

docker容器学习笔记1

docker容器是干什么用的 docker就是一个轻量级的虚拟机,是一个容器,隔离性好,能够确保环境的统一,有效利用系统资源,轻松迁移和拓展。简单的可以理解为容器就是一个小型功能齐全的虚拟机。 实际上是如何使用的呢&…

RocketMQ发送消息超时异常

说明:在使用RocketMQ发送消息时,出现下面这个异常(org.springframework.messging.MessgingException:sendDefaultImpl call timeout……); 解决:修改RocketMQ中broke.conf配置,添加下…

2023华数杯数学建模竞赛C题思路解析

如下为:2023华数杯数学建模竞赛C题 母亲身心健康对婴儿成长的影响 的思路解析 C题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一,她不仅为婴儿提供营养物质和身体保护,还为婴儿提供情感支持和安全感。母亲心理健康状态的不…

HCIP作业3

题目 配置IP地址 R1 [r1]int g0/0/1 [r1-GigabitEthernet0/0/1]ip add 192.168.1.1 24 [r1-Serial4/0/0]ip add 12.1.1.1 24 R2 [r2]int s4/0/0 [r2-Serial4/0/0]ip add 12.1.1.2 24 [r2-Serial4/0/0]int s4/0/1 [r2-Serial4/0/1]ip add 32.1.1.1 24 [r2-Serial4/0/1]in…