Spring:何时扩展bean与它的祖先不兼容?

时间:2016-10-26 16:31:53

标签: spring spring-bean

我有两个已定义的组件

A类

package a;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
class A extends OncePerRequestFilter {

B类

package b;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@Primary
class A extends a.A {

在我的Spring(启动4.2.5)应用程序中使用这两个组件,我收到以下错误:

... 
nested exception is org.springframework.context.annotation.
ConflictingBeanDefinitionException:
Annotation-specified bean name 'a' for bean class [a.A] conflicts with existing, 
non-compatible bean definition of same name and class [b.A]

我本来期望(并且我希望),b.A将用于支持a.A替换/被覆盖。

为什么我在这里收到此错误消息?如何将b.A用作“组件a”?

完全异常/ sprint-boot启动错误:

Application startup failed","stack_trace":"o.s.c.a.ConflictingBeanDefinitionException: 
Annotation-specified bean name 'httpAccessLogFilter' for bean class [b.A] conflicts with existing, 
non-compatible bean definition of same name and class [a.A]
at o.s.c.a.ClassPathBeanDefinitionScanner.checkCandidate(ClassPathBeanDefinitionScanner.java:320)
at o.s.c.a.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:259)
at o.s.c.a.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:137)
at o.s.c.a.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:268)
at o.s.c.a.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:232)
at o.s.c.a.ConfigurationClassParser.parse(ConfigurationClassParser.java:199)
at o.s.c.a.ConfigurationClassParser.parse(ConfigurationClassParser.java:168)
... 16 common frames omitted
Wrapped by: o.s.b.f.BeanDefinitionStoreException: Failed to parse configuration class [a.SpringBootApplication]; 
nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: A
nnotation-specified bean name 'a' for bean class [b.A] conflicts with existing, non-compatible bean definition of same name and class [a.A]
at o.s.c.a.ConfigurationClassParser.parse(ConfigurationClassParser.java:182)
at o.s.c.a.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:321)
at o.s.c.a.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
at o.s.c.s.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273)
at o.s.c.s.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:98)
at o.s.c.s.AbstractApplicationContext.invokeBeanFactoryPostProcessors(Abst...

1 个答案:

答案 0 :(得分:1)

似乎不支持来自不同包的相同bean。

  

"当现有bean定义来自同一来源或非扫描来源时,它们认为是兼容的。" ClassPathBeanDefinitionScanner:isCompatible

在Spring,他们的问题跟踪器中已经讨论过这个问题,请参阅SPR-14665SPR-10808

我得到了一个丑陋的解决方法。 祖先获得了不同的名称,并注释了#34; ConditionalOnMissingBean"。

祖先:

package a;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnMissingBean(name = "a")
class AncestorOfA extends OncePerRequestFilter {

B组:

package b;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
class A extends a.AncestorOfA {

这样,我有组件" ancestorOfA",如果我不想实现自己的组件。如果我想使用自己的版本,我将使用组件" a",但不是" ancestorOfA"。

明显的缺点是,子组件的名称正确。