Spring AOP方法内部调用不生效的解决方案

 更新时间:2025年01月08日 09:00:29   作者:菜鸟日常  
最近有个需求,统计某个方法的调用次数,开始使用 Spring AOP 实现,后来发现当方法被内部调用时,切面逻辑将不会生效,所以本文就给大家介绍了Spring AOP方法内部调用不生效的解决方案,需要的朋友可以参考下

问题描述

最近有个需求,统计某个方法的调用次数,开始使用 Spring AOP 实现,后来发现当方法被内部调用时,切面逻辑将不会生效,直接上样例:

定义接口,包含方法 A,方法 B

public interface ISon {
    void A();
    void B();
}

定义接口实现,方法 B 调用方法 A

@Service
public class Son implements ISon {
    @Override
    public void A() {
        System.out.println("method A");
    }
    @Override
    public void B() {
        System.out.println("method B");
        A();
    }
}

切点定义,对方法 A 进行增强

@Aspect
@Component
public class AspectDemo {

    @Pointcut(value = "execution(* com.example.transactiondemo.aop.ISon.A(..))")
    public void pointCut(){
    }

    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        System.out.println("before ");
    }

    @After("pointCut()")
    public void after(){
        System.out.println("after ");
    }

}

测试

@Autowired
private ISon iSon;

@Test
public void test11(){
    iSon.A();
    System.out.println("-----------");
    iSon.B();
}

打印输出

before 
method A
after 
-----------
method B
method A

可以发现,如果直接使用 实例调用 A,会进行增强;但是如果是方法 B 调用,A 的增强逻辑将失效。

失效原因

方法 A 被调用,是基于 AOP 生成的 代理对象 进行的调用;方法 B 调用方法 A ,是 this 目标对象 直接调用,并不是代理对象进行调用

5.8. Proxying Mechanisms

解决方案

回到最开始的需求,如何通过切面的方式获取某一个方法的调用次数? 包括方法自调用

  • 使用 AopContext.currentProxy()

    切面开启注解

@EnableAspectJAutoProxy(exposeProxy = true,proxyTargetClass = true)

方法 B 不直接调用 A

    @Override
    public void B() {
        System.out.println("method B");
        ((Son) AopContext.currentProxy()).A();
    }

先获取上下文的 Bean 再调用

@Autowired
private ApplicationContext applicationContext;

((Son) applicationContext.getBean(Son.class)).A();

以上就是Spring AOP方法内部调用不生效的解决方案的详细内容,更多关于Spring AOP方法调用不生效的资料请关注脚本之家其它相关文章!

相关文章

  • java final 和instanceof 关键字的区别

    java final 和instanceof 关键字的区别

    这篇文章介绍了java final 和instanceof 关键字的区别,有需要的朋友可以参考一下
    2013-09-09
  • 浅谈对象与Map相互转化

    浅谈对象与Map相互转化

    这篇文章主要介绍了利用BeanMap进行对象与Map的相互转换,在文中列举了完整代码,需要的朋友可以参考下。
    2017-09-09
  • Spring Security 实现短信验证码登录功能

    Spring Security 实现短信验证码登录功能

    这篇文章主要介绍了Spring Security 实现短信验证码登录功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • Java实现邮件发送功能

    Java实现邮件发送功能

    这篇文章主要为大家详细介绍了Java实现邮件发送功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • JavaWeb如何实现禁用浏览器缓存

    JavaWeb如何实现禁用浏览器缓存

    这篇文章主要介绍了JavaWeb如何实现禁用浏览器缓存,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java OpenCV4.0.0实现实时人脸识别

    Java OpenCV4.0.0实现实时人脸识别

    这篇文章主要为大家详细介绍了Java OpenCV4.0.0实现实时人脸识别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • Java synchronized与死锁深入探究

    Java synchronized与死锁深入探究

    这篇文章主要介绍了Java synchronized与死锁,Java中提供了synchronized关键字,将可能引发安全问题的代码包裹在synchronized代码块中,表示这些代码需要进行线程同步
    2023-01-01
  • Spring实现文件上传的配置详解

    Spring实现文件上传的配置详解

    这篇文章将为大家详细说明一下spring上传文件如何配置,以及从request请求中解析到文件流的原理,文中示例代码讲解详细,感兴趣的可以了解一下
    2022-08-08
  • Java中的 BigDecimal 和 String 的相互转换问题

    Java中的 BigDecimal 和 String 的相互转换问题

    这篇文章主要介绍了Java中的 BigDecimal 和 String 的相互转换问题,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • 通过代码示例了解submit与execute的区别

    通过代码示例了解submit与execute的区别

    这篇文章主要介绍了通过代码示例了解submit与execute的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论