我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解Spring AOP自定义可重复注解没有生效问题

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解Spring AOP自定义可重复注解没有生效问题

目录
  • 1. 问题背景
  • 2. 不啰嗦,上代码
  • 3. 问题排查
    • 3.1 是不是切点写得有问题,于是换成如下形式:
    • 3.2 是不是使用的地方不是代理对象
  • 4. 问题原因

    1. 问题背景

    工作中遇到这样的场景:某个方法需要在不同的业务场景下执行特定的逻辑,该方法已经上生产,不想改变原来的代码,因此决定用AOP做个切面执行逻辑。

    2. 不啰嗦,上代码

    以下为核心代码:

    定义注解:

    
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    @Repeatable(value = StartTaskRuns.class)
    public @interface StartTaskRun {
    
      int businessType() default 0;
    
    }
    
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface StartTaskRuns {
    
      StartTaskRun[] value();
    }
    
    

    定义切面

    
    @Aspect
    @Component
    public class StartTaskRunAspect {
    
      @AfterReturning(pointcut = "@annotation(com.freedom.code.annotation.StartTaskRun)", returning = "retValue")
      public void startTask(JoinPoint joinPoint, Object retValue) throws Exception {
        Object[] args = joinPoint.getArgs();
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        StartTaskRun[] annotations = method.getAnnotationsByType(StartTaskRun.class);
        for (StartTaskRun annotation : annotations) {
          System.out.println(annotation.businessType());
        }
      }
    }

    业务代码加注解

    
      @StartTaskRun(businessType = 5)
      @StartTaskRun(businessType = 6)
      @Override
      @Transactional(rollbackFor = Exception.class)
      public String doCsmsStrategy(Long id) {
        // 业务逻辑
        return userDO.getId().toString();
      }
    

    debug的时候发现,切面的代码没有执行。

    3. 问题排查

    3.1 是不是切点写得有问题,于是换成如下形式:

    
      @AfterReturning(pointcut = "execution(* com.freedom.code.service.UserServiceImpl.doCsmsStrategy(..))", returning = "retValue")
      public void startTask(JoinPoint joinPoint, Object retValue) throws Exception {
        Object[] args = joinPoint.getArgs();
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        StartTaskRun[] annotations = method.getAnnotationsByType(StartTaskRun.class);
        for (StartTaskRun annotation : annotations) {
          System.out.println(annotation.businessType());
        }
      }
    

    还是不行,但是我的工程中其他地方也是类似的写法却没有问题啊。看起来不像是AOP配置不对的问题

    3.2 是不是使用的地方不是代理对象

    打断点吧,如下:

    在这里插入图片描述

    是使用cglib生成的代理对象,没有问题啊,到底问题在哪里。没办法,面向百度编程吧,还真找到问题解决办法。如下帖子:https://www.jb51.net/article/220762.htm

    4. 问题原因

    对于可重复注解,如果方法上用多个可重复注解,AOP拦截不到。需要用它的包装类型注解做切点,改成以下代码就可以了:

    
    @Aspect
    @Component
    public class StartTaskRunAspect {
    
      @AfterReturning(pointcut = "@annotation(com.freedom.code.annotation.StartTaskRun) || @annotation(com.freedom.code.annotation.StartTaskRuns)", returning = "retValue")
      public void startTask(JoinPoint joinPoint, Object retValue) throws Exception {
        Object[] args = joinPoint.getArgs();
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        StartTaskRun[] annotations = method.getAnnotationsByType(StartTaskRun.class);
        for (StartTaskRun annotation : annotations) {
          System.out.println(annotation.businessType());
        }
      }
    }
    
    

    到此这篇关于详解Spring AOP自定义可重复注解没有生效问题的文章就介绍到这了,更多相关Spring AOP注解没有生效内容请搜索编程界以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程界!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    详解Spring AOP自定义可重复注解没有生效问题

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    详解Spring AOP自定义可重复注解没有生效问题

    目录1. 问题背景2. 不啰嗦,上代码3. 问题排查3.1 是不是切点写得有问题,于是换成如下形式:3.2 是不是使用的地方不是代理对象4. 问题原因1. 问题背景工作中遇到这样的场景:某个方法需要在不同的业务场景下执行特定的逻辑,该方法已经上生产,不想改变原
    2019-04-16

    gin自定义中间件解决requestBody不可重复读问题(最新推荐)

    这篇文章主要介绍了gin自定义中间件解决requestBody不可重复读问题,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-18

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录