You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring AOP场景下toString、getClass()、hashCode返回结果不一致问题咨询

Spring AOP动态代理现象原理说明

所有你观察到的现象都和Spring CGLIB动态代理的实现机制直接相关,具体拆解如下:

核心基础前提

CGLIB动态代理的本质是生成目标类的子类作为代理类,有两个不可修改的底层特性:

  • Object类的getClass()是final修饰的native方法,任何子类都无法重写,哪个对象调用该方法,就返回哪个对象的实际运行时类型。
  • Spring AOP只能拦截外部对代理对象发起的方法调用,目标对象内部的this永远指向原生目标对象本身,通过this调用的所有方法都不会走代理增强逻辑。

各现象逐一解释

1. toString()结果一致,但getClass()、hashCode()单独调用结果不一致

  • 代理对象调用getClass()时,因为是final方法无法被拦截,直接返回代理类自身的类型,所以会携带$$EnhancerBySpringCGLIB$$后缀;而目标对象内部this.getClass()返回的是原生类的类型,两者必然不一样。
  • Spring对CGLIB代理的toString()方法做了特殊转发逻辑:代理对象调用toString()时,会直接把调用转发给持有的目标对象执行,所以返回的是目标对象执行toString()的结果,和目标对象内部this.toString()的输出完全一致。
  • 你观察到的hashCode()调用结果不一致,本质是对比维度的差异:如果直接调用代理对象的hashCode()方法,Spring默认也会转发给目标对象执行,返回值和目标对象的hashCode()一致;如果你获取的是代理对象本身的身份哈希值(比如通过System.identityHashCode()获取),和目标对象的身份哈希值属于两个不同对象的内存地址标识,自然会不一致。

2. addAccount方法内部this.hashCode()和传入的accountDAO的hashCode()一致

你传入addAccount方法的accountDAO参数就是Spring生成的代理对象,代理对象调用hashCode()时,Spring会把调用转发给持有的目标对象执行,所以返回值和方法内部this(原生目标对象)的hashCode()完全相等。

内容的提问来源于stack exchange,提问作者BeastMaster64

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:24:07