使用spring-boot @ConditionalOnMissingBean的Spring配置类加载顺序?

时间:2014-12-19 15:08:31

标签: java spring spring-boot

我想使用@ConditionalOnMissingBean启用自定义配置和合理默认设置吗? 我有一个春季启动应用程序:

@Configuration
@Import({CustomConfiguration.class, DefaultConfiguration.class})
@EnableAutoConfiguration(exclude={MetricFilterAutoConfiguration.class})
public class Application {

    @Autowired
    ErrorListener errorListener;
}

和允许Spring xml或组件扫描的CustomConfiguration

@Configuration("customConfiguration")
@ImportResource("classpath:customContext.xml")
@ComponentScan({"org.custom.impl"})
public class CustomConfiguration

DefaultConfiguration使用ConditionalOnMissingBean

@Bean
@ConditionalOnMissingBean 
ErrorListener errorListener() {
     return new LoggingErrorListener();
}

我想要实现的是允许在类路径中定义自定义ErrorListener,如果未定义,则使用默认LoggingErrorListener(通过ConditionalOnMissingBean)。我发现在DefaultConfiguration之前总是使用CustomConfiguration

我一直在尝试@DependsOn@Order,但没有快乐。

2 个答案:

答案 0 :(得分:4)

如果我是你,我不会在自动配置类之外使用@ConditionalOnMissingBean,除非你可以控制@Configuration类的导入顺序。自动配置是明确的,但普通的用户配置类(特别是如果它们是@ComponentSCanned)没有定义的顺序。

答案 1 :(得分:-1)

回应Daves回答:看起来它适用于不会干扰Spring Boot的独立bean。例如,在为Spring Boot应用程序开发库时,我想提供一个RestTemplate,如果应用程序开发人员没有提供它。 @ConditionalOnMissingBean似乎有效:

@Bean
@ConditionalOnMissingBean(RestTemplate.class)
public RestTemplate restTemplate() {

    return new RestTemplate();
}

为了确认它是否能够保持一致,我看了一下Spring的源代码(例如参见ConditionEvaluator)。看来Spring在第一遍中跳过创建带有@ConditionalOnMissingBean注释的bean。然后它将执行第二次传递来配置这些bean。

另外,我看到@ConditionalOnMissingBean@Configuration类或@Beans内部配置类中运行良好。但它在其他地方不能正常工作,例如在用@Component注释的类上或内部。