Spring ApplicationContext.getBean(Class c)不适用于代理类



我需要通过bean的类类型来查找它们。当bean被代理(有些方法是@Transactional)包装时,ApplicatoinContext无法找到它们。我发现,如果我通过接口查找它们,它是有效的,但在这种情况下,我使用的是一个具体的类类型。我知道bean是我想要的类型,但是getBean()方法失败了。

我可以调试(并修复)Spring的AbstractBeanFactory代码中的问题。问题是它根据我请求的类型检查beanInstance的类型,但beanInstance.getClass()是一个代理。AbstractBeanFactory应该对此进行补偿,并将类型与代理的目标类进行比较。

我对此有一个修复程序,但我并不特别想使用Spring的修补版本,我怀疑一定有一些东西可以配置以使其正常工作,或者这真的是一个bug吗?

Spring实现AOP(例如@Transactional支持)的主要方式有两种:使用代理接口或CGLIB。

对于接口(默认),如果您的类实现了任何接口,Spring将创建一个实现所有接口的代理。从现在起,您只能通过这些接口使用您的bean。你的课被深深地埋在里面了。

如果您通过cglib:启用代理目标类

<aop:config proxy-target-class="true">

Spring将创建一个子类(显然仍然实现所有接口)。这将解决您的问题。但是,请记住,返回的对象并不是真正的类,而是动态生成的子类,它包装并委托给原始对象。在大多数情况下,这不应该是个问题。

不,当然这不是一个bug,而是众所周知的行为,不,没有必要修补Spring。

另请参阅

  • Spring AOP生成的代理类的位置
  • 获取弹簧错误";名为';x';必须是[y]类型,但实际上是[$Proxy]"类型;在詹金斯
  • 如何在Spring配置文件中混合使用CGLIB和JDK代理
  • 模拟CGLIB代理服务的属性不工作
<context:component-scan base-package="<Your base package name goes here>" />
<aop:aspectj-autoproxy />
<aop:config proxy-target-class="true"/>

在applicationContext.xml中写下这三行,这对我很有用。

最新更新