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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27568728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:00:47  来源:igfitidea点击:

Spring configuration class loading order with spring-boot @ConditionalOnMissingBean?

javaspringspring-boot

提问by Gethin James

I'd like to enable custom configuration and sensible defaults using @ConditionalOnMissingBean? I have a spring boot application:

我想使用@ConditionalOnMissingBean? 我有一个弹簧启动应用程序:

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

    @Autowired
    ErrorListener errorListener;
}

and a CustomConfigurationthat allows for either Spring xml or component scanning:

和一个CustomConfiguration允许 Spring xml 或组件扫描:

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

The DefaultConfigurationuses ConditionalOnMissingBean:

DefaultConfiguration用途ConditionalOnMissingBean

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

What I'm trying to achieve is allow for a custom ErrorListenerto be defined in the classpath, if not defined then use the default LoggingErrorListener(via the ConditionalOnMissingBean). I'm finding that the DefaultConfigurationis always being used before the CustomConfiguration.

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

I've been experimenting with @DependsOnand @Orderbut no joy.

我一直在尝试@DependsOn@Order,但没有喜悦。

回答by Dave Syer

I wouldn't use @ConditionalOnMissingBeanoutside of an auto-configuration class if I were you, unless you can control the order of import of @Configurationclasses. Auto-configuration does it explicitly, but normal user config classes (especially if they are @ComponentSCanned) do not have a defined order.

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

回答by Sanjay

In response to Daves answer: Looks like it works for independent beans which wouldn't interfere with Spring Boot. For example, when developing a library for Spring Boot applications, I wanted to provide a RestTemplateif one is not provided by the the application developer. @ConditionalOnMissingBeanseemed to work:

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

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

    return new RestTemplate();
}

To confirm whether it would work consistently, I gave a look at Spring's source code (e.g. see ConditionEvaluator). Seemed that Spring skips creating beans with @ConditionalOnMissingBeanannotations in the first pass. It would then do a second pass to configure these beans.

为了确认它是否能始终如一地工作,我查看了 Spring 的源代码(例如,参见ConditionEvaluator)。似乎 Spring@ConditionalOnMissingBean在第一遍跳过创建带有注释的bean 。然后它会做第二遍来配置这些 bean。

Also, I saw that @ConditionalOnMissingBeanworks well on @Configurationclasses or @Beansinside configuration classes. But it does not work properly elsewhere, e.g. on or inside classes annotated with @Component.

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