spring aop 内部引用失效分析

背景

用了spring retry 发现在有些场景下失效,也让我想起了之前看spring 事务时会有一些场景下失效的这个问题

代码

bash 复制代码
接口

public interface UserService {


    public void start() ;


    public void stop();
}

实现类
@Service
public class UserServiceImpl implements UserService {
    @Override
    @Retryable()
    public void start() {

        if (1 == 1) {
            throw new RuntimeException();
        }

    }

    @Override
    public void stop() {

        start();
        

    }
}

测试

bash 复制代码
        ConfigurableApplicationContext run = SpringApplication.run(K8sDemoApplication.class, args);

        UserService user = run.getBean(UserService.class);
        
        //生效
        user.start();

        
        //失效
        // user.stop();

测试发现如果直接调用start 方法是会生效的

通过stop()方法里面调用start 方法是会失效的

分析

首先我们知道如果要在一个方法前后加一些todo ,有两种方法,一种是硬code

还有一种是通过动态代理的方法,这里通过注解的方法,实际底层是通过cglib这种代理实现的,默认应该是jdk动态代理的,但是我用arthas分析实际是用cglib这种形式,这个不重要。

为啥通过代理的,两种不同的调用方式会有区别呢

直接调用为啥是可以的,因为实际上的调用对象是生成的动态代理对象,在方法上进行代理的。

bash 复制代码

我们重点了解下为啥间接调用失败。

看下编译后的代码

bash 复制代码
@Service
public class UserServiceImpl implements UserService {
    public UserServiceImpl() {
    }

    public void start() {
        throw new RuntimeException();
    }

    public void stop() {
    //实际上调用start,我们可以发现是通过this 对是本身这个对象直接调用的
        this.start();
    }
}

总结

加深了对之前glibc动态代理的理解

相关推荐
wuminyu4 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
txxzjmzlh4 小时前
SpringBoot 配置⽂件
java·spring boot·spring
ZhengEnCi4 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
王中阳Go4 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型
Wang's Blog4 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
程序猿DD4 小时前
OctaFuse Gateway 2.18.0:MCP 接入支持 OAuth,供应商粘性绑定可视化管理
后端
骑着蜗牛撵大象3275 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
独泪了无痕5 小时前
Hutool之LocalDateTimeUtil:让时间间隔操作如虎添翼
java
三无少女指南6 小时前
从这里开始:Java 后端与 AI 工程的三条阅读路线
java·学习路线·ai工程
ZhengEnCi6 小时前
Agent 规则管理:让 Memory 做索引、让 Skill 存规则——上下文上限实测与分工方案
后端