SpringBoot AOP无法拦截类内部的调用方法

本文介绍了解决Spring AOP无法拦截同一类内部方法调用的问题。通过改变调用方式和在SpringBoot启动类中添加@EnableAspectJAutoProxy注解,实现了AOP对内部方法的有效拦截。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:
类A中有个方法B,方法B去调用类A中的另一个方法C,现在想用aop去拦截这个C方法,发现无法拦截。
由于博主学术不精,钻研的不深,说不太清楚为什么,反正是一些关于底层代理的问题。这里就直接给出解决方法。
1.改变调用C方法的写法:

`
// handlerApConfigMod(msg_json);//原来是直接调用另一个方法,改为下面这种写法

((AcUpdataHandler) AopContext.currentProxy()).handlerApConfigMod(msg_json);//AcUpdataHandler是当前类名
`

2.SpringBoot启动类中加一个注解
@EnableAspectJAutoProxy(exposeProxy = true)
这样就可以解决问题了。
原文链接:Spring AOP无法拦截内部方法调用

### 使用Spring Boot AOP拦截Service层方法 为了在Spring Boot应用程序中使用面向切面编程(AOP)来拦截服务层的方法,需要遵循几个关键步骤。这不仅有助于减少重复代码,还能增强系统的可维护性和灵活性。 #### 创建基础Spring Boot项目并配置依赖项 定义了一个名为`LogDemoApplication`的基础Spring Boot应用入口点[^1]: ```java package cn.juwatech.logdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class LogDemoApplication { public static void main(String[] args) { SpringApplication.run(LogDemoApplication.class, args); } } ``` 接着,在项目的构建文件中添加必要的依赖项以支持AOP功能。对于Maven用户来说,这意味着要在`pom.xml`里加入如下片段: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` #### 启用AOP代理机制 为了让AOP能够正常工作,还需要确保启用了相应的代理设置。可以在启动上通过添加特定注解来完成这一操作[^2]: ```java @EnableAspectJAutoProxy(exposeProxy = true) @SpringBootApplication public class LogDemoApplication { ... } ``` 此配置允许框架自动处理目标对象的代理创建过程,并暴露当前线程中的代理实例给其他组件访问。 #### 编写自定义切面逻辑 接下来就是编写实际用于拦截指定方法执行前后的横切关注点——即所谓的“切面”。下面是一个简单的例子,展示了如何利用AOP技术捕获所有标记有`@Service`注释的服务接口下的公共成员函数调用事件[^3]: ```java package cn.juwatech.logdemo.aspect; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Slf4j @Aspect @Component public class ServiceMethodInterceptor { @Before("execution(public * cn.juwatech..service.*.*(..)) && within(@org.springframework.stereotype.Service *)") public void logServiceInvocation(JoinPoint joinPoint){ String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); StringBuilder messageBuilder = new StringBuilder("Invoking method ").append(methodName).append("("); if (arguments != null && arguments.length > 0) { for (Object arg : arguments) { messageBuilder.append(arg.toString()).append(", "); } // Remove trailing ", " int lastCommaIndex = messageBuilder.lastIndexOf(","); if(lastCommaIndex >= 0){ messageBuilder.deleteCharAt(lastCommaIndex); messageBuilder.deleteCharAt(lastCommaIndex - 1); } } messageBuilder.append(")"); log.info(messageBuilder.toString()); } } ``` 上述代码实现了对任何位于包路径下带有@Service标注的服务内公开方法的前置通知(`@Before`),并在每次这些方法被触发之前打印一条日志消息到控制台。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值