如何延迟对Spring @Conditional配置注释的评估? [英] How do I delay evaluation of a Spring @Conditional configuration annotation?

查看:106
本文介绍了如何延迟对Spring @Conditional配置注释的评估?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring @Configuration类,当在环境中设置了特定的属性值时,该类应该注册一个bean.我编写了一个自定义的Condition实现,用于检查该值是否存在,并且在Spring Boot中启动该应用程序时可以运行,但是在运行JUnit测试时从未注册该bean.我调试了该应用程序,并确定在实例化PropertySourcesPlaceholderConfigurer之前正在评估Condition.

I have a Spring @Configuration class that should register a bean when a specific property value is set in the environment. I wrote a custom Condition implementation that checked whether the value was present, and it works when I fire up the application in Spring Boot, but the bean was never registered when running JUnit tests. I debugged the application and determined that the Condition was being evaluated before the PropertySourcesPlaceholderConfigurer was being instantiated.

我修改了Condition以实现ConfigurationCondition,并在REGISTER_BEAN阶段指定了评估.在实例化配置程序之前,仍会调用该方法,但是随着我在属性文件中添加或删除属性,已注册的bean现在来来往往.

I modified my Condition to implement ConfigurationCondition and specify evaluation during the REGISTER_BEAN phase. The method is still called before the configurer is instantiated, but the registered bean now comes and goes as I add or remove the property from the properties file.

这是重新排序评估的最佳方法吗?这是ConfigurationCondition界面的目的,还是我现在不小心使它开始工作?

Is this the best way to reorder the evaluation? Is this what the ConfigurationCondition interface is for, or am I just accidentally getting it to work now?

@Conditional(PropertyCondition.class)
@Configuration
public class PostbackUrlConfiguration {
    @Value("${serviceName.postbackUrl}")
    String postbackUrl;

    @Bean
    public PostbackUrlProvider provider() {
        return new FixedUrlProvider(postbackUrl);
    }
}

 

public class PropertyCondition implements ConfigurationCondition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment().containsProperty("serviceName.postbackUrl");
    }

    @Override
    public ConfigurationPhase getConfigurationPhase() {
        return ConfigurationPhase.REGISTER_BEAN;
    }
}

测试配置是我的测试用例的静态类:

The test configuration is a static class on my test case:

@Configuration
@ComponentScan
@PropertySource("classpath:/postback.properties")
@Import(PostbackUrlConfiguration.class)
public static class TestConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

推荐答案

The parsing phase for a @Configuration class involves reading its class definition, populating a collection of Configuration objects (because one @Configuration class may @Import another @Configuration class so these imports are parsed as well), processing @PropertySources, @ImportResources etc.

处理@PropertySources也不加载那些属性.解析阶段完成后,将加载@PropertySources属性.加载这些后,然后将注册@Configuration类内部的bean的定义(REGISTER_BEAN阶段).

Processing @PropertySources doesn't, also, load those properties yet. After the parsing phase is done, the @PropertySources properties are loaded. After these are loaded, then the beans' definitions from inside @Configuration classes are registered (REGISTER_BEAN phase).

因此,可以预期将ConfigurationConditionConfigurationPhase.REGISTER_BEAN阶段结合使用会看到什么,因为在注册bean的定义时以及在解析@Configuration类之后,这些属性实际上在Environment中可用. . 我相信仅使用Condition甚至还没有达到@Configuration的解析阶段,甚至在注册@Configuration类定义时就已经执行了评估.

So, what you see using a ConfigurationCondition with ConfigurationPhase.REGISTER_BEAN phase is expected because those properties are actually available in the Environment at the time when beans' definitions are registered and after the @Configuration class has been parsed. Using just a Condition I believe it doesn't even reach the parsing phase of a @Configuration, the evaluation is done even before that, when the @Configuration class definition is to be registered.

这篇关于如何延迟对Spring @Conditional配置注释的评估?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆