即使打开了大量的调试,这个让我神秘化了。我有一个像这样定义的spring bean:
@Component
public class GraphHistoryLoader {
...
}
我将它注入另一个这样的bean:
@Component
public class StartupPostProcessor {
@Autowired
GraphHistoryLoader historyLoader;
}
这适用于实例化GraphHistoryLoader并注入StartupPostProcessor。但是,如果我然后向GraphHistoryLoader添加一个接口,如下所示:
@Component
public class GraphHistoryLoader implements FXCommandLineAware {
...
}
我看到Spring创建的GraphHistoryLoader可用于注入,但是注入StartupPostProcessor失败了:
Error creating bean with name 'startupPostProcessor':
Injection of auto wired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException:
Could not autowire field: au.com.anz.fx.process.GraphHistoryLoader
au.com.anz.fx.process.StartupPostProcessor.historyLoader
奇怪的是我有其他类也实现了FXCommandLineAware接口,它们工作得很好。很高兴基于他们的课程注入其他豆类。关于这个特定定义和注入导致失败的一些事情。
有没有人有什么想法可以看?
答案 0 :(得分:1)
我遇到了同样的问题,但另外我使用了Spring AOP。这意味着您的示例中的GraphHistoryLoader
由Spring代理以实现AOP处理。 Spring以两种方式使用代理。见spring docs
BeanCreationException
要在这两个选项之间切换,启用spring-aop时,请在xml中指定标记proxy-target-class
。
<aop:config proxy-target-class="true">
<!-- other beans defined here... -->
</aop:config>
或者在Java Spring Config类中通过注释
@EnableAspectJAutoProxy(proxyTargetClass = true)
请注意,代理在Spring中用于其他模块,如事务和缓存。然后你需要在主题的模块的相应位置设置标志proxyTargetClass
。
答案 1 :(得分:0)
您是否在applicationContext xml文件中定义了compoent-scan。组件扫描会扫描您声明的包,如果找到注释@ Component,@ Service,@ Repository,@ Controller或@Configuration将为您创建一个bean实例。
请确保您在组件扫描中定义的包(也包括GraphHistoryLoader类包)。
<context:component-scan base-package="com.mycompany.*"/>
可能的原因是: 声明GraphHistoryLoader的上下文既不是与StartupPostProcessor相同的上下文,也不是父上下文
答案 2 :(得分:0)
如果调试代码,spring类ClassUtils.java#isAssignableValue(Class,Class)正在比较类的实际类型与“proxy”类(类型为com.sun.proxy。$ Proxy47)。这就是为什么它不起作用的原因:
public static boolean isAssignableValue(Class<?> type, Object value) {
Assert.notNull(type, "Type must not be null");
return (value != null ? isAssignable(type, value.getClass()) : !type.isPrimitive());
}
目前有两种选择:
示例:
<tx:annotation-driven proxy-target-class="true"/>
答案 3 :(得分:0)
Spring AOP默认将标准JDK动态代理用于AOP代理。这使得可以代理任何接口(或一组接口)。参见AOP Proxies docs。因此,当您的bean实现任何接口时,都会使用JDK Proxy.getProxyClass
进行复制,并且在创建的代理bean中只有接口方法可用。
为了在全局范围内强制类字节码生成,请在@Andrés答案中使用AOP配置。或者,您可以专门在问题Bean上声明此代理类型:
@Component
@Scope( proxyMode = ScopedProxyMode.TARGET_CLASS )
public class GraphHistoryLoader implements FXCommandLineAware {
....
}