使用spring的MethodInterceptor实现aop功能的三种方式

2023-11-14

如果对于spring MethodInterceptor或spring aop概念不清楚,参考:spring aop, spring interceptor, springmvc interceptor有什么区别?

以下是在spring boot环境下执行的

在spring boot下有两种方式设置AOP(实现织入weave):

1. 使用@Aspect注解

2. 使用DefaultPointcutAdvisor

以实现TracingInterceptor为例

方法1:使用aspectj execution(切点) + interceptor(增强Advice)构成织入(DefaultPointcutAdvisor)

interceptor

class TracingInterceptor implements MethodInterceptor {
  Object invoke(MethodInvocation i) throws Throwable {
    System.out.println("method "+i.getMethod()+" is called on "+
                       i.getThis()+" with args "+i.getArguments());
    Object ret=i.proceed();
    System.out.println("method "+i.getMethod()+" returns "+ret);
    return ret;
  }
}

织入配置类

 

@Configuration
public class InterceptorConfig {

    public static final String traceExecution = "execution(* com.hfi.aop..*.*(..))";


    @Bean
    public DefaultPointcutAdvisor defaultPointcutAdvisor2() {
        TracingInterceptor interceptor = new TracingInterceptor();
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(traceExecution);

        // 配置增强类advisor
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setPointcut(pointcut);
        advisor.setAdvice(interceptor);
        return advisor;
    }
}

效果:当执行到com.hfi.aop包下的方法,当执行performEncore方法

可以看到我们配置的TracingInterceptor生效了

方法2:使用自定义注解(切点)+interceptor(增强Advice)构成织入(DefaultPointcutAdvisor)

自定义注解HfiTrace

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HfiTrace {
}

interceptor

public class TracingInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Method method = invocation.getMethod();
        HfiTrace annotation = getAnnotation(method);
        if (annotation == null) {
            return invocation.proceed();
        }
        // 为什么调用http://127.0.0.1:8089/jpademo/perform时有两次输出呢?
        // 因为在Audience里面用的是@Around,会拦截到两次
        System.out.println("method " + invocation.getMethod() + " is called on " + invocation.getThis() + " with args" +
                " " + invocation.getArguments());
        Object proceed = invocation.proceed();
        System.out.println("method " + invocation.getMethod() + " returns " + proceed);
        return proceed;
    }

    private HfiTrace getAnnotation(Method method) {
        // 如果有多个annotation 似乎就不好用了 如放在controller上 由于已经有了@RequestMapping注解了 所以...
        if (method.isAnnotationPresent(HfiTrace.class)) {
            return method.getAnnotation(HfiTrace.class);
        }
        return null;
    }
}

织入配置类

@Configuration
public class InterceptorAnnotationConfig {

    @Bean
    public DefaultPointcutAdvisor defaultPointcutAdvisor3() {
        TracingInterceptor interceptor = new TracingInterceptor();

        // AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(HfiTrace.class, true);
        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
        pointcut.setPatterns("com.hfi.*");

        // 配置增强类advisor
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setPointcut(pointcut);
        advisor.setAdvice(interceptor);
        return advisor;
    }
}

业务代码

    @HfiTrace
    @Override
    public String perform() {
        System.out.println("perform...");
        return "perform";
    }

效果:

可以看到执行也是生效的

方法3:使用自定义注解(切点)+@Aspect(切面)构成织入

自定义注解HfiTrace

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HfiTrace {
    String name() default "默认注解信息";
}

织入配置类

@Component
@Aspect
public class TracingAspect {
    @Before("@annotation(test)")
    public void beforeTest(JoinPoint point, HfiTrace test){
        System.out.println("method " + point.getSignature().getName() + " is called on " + point.getThis() + " with " +
                "args" +
                " " + point.getArgs());
        System.out.println("before invoke: "+ test.name());
    }

    @AfterReturning(value = "@annotation(test)", returning = "rvt")
    public void afterTest(JoinPoint point, HfiTrace test, Object rvt) {
        System.out.println("method "+point.getSignature().getName() + " returns " + rvt);
        System.out.println("after invoke: " + test.name());
    }
}

业务代码:

controller层:

    @HfiTrace
    @GetMapping("/perform")
    public String perform() {
        String perform = performance.perform();
        return perform;
    }

    @HfiTrace(name = "abc")
    @GetMapping("/performEncore")
    public String performEncore() {
        // 强制转换
        Encoreable encoreable = (Encoreable) performance;
        return encoreable.performEncore();
    }

service层:

@Component
public class PerformanceImpl implements Performance {

    @HfiTrace
    @Override
    public String perform() {
        System.out.println("perform...");
        return "perform";
    }
}

效果:

综上:三种方式都可以实现相同的功能,方法3看起来最为简洁,只需要定义一个注解,然后写一个@Aspect切面类,就可以拦截指定方法的运行了

源代码:https://gitee.com/constfafa/spring_springboot_learning/tree/master/methodinterceptor-demo

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用spring的MethodInterceptor实现aop功能的三种方式 的相关文章

  • matlab 计算协方差矩阵

    但是在有些用到协方差的算法中 分母使用了N 而不是N 1 但是由于样本很多 差别不大 gt gt v magic 3 v 8 1 6 3 5 7 4 9 2 gt gt cov v ans 7 8 1 8 16 8 1 8 7 gt gt
  • Base64编码工具类

    public class Base64Util private static final char last2byte char Integer parseInt 00000011 2 private static final char l
  • 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0304 没有与参数列表匹配的 重载函数 "std::regex_match" 实例 Project16 D:\Program Files(x86)\Microsoft Visual Stu

    这个错误表示在你的代码中调用了一个名为 std regex match 的函数 但是在你的代码中并没有定义该函数的重载函数 没有参数列表与你调用的函数相匹配 这个错误发生在 Project16D Program Files x86 Micr
  • jstat命令

    文章目录 1 简介 2 常用选项示例 1 jstat class pid 2 jstat gc pid 3 jstat gcutil pid 4 其他命令 1 简介 jstat命令可以查看堆内存各部分的使用量 以及加载类的数量 命令的格式如
  • 推荐夸克和多御,非常的实用!

    一 多御浏览器 多御浏览器是一款集安全 速度 工具于一身的浏览器 它的界面简洁大方 干净利落 打开速度和加载速度都很快 并且注重浏览体验 浏览器常用的功能一应俱全 添加书签 夜间模式 视频下载 分享页面 密码锁屏等 保护你的隐私 满足你的需
  • Python之Pygame.rect函数

    1 参数设置 Pygame 通过 Rect 对象存储和操作矩形区域 一个 Rect 对象可以由 left top width height 几个值创建 Rect 也可以是由 Pygame 的对象所创建 它们拥有一个属性叫 rect 任何需要
  • svn使用中出现的错误

    svn虽然用过很多次 但是还是会遇到很多问题 因为有时候是为了使用而忽略了原因 这次使用svn出了很多错误 这里记录一下 1 注意 Tortoise SVN和eclipse SVN插件版本的匹配 出现问题 无法从仓库import 知道的有以
  • 怎么在浏览器中获取请求头Headers信息

    这里使用的是Chrome浏览器 打开你想查询的网站 按F12 或者鼠标右键一下选择检查 会弹出如下的审查元素页面 然后点击上方选项中的Network选项 此时在按Ctrl R 选择下方框中的第一个 单击 选择Headers选项 其中就会有R
  • 最简单三级管振荡分析(自由多谐振荡器电路)

    三极管震荡分析 1 电路 自由多谐振荡器电路 2 分析 摘抄于电子发烧友 最简单三极管震荡电路 http m elecfans com article 640326 html 由上图可见 这个电路是由两个非门 反相器 用电容C1 C2构成的
  • 无需训练,自动扩展的视觉Transformer来了

    来自德克萨斯大学奥斯汀分校 悉尼科技大学和谷歌的研究者提出了一个无需训练就能自动扩展框架 As ViT 其能以高效和有原则的方式自动发现和扩展 ViT 当前 Vision Transformers ViT 领域有两个主要的痛点 1 缺少对
  • 华为OD机试 - 污染水域(Java)

    题目描述 输入一行字符串 字符串可转换为N N的数组 数组可认为是一个水域 判断多少天后 水域被全部污染 数组中只有0和1 0表示纯净 1表示污染 每天只可污染上下左右的水域 如果开始全部被污染 或永远无法污染 则返回 1 输入描述 无 输
  • 顺序表算法:将2个有序顺序表合成一个有序的顺序表

    顺序表算法 设顺序表 A 元素的个数是 n 没有重复 如果 A 中前 k 个元 素有序 后 n k 个元素有序 设计一个算法使得整个顺序表有序 要求算法的空 间复杂度为 O 1 solution 由于题目要求空间复杂度为O 1 所以不能另外
  • 爬取微信好友的部分资料,并将所有人的个性签名制成词云图,哈哈~~~~

    import itchat itchat login friends itchat get friends update True 0 male female other 0 for i in friends 1 sex i Sex if
  • Linux云计算-02_CentOS Linux 7.X系统管理

    Linux系统安装完毕 需要对Linux系统进行管理和维护 让Linux服务器能真正应用于企业中 本章介绍Linux系统32位与64位区别 内核命名规则 引导原理 启动流程 TCP IP协议概述 IP地址及网络知识 CentOS 7密码重置
  • Windows libreOffice develpemet 搭建

    2020 7 10 Personal 7 1 参考 https wiki documentfoundation org Development lode https wiki documentfoundation org Developme

随机推荐

  • 使用 java 命令编译运行 java 程序

    java 编译的过程 就是将 java 项目从源文件变成 class 文件的过程 而 class 文件 最后会被加载到JVM 中运行 在 JDK bin 目录下 提供了 javac 命令 用于将 java 源文件编译成 class 字节码文
  • 贤者之路,Cuda block内部矩阵求逆,mxm矩阵 复杂度为O(m)

    在做线性变换上经常要用到NXN的矩阵求逆 在CUDA用的是高斯消元比较适合并行计算 下面是3X3Cuda实现矩阵求逆的Device函数 也就是说可以直接写到你的kernel函数上去 当然也可以是任何NXN矩阵 另外时间上 测试过6X6的矩阵
  • 解读YOLO v7的代码(三)损失函数

    在前两篇博客中我分析了YOLO v7的模型结构以及训练数据的准备 这里将对损失函数的代码进行分析 在train py中 我们可以看到以下的代码是进行损失值计算的 if loss ota not in hyp or hyp loss ota
  • 集成电路模拟版图入门-版图基础学习笔记(一)

    IC模拟版图设计 了解版图 版图的定义 版图是在掩膜制造产品上实现 电路功能且满足电路功耗 性能等 从版图上减少工艺制造对电路的偏差 提高芯片的精准性 版图的意义 1 集成电路掩膜版图设计师实现集成电路制造所必不可少的设计环节 它不仅关系到
  • 爬虫确定分页

    直接能确定分页数的直接根据分页num构造 导航栏目主页不能直接确定分页数 需要通过下一页来确定最后一页 这边主要介绍第二类如果下一页还存在 放进分页列表 就不是最后一页 如果不存在就是最后一页 import requests import
  • 快来考取属于自己的“区块链证书”吧!

    想要学习或参加 区块链咨询师 线上考试的朋友可识别下方海报二维码 进行报名登记 考试成绩合格 80分及以上 者 即可获得 区块链咨询师 初级 证书 证书的持有人身份及发证机构的法人身份由公安部第三研究所牵头的数字身份技术应用联合实验室提供权
  • Matlab数学建模学习(5)-- 神经网络常用传递函数

    常用传递函数 1 线性传递函数 purelin 图像表示为 f x x f x x f x x 2
  • 【学习笔记】 Thymeleaf的前端渲染(价值50)

    学习笔记 Thymeleaf的前端渲染 价值50 博客首页 文章目的 Thymeleaf前端页面的渲染 博主也在学习阶段 如若发现问题 请告知 非常感谢 同时也非常感谢各位小伙伴们的支持 每日一语 不要在夕阳下时幻想 要在旭日东升时努力 吾
  • ubuntu下各种软件与库安装(个人记录)

    ubuntu下各种软件与库安装 个人记录 环境 ubuntu20 04 软件安装 wps2019 Clion grub customizer disk usage analyzer 各种库安装 opencv 3 2 0以及opencv co
  • 19年就业形势怎么样

    我们都知道去年开始就业形势就不太好 尤其是程序员群体 好多人辞职后找不到合适的工作 同时越来越多中小企业出现了大厂 名校的求职者 就业形势的严峻性可见一斑 今天这篇文章结合 19 年上半年的就业数据做一个简单的分析总结 看看目前整体的形势
  • QT不同项目之间怎么调用其他项目里的类对象?

    以下方法解决的问题 假设有A B C三个项目 A中有一个类 B C都有用到 怎么直接调用而不是用笨方法慢慢的复制粘贴 重点在 pri分文件处理上 步骤如下 一 首先把这个共同要使用到的类弄成分文件管理 同一个项目里 分文件管理的方法 1 在
  • ROS初学(rosrun执行找不到可以执行的node)

    此处特殊标注 方案一 在命令空间文件夹内直接执行 catkin make 方案二 在code中 点击ctrl shift b出现 选择catkin make build行的设置图标 保存task json 错误实例 选择catkin mak
  • EndNote和Word关联&&“endnote cwyw dll不是有效的office加载项“解决方案

    一 问题背景 前不久把Word重装了一遍 装好了以后就重新打开 无奈之前的EndNote插件不见了 这对于要查文献的我真的受到了一万点伤害 有点夸张 但其实也还好 不过EndNote导出文献格式真的很方便 对于我看文献做笔记啥的还是非常有帮
  • CentOS7下Grafana简单安装测试使用。

    Grafana安装 yum 方式安装 设置安装源 vim etc yum repos d grafana repo grafana name grafana baseurl https packages grafana com enterp
  • 阿里云2核4G轻量应用服务器5M峰值带宽性能评测

    阿里云双十一金秋云创季轻量应用服务器2核4G配置 系统盘为60GB ESSD云盘 5M峰值带宽 每月1100GB流量 轻量服务器每月流量不够用的的话 超出流量为0 8元每GB 阿里云百科来详细说下阿里云2核4G轻量应用服务器配置及购买条件
  • 奇安信笔试编程题

    package one import java util 3 1 5 21 10 7 0 3 3 1 5 3 3 3 1 5 21 10 0 3 3 1 5 5 public class Main public static int res
  • 指数族分布

    写在前面 本文只是对暂时学到的指数族分布的理论知识进行总结 至于指数族分布在实际机器学习中的具体应用 等后续学习到了再进行补充 也欢迎有经验的大佬赐教 文章将按照下面的思路进行 第一章首先给出指数族分布通用的 pdf 的表达式 简单介绍什么
  • 模板方法设计模式,让我的代码更加优雅了,这一波不亏

    模板方法设计模式属于行为模式的分类 为啥要使用设计模式 使用设计模式可以重构整体架构代码 提交代码复用性 扩展性 减少代码冗余问题 让我们的代码更直观和优雅 模板方法模式和策略模式都有相同之处就是有具体的行为实现 所以也是基于工厂模式的实现
  • 命令行安装卸载驱动服务

    1 创建驱动服务 用法 sc
  • 使用spring的MethodInterceptor实现aop功能的三种方式

    如果对于spring MethodInterceptor或spring aop概念不清楚 参考 spring aop spring interceptor springmvc interceptor有什么区别 以下是在spring boot