Spring Environment backed by Typesafe Config

前端 未结 4 1680
庸人自扰
庸人自扰 2020-12-30 01:22

I want to use typesafe config (HOCON config files) in my project, which facilitate easy and organized application configuration. Currently I am using normal Java properties

4条回答
  •  臣服心动
    2020-12-30 01:55

    I tried all of the above and failed. One particular problem I had was initilization order of the beans. We for example needed flyway support to pick up some overriden properties which come from a typesafe config and also the same for other properties.

    As suggested in one of the comments from m-deinum for us the following solutions works, also relying on the input from the other answers. By using an ApplicationContextInitializer when loading the main App we make sure that the props are loaded at the start of the App and merged into the "env" correctly:

    import org.springframework.boot.SpringBootConfiguration;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.context.annotation.Import;
    
    @SpringBootConfiguration
    @Import({MyAppConfiguration.class})
    public class MyApp {
    
        public static void main(String[] args) {
            new SpringApplicationBuilder(MyApp.class)
                .initializers(new MyAppContextInitializer())
                .run(args);
        }
    }
    

    The ContextInitializer looks like this:

    import org.springframework.context.ApplicationContextInitializer;
    import org.springframework.context.ConfigurableApplicationContext;
    
    public class MyAppContextInitializer implements
        ApplicationContextInitializer {
    
        @Override
        public void initialize(ConfigurableApplicationContext ac) {    
            PropertiesLoader loader = new PropertiesLoader(ac.getEnvironment());
            loader.addConfigToEnv();
        }
    
    } 
    

    The PropertiesLoader works like this to load the properties from the config and stuff it into the environment:

    import com.typesafe.config.Config;
    import com.typesafe.config.ConfigFactory;
    import org.springframework.core.env.ConfigurableEnvironment;
    import org.springframework.core.env.MutablePropertySources;
    
    class PropertiesLoader {
    
        private ConfigurableEnvironment env;
    
        public PropertiesLoader(ConfigurableEnvironment env) {
            this.env = env;
        }
    
        public void addConfigToEnv() {
            MutablePropertySources sources = env.getPropertySources();
    
            Config finalConfig = ConfigFactory.load().resolve();
            // you can also do other stuff like: ConfigFactory.parseFile(), use Config.withFallback to merge configs, etc.
            TypesafeConfigPropertySource source = new TypesafeConfigPropertySource("typeSafe", finalConfig);
    
            sources.addFirst(source);
        }
    
    }
    

    And we also need the TypesafeConfigPropertySource which works for the typesafe config:

    import com.typesafe.config.Config;
    import org.springframework.core.env.PropertySource;
    
    public class TypesafeConfigPropertySource extends PropertySource {
    
        public TypesafeConfigPropertySource(String name, Config source) {
            super(name, source);
        }
    
        @Override
        public Object getProperty(String path) {
            if (path.contains("["))
                return null;
            if (path.contains(":"))
                return null;
            if (source.hasPath(path)) {
                return source.getAnyRef(path);
            }
            return null;
        }
    
    }
    

提交回复
热议问题