Can I manually load @ConfigurationProperties without the Spring AppContext?

前端 未结 5 1674
天命终不由人
天命终不由人 2021-01-02 00:28

Is there any way to load a class marked with @ConfigurationProperties without using a Spring Context directly? Basically I want to reuse all the smart logic tha

5条回答
  •  时光说笑
    2021-01-02 01:10

    I had the same "issue". Here is how I solved it in SpringBoot version 1.3.xxx and 1.4.1.

    Let's say we have the following yaml configuration file:

    foo:
      apis:
          -
           name: Happy Api
           path: /happyApi.json?v=bar
          -
           name: Grumpy Api
           path: /grumpyApi.json?v=grrr
    

    and we have the following ConfigurationProperties:

    @ConfigurationProperties(prefix = "foo")
    public class ApisProperties {
        private List apis = Lists.newArrayList();
    
        public ApisProperties() {
        }
    
        public List getApis() {
            return apis;
        }
    
        public static class ApiPath {
            private String name;
            private String path;
    
            public String getName() {
                return name;
            }
    
            public void setName(final String aName) {
                name = aName;
            }
    
            public String getPath() {
                return path;
            }
    
            public void setPath(final String aPath) {
                path = aPath;
            }
        }
    } 
    

    Then, to do the "magic" things of Spring Boot programmatically (e.g. loading some properties in a static method), you can do:

    private static ApisProperties apiProperties() {
        try {
            ClassPathResource resource;
            resource = new ClassPathResource("/config/application.yml");
    
            YamlPropertiesFactoryBean factoryBean;
            factoryBean = new YamlPropertiesFactoryBean();
            factoryBean.setSingleton(true); // optional depends on your use-case
            factoryBean.setResources(resource);
    
            Properties properties;
            properties = factoryBean.getObject();
    
            MutablePropertySources propertySources;
            propertySources = new MutablePropertySources();
            propertySources.addLast(new PropertiesPropertySource("apis", properties));
    
            ApisProperties apisProperties;
            apisProperties = new ApisProperties();
    
            PropertiesConfigurationFactory configurationFactory;
            configurationFactory = new PropertiesConfigurationFactory<>(apisProperties);
            configurationFactory.setPropertySources(propertySources);
            configurationFactory.setTargetName("foo"); // it's the same prefix as the one defined in the @ConfigurationProperties
    
            configurationFactory.bindPropertiesToTarget();
            return apisProperties; // apiProperties are fed with the values defined in the application.yaml
    
        } catch (BindException e) {
            throw new IllegalArgumentException(e);
    
        }
    }
    

提交回复
热议问题