解决使用注解的spring中aop,无法拦截方法中调用其他的方法(函数内部调用无法拦截)问题

Spring AOP 内部调用失效解决方案 背景 前两篇博客采用AOP实现接口入参、返回结果的log打印和方法参数校验。测试时发现一个问题,简言之: 1、service中方法1设置AOP拦截,奏效 2、同service中方法2未设置AOP拦截,但在方法2中直接diao调用方法1,方法1的AOP拦截失效。 原因 通过debug发现,在方法2调用方法1时,this指向service对象本身(写或不写都指向本service),而非ser... 阅读详情

最近在项目中要记录用户日志,使用自定义注解进行aop拦截,发现可以拦截调用类的第一个方法,方法中调用其他方法,则其他方法无法拦截,经过查询,发现是aop自身的动态代理造成的,下面我贴出项目的代码:

1、自定义注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogController {
    String operationContent() default "";
}

2、spring的aop代码

@Aspect
@Component
public class UserLogAspect {

    @Pointcut("@annotation(com.jingli.creditchain.service.userlog.LogController)")
    public void methodAspect() {

    }

    @SuppressWarnings("rawtypes")
    @After("methodAspect()")
    public void doAfter(JoinPoint joinPoint) {
        try {
            //拦截的实体类
            Object target = joinPoint.getTarget();
            //拦截的方法名称
            String methodName = joinPoint.getSignature().getName();
            //拦截的参数类型
            Class[] parameterTypes = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterTypes();
            //通过反射获得拦截的method
            Method method = target.getClass().getMethod(methodName, parameterTypes);
            String content = method.getAnnotation(LogController.class).operationContent();
            //打印注解上的说明
            System.out.println("================="+content);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

3、controller中进行方法拦截

    @LogController(operationContent = "findApply")
    @RequestMapping(path = "/list", method = RequestMethod.POST)
    public List<ApplyVm> findApply(@RequestBody QueryInnerApplyVm query) {
        //转换请求vm,在转换的方法上也加上拦截(转换方法在同一个类中)
        QueryParam queryParam = queryInnerApplyVmToQueryParam(query);
        return applyService.findApply(queryParam)
            .stream()
            .filter(Objects::nonNull)
            .map(this::assignApplyVm)
            .collect(Collectors.toList());
    }


//转换方法
@LogController(operationContent = "queryInnerApplyVmToQueryParam")
public QueryParam queryInnerApplyVmToQueryParam(QueryInnerApplyVm vm) {
    return new QueryParam();
}

4、测试,看打印结果

=================findApply

可以看到,方法中调用的第二个方法并没有拦截。

原因:

当调用这个类的时候,调用的是代理对象,代理类内部代码大致是:

private ApplyController applyController;

public List<ApplyVm> findApply(@RequestBody QueryInnerApplyVm query) {

    //也就是说,在调用其他函数时,其实是被代理对象调用的,所以方法是不会被增强,也就是没
        有拦截。调用其他函数时,如果是代理对象调用的,那就可以被拦截。
    QueryParam queryParam = applyController.queryInnerApplyVmToQueryParam(query);
       
}

5、修改代码

拿到ApplicationContext,从容器中拿对象,如果那个对象有代理对象,就可以获得代理对象。

//工具类
@Component
public class BeanUtil implements ApplicationContextAware {
    private  static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(@NotNull ApplicationContext applicationContext){
        BeanUtil.applicationContext = applicationContext;
    }

    public static <T> T getBean(Class<T> bean){
        return applicationContext.getBean(bean);
    }
}
    @LogController(operationContent = "findApply")
    @RequestMapping(path = "/list", method = RequestMethod.POST)
    public List<ApplyVm> findApply(@RequestBody QueryInnerApplyVm query) {
        QueryParam queryParam = BeanUtil.getBean(this.getClass()).queryInnerApplyVmToQueryParam(query);
    }

6、测试

=================queryInnerApplyVmToQueryParam

=================findApply

第二个方法也被拦截了。

7、总结

spring是不建议这种使用aop有函数内部调用的,可以把调用的函数写到另一个类中。但是这样的话,代码会有点乱,所以我项目中看情况如果上面的写法方便的话我还是用上面的方法把=。=

这个问题一开始困扰我好久,上网查查这问题有大神解答,十分感谢,也记录一下。

光伏系统选型指南:5种主流MPPT算法优缺点对比(附选型流程图) 本文深入剖析了光伏系统中五种主流MPPT算法的核心原理与性能差异。通过对比扰动观察法、电导增量法、恒定电压法、模糊逻辑控制及人工智能算法在追踪精度、响应速度、实现成本与稳定性等方面的表现,为不同应用场景(如户用、工商业及大型电站)提供了清晰的选型决策流程图和实战指南,帮助工程师优化系统效率与投资回报。 阅读详情

相关推荐

Playwright与MCP协议结合:AI驱动的智能Web自动化测试实践

Web自动化测试是现代软件开发流程中保障产品质量的关键环节,其核心原理是通过程序模拟用户操作,对Web应用进行功能验证。传统自动化测试工具如Selenium和Playwright虽然提供了强大的API,但脚本编写和维护仍需较高的编程技能。随着AI技术的发展,智能测试成为新的趋势,它通过自然语言理解和自动化执行,显著降低了测试创建门槛。Model Context Protocol(MCP)作为一种连接AI模型与外部工具的开放协议,为自动化测试带来了“智能大脑”。通过将MCP与Playwright结合,测试人员

aoe41606的博客 604

aop定义切入点规则(@Pointcut)后不生效,方法执行时无法被aop拦截

aop定义切入点规则(@Pointcut)后不生效,方法执行时无法被aop拦截

weixin_52116015的博客 3725

海康视觉相机驱动软件MVS参数配置全攻略(附接线图+避坑指南)

本文提供了海康视觉相机驱动软件MVS从硬件连接到软件参数配置的完整指南。详细解析了供电与通讯线缆的区分、PNP/NPN信号逻辑的接线避坑方法,并重点阐述了MVS软件中触发模式、网络IP配置、图像采集及光源控制等核心参数的设置技巧,旨在帮助用户快速完成相机调试,实现稳定高效的图像采集。

weixin_29204205的博客 397

Spring AOP无法拦截内部方法调用

Spring AOP无法拦截内部方法调用 spring aop之对象内部方法间的嵌套失效 来看一个内部调用失败的经典例子 //如果存在事务,则抛出异常。 public class TxDemo{ @Transactional(propagation = Propagation.NEVER) public void serviceH() { User...

piaoslowly的专栏 5222

智能体在车联网中的应用:第31天 基于RLlib的多智能体PPO实战:MAPPO算法解决simple_spread合作任务

本文介绍了如何利用RLlib框架实现多智能体强化学习算法MAPPO,解决simple_spread任务。首先分析了RLlib的架构设计理念和多智能体支持特性,包括策略映射、环境包装等核心组件。然后详细解析了simple_spread环境的任务定义、观察空间和奖励函数设计。最后回顾了MAPPO算法原理,说明其如何在RLlib中实现集中式训练与分布式执行的CTDE范式。文章提供了完整的安装指南和环境配置方法,帮助读者快速搭建多智能体强化学习实验环境。

IT深耕十余载,大道之简 1332

SAP-ABAP:接口多继承与复合接口设计:复杂业务场景下的能力组合实现方案

本文介绍了ABAP中通过接口多继承与复合接口设计实现能力组合的方案。文章首先辨析了类实现多个接口与接口继承接口的核心概念,指出ABAP虽不支持类多继承,但可通过这两种机制灵活组合能力。随后详细讲解了类实现多个接口的语法规则与三种调用方式,并给出了五个基础能力接口的设计示例(日志记录、权限校验、数据导出、消息通知、格式转换)。作者通过对比单继承与接口多重实现的差异,强调后者在解耦和扩展性上的优势,为复杂业务场景下的能力组合提供了实用解决方案。

baidu_35680696的博客 245

spring aop 同一个类中一个方法调用另一个方法,拦截不到被调用的方法

转自:http://huqilong.blog.51cto.com/53638/732088            在开发基于 Spring 的应用的过程中碰到了一个让我困惑了好久的问题,我在一个 Service 类的 doSomething1() 方法中通过 this.doSomething2(); 语句调用了同一个类中的 doSomething2 方法,运行时通过调试发现

jisuanjixuezi的专栏 6075

YOLOv11涨点改进 | 全网独家创新,注意力改进篇 | TGRS 2025 | 引入APCM自适应像素级协同机制,动态增强目标区域、抑制背景噪声,助力YOLOv11做红外小目标检测有效涨点

本文提出了一种基于APCM模块改进的YOLOv11网络模型,通过像素级局部-全局协同建模增强目标特征并抑制背景噪声。APCM模块采用轻量化设计,无需复杂参数,能有效提升小目标检测性能。文章详细介绍了APCM的原理、优势及其在红外小目标检测中的应用,包括模块结构、核心代码实现和YAML配置文件修改方法。实验结果表明,该方法在NUAA-SIRST和IRSTD-1K数据集上优于现有技术,显著提高了复杂场景下的检测精度与鲁棒性。

Ai缝合怪、助力小伙伴高效发论文 116

Aop无法拦截内部方法调用的原因

目录 前言 Aop小案例 过程分析 解决方案 前言 今天在写系统权限校验时发现某个含有切点注解的方法进不去切面类,单元测试了下,发现在单个类内的方法调用是不能够进入切 面中的,这就说明在内部方法调用时并未使用代理对象进行代理。 Aop小案例 为了验证这个现象,我们写个Aop的小例子,注意本案例是基于SpringBoot 2.1.3版本 首先自定义一个注解,用于标识切点: ...

清茶的博客 4980

MATLAB之把多个小cell拼成一个数组

问题描述 现有一个cell向量 L (90000,1),每个元素都是由一个(100X9)的double数组组成的.如图. 其中, 每个cell元素都是一个单独的数据, 我们要把它转换成(90000, 19, 100)的三维数组. cell2mat, 但是所有的数据会堆叠起来 L2=cell2mat(L); % (90000, 19) reshape, 变成三维数组 reshape的原理是从上到下, 从左往右拆开重组. 目前只有19这一维数据与要求一致, 那就以这个为突破口. L2=L2'; %

落日之城 9249

杰理SDK入门教程(一):SDK的四种编译方式的使用

杰理SDK提供了四种主要编译方式:1) JL Studio官方IDE,适合初学者;2) VS Code轻量级编辑器,需在SDK根目录打开;3) 命令行/脚本编译,灵活支持自动化;4) Code::Blocks开源IDE。每种方式都有详细操作指南,开发者可根据需求选择,初学者推荐从JL Studio开始熟悉编译流程。环境配置注意事项和编译成功标识均有明确说明,确保开发效率。

qq_42014563的博客 1146

使用aop实现对指定方法的拦截

切面(个人理解):其实就是开发中对重复代码单独封装成的类,在使用时对需要加强的方法(该方法也就是切点)进行切割 ChineseSay.java public class ChineseSay implements ISay { @Override public void say() { // return "你好"; //返回的话会打乱aop拦截的顺序,最后...

qq_41519943的博客 2996

基于MATLAB开发AUTOSAR软件应用层模块-part3.自动生成的代码文件介绍

上篇文章我们介绍了如何设计一个简单的模型,之后自动生成autosar架构的代码,这篇文章我带大家看下,生成了哪些文件,以及这些文件的内容。 生成的文件见下图: model files是模型控制逻辑部分代码,包括 DEMO1.c DEMO1.h DEMO1_private.h DEMO1_types.h DEMO1.c 1 /* 2 * File: DEMO1.c 3 * 4 * Cod.

汽车软件开发 1977

spring aop无法拦截接口上的注解

目录问题背景问题现场(aop代码)源码初步解决方案重写事务拦截器设置拦截器通用解决方案(自定义的方法拦截器)demo 乞丐版Pro版注意细节 问题背景 最近在spring-boog项目中做mysql读写分离时遇到了一些奇葩问题,问题现象:通过常规的spring aop去拦截带有自定义注解的方法时,发现只有注解写在实现类上面时才有效,写在接口上时却不生效。所用的spring-boot版本为1.x版本 问题现场(aop代码) @Aspect @Component @EnableAspectJAutoProxy

zhaopiandehuiyi 4954

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

spring aop拦截指定方法和自定义注解

1、使用aop需要加入maven依赖 <!--与aop相关--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifac...

zengqingfa123的博客 1万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Spring AOP 的两种形式:拦截方法 and 拦截注解

AOP模块提供了面向切面的编程实现,允许你定义方法拦截器和切入点对代码进行干净地解耦,它实现了应该分离的功能。 一,添加aop依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</art...

_夜渐凉 2485

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Spring Aop 内部方法调用拦截问题

Spring Aop 内部方法调用拦截问题问题描述通过spring aop实现方法调用日志记录上述实现存在的问题问题产生原因问题解决方法 问题描述 通过spring aop实现方法调用日志记录 首先定义日志记录注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogAnno...

godwei_ding的博客 951

Spring AOP 拦截指定注解标识的类或方法

代码Demo @Aspect @Component @Order(10) public class BidAuthorityProxy { /** * 扫描指定包下的类中使用@EnableRoleAuthority注解修饰的类 */ @Around("@within(com.core.annotation.EnableRoleAuthority) &am...

琅琊之榜 1万+

aop阻止方法运行_Aop无法拦截内部方法调用的原因

目录前言今天在写系统权限校验时发现某个含有切点注解的方法进不去切面类,单元测试了下,发现在单个类内的方法调用是不能够进入切面中的,这就说明在内部方法调用时并未使用代理对象进行代理。Aop小案例为了验证这个现象,我们写个Aop的小例子,注意本案例是基于SpringBoot 2.1.3版本首先自定义一个注解,用于标识切点:@Target(ElementType.METHOD)@Retention(Re...

weixin_33331639的博客 961

Spring AOP:this 调用当前类方法无法被拦截

回溯之前的代码可知,在 @Around 的切面类中,我们很清晰地定义了切面对应的方法,但是却没有被执行到。这说明了在类的内部,通过 this 方式调用的方法,是没有被 Spring AOP 增强的。上述代码中的关键方法是 wrapIfNecessary,顾名思义,在需要使用 AOP 时,它会把创建的原始的 Bean 对象 wrap 成代理对象作为 Bean 返回。这时候我们就引入了一个 @Around 的增强 ,分别记录在 pay() 方法执行前后的时间,并计算出执行 pay() 方法的耗时。

山海守门人 1436

Spring AOP 和 拦截器 获取类上与方法上的注解

在做一个跨过目标注解的鉴权功能时,想到了AOP与拦截器两种方式,其中 @HasPermission 是我自定义的注解,以下分别为AOP与拦截器获取访问目标类与方法上的注解的方法。由于我的系统在拦截器上配置了拦截过则,所以我选的是拦截器的方式,读者可根据自己的需求来。先通过ProceedingJoinPoint对象的 joinPoint.getSignature()方法获取到 Signature 的对象并强制类型转换为一个MethodSignature对象,通过 signature.getClass()方法获

TechnicianWang的博客 8569

Spring AOP无法拦截内部方法调用—— exposeProxy=true用法

假设一个接口里面有两个方法: package demo.long; public interface CustomerService { public void doSomething1(); public void doSomething2(); } 接口实现类如下: package demo.long.impl; import demo.long.CustomerService; public class CustomerServiceImpl imp

meser88的博客 2042

Spring aop拦截注解标记的接口方法

参考@Repository 会自动加入PersistenceExceptionTranslationAdvisor 实现mapper接口方法拦截 1.自定义注解 @Target( AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD, AnnotationTarget.FUNCTION ) @Retention(A...

weixin_40118996的博客 4472

Spring AOP无法拦截内部方法

Spring AOP无法拦截内部方法调用 spring aop之对象内部方法间的嵌套失效 来看一个内部调用失败的经典例子: //如果存在事务,则抛出异常。 public class TxDemo{ @Transactional(propagation = Propagation.NEVER) public void serviceH() { UserInfoV...

Naland's Blog 1164

spring aop与自定义注解的联合使用以及如何拦截mybatis层接口方法

spring-aop 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方 式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个 热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑 的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可...

QFann的博客 3533

使用Spring的注解方式实现AOP

Spring对AOP的实现提供了很好的支持。下面我们就使用Spring的注解来完成AOP做一个例子。 首先,为了使用Spring的AOP注解功能,必须导入如下几个包。aspectjrt.jar,aspectjweaver.jar,cglib-nodep.jar. 然后我们写一个接口 package com.bird.service; public interface PersonServe

技术是我的毕生追求 9万+
上一篇: maven工程创建ssm项目,启动tomcat,控制台报错BeanFactory not initialized or already closed....的原因
下一篇: springboot使用gradle构建项目,导入外部jar包的方法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值