подстановочный знак classpath в @PropertySource

Я использую конфигурацию Spring Java для создания своего bean-компонента. Но этот бин является общим для 2-х приложений. Оба имеют один файл свойств abc.properties, но с разными путями к классам. Когда я помещаю явный путь к классам, например

@PropertySource("classpath:/app1/abc.properties")

тогда это работает, но когда я пытаюсь использовать подстановочный знак, например

@PropertySource("classpath:/**/abc.properties")

тогда это не работает. Я пробовал много комбинаций подстановочных знаков, но это все равно не работает. Работает ли подстановочный знак в @ProeprtySource Есть ли другой способ чтения свойства в классе, отмеченном @Configurations.


person dmay    schedule 17.01.2013    source источник


Ответы (3)


API @PropertySource: 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;
    }
person Evgeniy Dorofeev    schedule 18.01.2013
comment
Добавление модификатора static предотвратит выдачу предупреждений во время развертывания: ConfigurationClassEnhancer:310 - метод @Bean Test.getPropertyPlaceholderConfigurer не является статическим и возвращает объект, назначаемый интерфейсу Spring BeanFactoryPostProcessor. Это приведет к невозможности обработки аннотаций, таких как @Autowired, @Resource и @PostConstruct, в методе, объявляющем класс @Configuration. Добавьте к этому методу модификатор static, чтобы избежать проблем с жизненным циклом контейнера; полную информацию см. в @Bean javadoc. Но спасибо, это сработало как шарм. - person Mital Pritmani; 11.08.2015

В дополнение к обходному пути dmay:

Начиная с Spring 3.1, PropertySourcesPlaceholderConfigurer следует использовать предпочтительно, а не PropertyPlaceholderConfigurer, а компонент должен быть статическим.

@Configuration
public class PropertiesConfig {

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

}
person Michal Z m u d a    schedule 01.09.2013
comment
В этом решении есть существенная проблема: приоритет свойств, импортированных PropertySourcesPlaceholderConfigurer#setLocations, даже выше, чем системных свойств. Таким образом, вы не можете использовать системные свойства или аргументы командной строки для их переопределения. - person Bian Jiaping; 13.08.2018

Если вы используете свойства 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 {
    // ...
}
person aksh1618    schedule 17.02.2021