@PropertySource中的classpath通配符

时间:2013-01-17 23:25:11

标签: java spring config

我正在使用Spring Java配置来创建我的bean。 但是这个bean在2个应用程序中很常见。 两者都有一个属性文件abc.properties但具有不同的类路径位置。 当我把类似

的显式类路径
@PropertySource("classpath:/app1/abc.properties")

然后它可以工作,但当我尝试使用像

这样的通配符时
@PropertySource("classpath:/**/abc.properties")

然后它不起作用。 我尝试了许多通配符的组合,但它仍然无效。 通配符是否适用于@ProeprtySource 是否有其他方法可以读取标有@Configurations的分类中的属性。

3 个答案:

答案 0 :(得分:15)

@PropertySource API:Resource location wildcards (e.g. **/*.properties) are not permitted; each location must evaluate to exactly one .properties resource.

解决方法:尝试

@Configuration
public class Test {

    @Bean
    public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer()
            throws IOException {
        PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
        ppc.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/**/abc.properties"));
        return ppc;
    }

答案 1 :(得分:7)

添加到 dmay 解决方法:

由于Spring 3.1 PropertySourcesPlaceholderConfigurer应该优先于PropertyPlaceholderConfigurer使用,并且bean应该是静态的。

@Configuration
public class PropertiesConfig {

  @Bean
  public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
    PropertySourcesPlaceholderConfigurer propertyConfigurer = new PropertySourcesPlaceholderConfigurer();
    propertyConfigurer.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/**/abc.properties"));
    return propertyConfigurer;
  }

}

答案 2 :(得分:0)

如果您使用 YAML 属性,则可以使用自定义 PropertySourceFactory 来实现:

public class YamlPropertySourceFactory implements PropertySourceFactory {

    private static final Logger logger = LoggerFactory.getLogger(YamlPropertySourceFactory.class);

    @Override
    @NonNull
    public PropertySource<?> createPropertySource(
            @Nullable String name,
            @NonNull EncodedResource encodedResource
    ) {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        String path = ((ClassPathResource) encodedResource.getResource()).getPath();
        String filename = encodedResource.getResource().getFilename();
        Properties properties;
        try {
            factory.setResources(
                    new PathMatchingResourcePatternResolver().getResources(path)
            );
            properties = Optional.ofNullable(factory.getObject()).orElseGet(Properties::new);
            return new PropertiesPropertySource(filename, properties);
        } catch (Exception e) {
            logger.error("Properties not configured correctly for {}", path, e);
            return new PropertiesPropertySource(filename, new Properties());
        }
    }
}

用法:

@PropertySource(value = "classpath:**/props.yaml", factory = YamlPropertySourceFactory.class)
@SpringBootApplication
public class MyApplication {
    // ...
}