Spring Boot在Java中使用JDK或CGLIB动态代理时,如何调试



我遇到了一个问题,在类中添加注释会产生代理错误

名为"XXXX"的Bean的类型应为"XXXX.XXXX",但实际类型为"com.sun.proxy.$Proxy223">

有关更多详细信息,请参阅如何在@Component上启用CGLIB代理?

我试图了解Java何时决定创建JDK或CGLIB代理。我知道这意味着在有接口的情况下创建JDK代理,而在其他情况下创建CGLIB代理。Plus SpringBoot 2.0+旨在始终使用CGLIB代理。看见https://www.springcloud.io/post/2022-01/springboot-aop/#gsc.tab=0

然而,在我的情况下,当没有接口时,我得到了JDK代理。因此,我想弄清楚代码在哪里做出这个决定,以便对其进行调试

这可能是通过AbstractAdvisorAutoProxyCreator的实现来实现的。但实际上,找到做出决定的点是很耗时的。即使手头有调试器。

有指针吗?

我发现隐藏在Configuration层次结构中的以下bean定义。

@Bean
public AnnotationAwareAspectJAutoProxyCreator aspectJProxyCreator() {
return new AnnotationAwareAspectJAutoProxyCreator();
}

这似乎是问题的根源。这令人印象深刻,因为我的Component名为XXXX,它不是一个接口,也没有实现接口。即,这意味着不应该使用JDK代理。

如果我将bean定义切换到

@Bean
public AnnotationAwareAspectJAutoProxyCreator aspectJProxyCreator() {
var a = new AnnotationAwareAspectJAutoProxyCreator();
// Fixes the problem
a.setProxyTargetClass(true);
return a;
}

而是创建一个CGLIB代理。一个更好的解决方案是完全删除这个bean,我正在对此进行调查。

最新更新