簡體   English   中英

Bean中發生沖突時,Spring Bean創建異常

[英]Spring Bean Creation Exception when Conflicts in Beans

以下是我們項目中使用的通用啟動器中提供的代碼。

@ConditionalOnProperty(prefix = "some.prefix", value = "some-enable")
@EnableConfigurationProperties(value = {
    SomeProperties.class,
})
@Configuration
class RabbitGenericValueConfiguration {

    @Autowired
    public void setuoRabbit(AmqpAdmin admin) {
        admin.declareExchange(exchange());
    }

    @ConditionalOnProperty(prefix = "existing.property", value = "setup")
    @ConditionalOnMissingBean
    @Bean
    Exchange exchange() {
        return ExchangeBuilder.topicExchange(properties.getExchange())
            .build();
    }

}    

在我們的服務中,我們需要創建一個自定義交換,但是,每當添加以下代碼時,都會發生以下錯誤

@Configuration
    public class CustomConfiguration {


        @Bean
        public DirectExchange direct() {
            return new DirectExchange("test.direct");
        }

    }

例外是

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'exchange' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.obtainBeanInstanceFromFactory(ConfigurationClassEnhancer.java:389)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361)
    at com.something.RabbitGenericValueConfiguration$$EnhancerBySpringCGLIB$$2df2c1f1.exchange(<generated>)
    at com.something.RabbitGenericValueConfiguration.setuoRabbit(RabbitGenericValueConfiguration.java:145)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

問題是,為什么在沒有自定義交換的情況下啟動應用程序,為什么在有自定義交換的情況下啟動失敗?

您聲明了名為bean的exchange例如:

@ConditionalOnProperty(prefix = "existing.property", value = "setup")
@ConditionalOnMissingBean
@Bean
Exchange exchange() {
    return ExchangeBuilder.topicExchange(properties.getExchange())
        .build();
}

聽起來這兩個聲明的bean派生自Exchange類。 因此,如果先實例化此bean,則@ConditionalOnMissingBean批注的存在會阻止實例化bean:

@Bean
public DirectExchange direct() {
    return new DirectExchange("test.direct");
}

正如@ConditionalOnMissingBean javadoc指出的(強調是我的):

僅當指定的Bean類和/或名稱尚未包含在BeanFactory中時, 條件才匹配。

如果您希望Spring實例化兩個實例,則應該刪除@ConditionalOnMissingBean

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM