我有一个Spring @Configuration
类,当在环境中设置特定属性值时,它应该注册一个bean。我编写了一个自定义的Condition
实现来检查该值是否存在,当我在Spring Boot中启动应用程序时,它可以工作,但是在运行JUnit测试时,bean从未注册过。我调试了应用程序,确定在实例化PropertySourcesPlaceholderConfigurer
之前对Condition
进行了评估。
我修改了我的Condition
来实现ConfigurationCondition
,并在REGISTER_BEAN
阶段指定评估。在配置器实例化之前仍然调用该方法,但是当我从属性文件中添加或删除属性时,注册的bean就会出现或消失。
这是重新排序求值的最好方法吗?这是ConfigurationCondition
接口的目的,还是我只是不小心让它现在工作?
@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;
}
}
测试配置是我的测试用例中的静态类:
@Configuration
@ComponentScan
@PropertySource("classpath:/postback.properties")
@Import(PostbackUrlConfiguration.class)
public static class TestConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
@Configuration
类的解析阶段包括读取它的类定义、填充Configuration对象的集合(因为一个@Configuration
类可能会@Import
另一个@Configuration
类,所以这些导入也会被解析)、处理@PropertySources
、@ImportResources
等。
处理@PropertySources
也不会加载这些属性。解析阶段完成后,将加载@PropertySources
属性。加载这些之后,然后注册来自@Configuration
类内部的bean定义(REGISTER_BEAN阶段)。
因此,您使用ConfigurationCondition
和ConfigurationPhase.REGISTER_BEAN
阶段所看到的是预期的,因为在注册bean定义时以及在解析@Configuration
类之后,这些属性实际上在Environment
中可用。仅使用Condition
,我相信它甚至没有达到@Configuration
的解析阶段,评估甚至在此之前完成,当@Configuration
类定义要注册时。