java Spring ApplicationContext.getBean(Class c) 不适用于代理类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11535527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring ApplicationContext.getBean(Class c) not working for proxy classes
提问by Alex Worden
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.
我需要通过它们的类类型查找 bean。当 bean 被代理包装时(某些方法是 @Transactional) - ApplicatoinContext 无法找到它们。我发现如果我通过接口查找它们,它可以工作,但在这种情况下,我正在使用具体的类类型。我知道 bean 是我正在寻找的类型,但 getBean() 方法失败。
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 的 AbstractBeanFactory 代码中的问题。问题是它根据我请求的类型检查 beanInstance 的类型,但 beanInstance.getClass() 是一个代理。AbstractBeanFactory 应该对此进行补偿并将类型与代理的目标类进行比较。
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 的修补版本,我怀疑必须有一些我可以配置的东西才能使其正常工作,或者这真的是一个错误吗?
回答by Tomasz Nurkiewicz
There are two major ways Spring implements AOP (e.g. @Transactional
support): either by using proxy interfaces or CGLIB.
Spring 实现 AOP 的主要方式有两种(例如@Transactional
支持):使用代理接口或 CGLIB。
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.
使用接口(默认),如果您的类实现了任何接口,Spring 将创建一个实现所有这些接口的代理。从现在开始,您只能通过该接口使用您的 bean。你的班级深深地埋在他们里面。
If you enable proxying target classes instead via cglib:
如果您通过cglib启用代理目标类:
<aop:config proxy-target-class="true">
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.
Spring 将创建一个子类(显然仍然实现所有接口)。这将解决您的问题。但是请记住,返回的对象实际上并不是您的类,而是动态生成的子类,它包装并委托给您的原始对象。在大多数情况下,这应该不是问题。
And no, of course this is not a bug but well known behaviour and no, there is no need to patch Spring.
不,当然这不是错误而是众所周知的行为,不,不需要修补 Spring。
See also
也可以看看
回答by Dangling Piyush
<context:component-scan base-package="<Your base package name goes here>" />
<aop:aspectj-autoproxy />
<aop:config proxy-target-class="true"/>
write these three lines in applicationContext.xml this worked for me.
在 applicationContext.xml 中写下这三行这对我有用。