我想使用@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
,但没有快乐。
答案 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
注释的类上或内部。