Spring ApplicationContext.getBean(Class c)不适用于代理类 [英] Spring ApplicationContext.getBean(Class c) not working for proxy classes

查看:1300
本文介绍了Spring ApplicationContext.getBean(Class c)不适用于代理类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要通过类类型查找bean。当bean被代理包装时(某些方法是@Transactional) - ApplicatoinContext无法找到它们。我发现,如果我通过接口查找它们,它可以工作,但在这种情况下,我正在使用具体的类类型。我知道bean是我正在寻找的类型,但getBean()方法失败。

I need to look up beans via their class type. When the beans have been wrapped by a Proxy (some methods are @Transactional) - the ApplicatoinContext fails to find them. I find that if I look them up via an interface, it works but in this case I'm working with a concrete class type. I know the bean is of the type I'm looking for but the getBean() method fails.

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

I can debug (and fix) the problem in Spring's AbstractBeanFactory code. The issue is that it checks the type of the beanInstance against type I'm requesting but the beanInstance.getClass() is a Proxy. AbstractBeanFactory should compensate for this and compare the type to the proxy's target class.

我已经解决了这个问题,但我并不特别想使用Spring的补丁版本,我怀疑必须有一些东西我可以配置才能使这个工作,或者这真的是一个错误吗?

I have a fix for this but I don't particularly want to use a patched version of Spring and I suspect there must be something I can configure to get this working, or is this really a bug?

推荐答案

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

There are two major ways Spring implements AOP (e.g. @Transactional support): either by using proxy interfaces or CGLIB.

如果您的类实现了任何接口,那么使用接口(默认),Spring将创建一个实现所有接口的代理。从现在开始,您只能通过该接口使用您的bean。你的班级深陷其中。

With interfaces (default) if your class implements any interfaces, Spring will create a proxy implementing all that interfaces. From now on you can only work with your bean through that interfaces. Your class is deeply burried inside them.

如果你通过 cglib

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

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

Spring will create a subclass (obvoiusly still implementing all your interfaces) instead. This will fix your problem. However remember that the returned object is not really your class but dynamically generated subclass that wraps and delegates to your original object. This shouldn't be a problem in most of the cases.

不,当然这不是一个错误,但众所周知的行为,不,没有必要补丁春天。

And no, of course this is not a bug but well known behaviour and no, there is no need to patch Spring.

  • Location of the proxy class generated by Spring AOP
  • Getting Spring Error "Bean named 'x' must be of type [y], but was actually of type [$Proxy]" in Jenkins
  • How to mix CGLIB and JDK proxies in Spring configuration files?
  • Mocking a property of a CGLIB proxied service not working

这篇关于Spring ApplicationContext.getBean(Class c)不适用于代理类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆