Spring Boot 3.2.1迁移后动态方法调用报错求助
Spring Boot 3.2.1(Java 21)动态方法调用异常修复
错误根源
修改后的代码中,调用Method.invoke()时错误传入了targetClass(Class类对象)作为第一个参数,但save是实例方法,必须传入该类的实际对象实例而非Class对象,这直接触发了IllegalArgumentException: Object is not an instance of declaring class异常。
修复方案
方案一:利用代理对象转发调用
无需额外获取真实目标对象,只需将invoke的第一个参数改为原始的serviceObject(代理对象)即可,Spring AOP代理会自动将调用转发给真实目标对象:
// Invokes the save method on the target class Object savedObject = targetClass.getMethod("save", moduleClass).invoke(serviceObject, object);
方案二:直接获取真实目标对象调用
如果需要直接操作真实目标实例,可通过AopProxyUtils获取(需确保项目依赖包含spring-aop):
// 获取真实目标对象 Object targetObject = AopProxyUtils.getSingletonTarget(serviceObject); // 兼容非代理场景 if (targetObject == null) { targetObject = serviceObject; } // 调用目标方法 Object savedObject = targetClass.getMethod("save", moduleClass).invoke(targetObject, object);
关于Spring Boot 3的代理变化说明
Spring Boot 3默认对实现接口的Bean使用JDK动态代理(替代了Spring Boot 2.x部分场景的CGLIB代理)。JDK代理基于接口实现,代理类不会继承目标ServiceImpl类,因此直接通过serviceObject.getClass()获取的代理类中,不存在ServiceImpl中未在接口声明的方法,这就是最初出现NoSuchMethodException的原因。通过AopProxyUtils.ultimateTargetClass可以正确获取到真实目标类,从而找到对应的save方法。
内容的提问来源于stack exchange,提问作者Gopikrishna
相关产品推荐
相关产品推荐

