首页 > 解决方案 > Spring 4 @Conditional:环境属性不可用,除非使用@PropertySource

问题描述

问题:

在类中使用@Conditionalbean 定义时,来自外部源(例如文件)的属性在评估时@Configuration不可用-除非使用。无论使用哪个,使用代替都没有区别。EnvironmentCondition#matches @PropertySourceConfigurationConditionConditionConfigurationPhase

由于我还需要对属性文件的名称使用通配符,因此使用@PropertySource不是一种选择,因为它要求位置是绝对的。Spring Boot 完全不在桌面上,因此@ConditionalOnProperty也不是一个选择。这让我将PropertySourcesPlaceholderConfigurerbean 定义为唯一剩余的可行选项。

问题:

有没有办法根据Environment使用普通 Spring 机制(不是引导,而不是其他一些 hacky 方式)中的属性的存在、不存在或值来定义 bean,同时还使用通配符指定属性位置,如果是这样,需要什么完毕?

例子:

在下面的测试中JUnit,我希望一个名为的 bean可用bean,如果在. 情况并非如此,因此测试失败。keynullEnvironmentmatchesPropertyCondition

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ConditionTest.ConditionTestConfiguration.class })
public class ConditionTest {

  private static final String PROPERTIES_LOCATION = "test.properties";
  private static final String BEAN_NAME = "bean";

  @Autowired
  private ApplicationContext applicationContext;

  @Test
  public void testBeanNotNull() {
    assertNotNull(applicationContext.getBean(BEAN_NAME));
  }

  @Configuration
  static class ConditionTestConfiguration {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
      PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
      propertySourcesPlaceholderConfigurer.setLocation(new ClassPathResource(PROPERTIES_LOCATION));
      return propertySourcesPlaceholderConfigurer;
    }

    @Bean
    @Conditional(PropertyCondition.class)
    public Object bean() {
      return BEAN_NAME;
    }

  }

  static class PropertyCondition implements ConfigurationCondition {

    private static final String PROPERTY_KEY = "key";

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
      return context.getEnvironment().getProperty(PROPERTY_KEY) != null;
    }

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

  }

}

一旦我像这样添加@PropertySource注释ConditionTestConfiguration

  @Configuration
  @PropertySource("classpath:test.properties")
  static class ConditionTestConfiguration 

该属性key可用,因此该PropertyCondition#matches方法的计算结果为 true,因此bean在 中可用ApplicationContext并且测试通过。

附加信息:

标签: javaspringproperties

解决方案


推荐阅读