开发者

springboot加载外部配置文件实践(properties、yml)

开发者 https://www.devze.com 2025-09-24 12:23 出处:网络 作者: 小鱼干。。
目录1.前言2.加载properties文件3.加载yml文件4.配置优先级对于优先读取该属性的值的解释5.使用的监听器以及加载的时机(监听的事件)备注:通过Environment取Spring配置中的值总结1.前言
目录
  • 1.前言
  • 2.加载properties文件
  • 3.加载yml文件
  • 4.配置优先级
    • 对于优先读取该属性的值的解释
  • 5.使用的监听器以及加载的时机(监听的事件)
    • 备注:通过Environment取Spring配置中的值
      • 总结

        1.前言

        通过PropertySourceLoader接口的实现类配合监听器实现加载外部的配置文件,加载properties文件使用PropertiesPropertySourceLoader,加载yml文件使用YamlPropertySourceLoader。

        通过监听器将配置文件加载到Spring环境配置中,且可以指定优先级。

        核心是将配置文件加载PropertySource中并将其添加到spring的MutablePropertySources中,使其可以通过@value等方式获取配置文件中的属性值。

        2.加载properties文件

        1.方法一:PropertiesPropertySourceLoader

        public class MyApplicationContextInitializer implements ApplicationContextInitializer {
            
            @Override
            public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
                PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
                try {
                    PropertySource<?> propertySource = loader.load("publicConfiguration", new InputStreamResource(Files.newInputStream(Paths.get("C:\\Users\\fkp12\\Desktop\\application.propwww.devze.comerties")))).get(0);
                    configurableApplicationContext.getEnvironment().getPropertySources().addFirst(propertySource);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        

        2.方法二:PropertiesFactoryBean

        public class MyApplicationContextInitializer implements ApplicationContextInitializer {
            
            @Override
            public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
                PropertiesFactoryBean factoryBean = new PropertiesFactoryBean();
                try {
                    factoryBean.setLocation(new InputStreamResource(Files.newInputStream(Paths.get("C:\\Users\\fkp12\\Desktop\\application.properties"))));
                    Properties object = factoryBean.getObject();
                    if(object != null){
                        PropertiesPropertySource propertySource = new PropertiesPropertySource("publicConfiguration",object);
                        configurableApplicationContext.getEnvironment().getPropertySources().addFirst(propertySource);
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        

        3.加载yml文件

        1.方法一:YamlPropertySourceLoader

        public class MyApplicationContextInitializer implements ApplicationContextInitializer {
            
            @Override
            public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        
                YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
                try {
                    PropertySource<?> propertySource = loader.load("externalConfiguration", new InputStreamResource(Files.newInputStream(Paths.get("C:\\Users\\fkp12\\Desktop\\application.yml")))).get(0);
                    configurableApplicationContext.getEnvironment().getPropertySources().addFirst(propertySource);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        

        2.方法二:YamlPropertiesFactoryBean

        public class MyApplicationContextInitializer implements ApplicationContextInitializer {
            
            @Override
            public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
                YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean();
                try {
                    factoryBean.setResources(new InputStreamResource(Files.newInputStream(Paths.get("C:\\Users\\fkp12\\Desktop\\application.yml"))));
                    Properties object = factoryBean.getObject();
                    if(object != null){
                        PropertiesPropertySource propertySource = new PropertiesPropertySource("publicConfiguration",object);
                        configurableApplicationContext.getEnvironment().getPropertySources().addFirst(propertySource);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        

        4.配置优先级

        通过上述代码可以发现所有方法最后都是通过configurableApplicationContext.getEnvironment().getPropertySources().addFirst(propertySource)将封装好的PropertySource对象加入到Spring配置中的,而都是通过调用addFirst(PropertySource  propertySource),除了addFirst还有addLast,addBefore,addAfter,这就与优先级有关系了,先说一下addBefore和addAfter,这两个方法参数都是String relativePropertySourceName, PropertySource<?> propertySource,意思就是要将此propertySource添加在名为relativePropertySourceName的propertySource的前边还是后边,放在前边的在读取属性时会优先读取属性值,而addFirst和addLast则是将此propertySource放在整个列表的最前或最后。

        对于优先读取该属性的值的解释

        例如项目中的配置文件application.yml中有属性name: zhangsan,外部配置文件externalApplication.yml中有属性name: lisi,通过上述任何方式将外部配置文件加载到Spring配置中后因为两个配置文件中都有name属性,但其值不相同,这个时候如果通过@Value("${name}")取值会取到zhangsan还是lisi呢,答案是在上述PropertySource列表中靠前的会优先生效。

        如果想让外部的配置文件优先则可以使用addFirst方法添加propertySourcjavascripte。

        提到配置文件的优先级就想起了springboot默认读取配置文件的优先级,参考下方说明:

        优先级依次递减

        • 1.在执行命令的目录下建config文件夹,然后把配置文件放到这个文件夹下。(在jar包的同一个目录下建config文件夹,执行命令需要在jar包所在目录下才行)
        • 2.直接把配置文件放到jar包的同级目录
        • 3.在classpath下建一个config文件夹,然后把配置文件放进去。
        • 4.在classpath下直接放配置文件。

        5.使用的监听器以及加载的时机(监听的事件)

        无论使用那种监听器的实现类型,都需要拿到ConfigurableEnvironment这个参数,可以在多个时机加载配置文件,例如environmentPrepared,contextPrepared,下面展示三种方式实现

        方法一:

        public class MyApplicationContextInitializer implements ApplicationContextInitializer {
        
            @Override
            public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
                YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
                try {
                    PropertySource<?> propertySource = loader.load("externalConfiguration", new InputStreamResource(Files.newInputStream(Paths.get("C:\\Users\\fkp12\\Desktop\\application.yml")))).get(0);
                    configurableApplicationContext.getEnvironment().getPropertySources().addFirst(propertySource);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        需要将该类的全限定名配置到spvYxzQAXXmEring.factories中

        org.springframework.context.ApplicationContextInitializer=com.fkp.springboot_listener.listener.MyApplicationContextInitializer

        方法二:

        public class MySpringApplicationRunListener implements SpringApplicationRunListener {
        
            private final SpringApplication springApplication;
        
            private final String[] args;
        
            public MySpringApplicationRunListener(SpringApplication springApplication, String[] args) {
                this.springApplication = springApplication;
                this.args = args;
            }
        
            @Override
            public void starting(ConfigurableBootstrapContext bootstrapContext) {
                System.out.println("SpringApplicationRunListener....starting");
            }
        
            @Override
            public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
                YamlPropertySourceLoader loader = new YamlPropertySourceLoader(android);
                try {
                    PropertySource<?> propertySource = loader.load("externalConfiguration", new InputStreamResource(Files.newInputStream(Paths.get("C:\\Users\\fkp12\\Desktop\\application.yml")))).get(0);
                    environment.getPropertySources().addFirst(propertySource);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        
            @Override
            public void contextPrepared(ConfigurableApplicationContext context) {
                System.out.println("SpringApplicationRunListener....contextPrepared");
            }
        
            @Override
            public void contextLoaded(ConfigurableApplicationContext context) {
                System.out.println("SpringApplicationRunListener....contextLoaded");
            }
        
            @Override
            public void started(ConfigurableApplicationContext context) {
                System.out.println("SpringApplicationRunListener....started");
            }
        
            @Override
            public void running(ConfigurableApplicationContext context) {
                System.out.println("SpringApplicationRunListener....running");
            }
        
            @Override
            public void failed(ConfigurableApplicationContext context, Throwable exception) {
                System.out.println("SpringApplicationRunListener....failed");
            }
        }
        

        需要将该类的全限定名配置到spring.factories中

        org.springframework.boot.SpringApplicationRunListener=com.fkp.springboot_listener.listener.MySpringApplicationRunListener

        方法三:

        public class MyApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
            @Override
            public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) {
                YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
                try {
                    PropertySource<?> propertySource = loader.load("externalConfiguration", new InputStreamResource(Files.newInputStream(Paths.get("C:\\Users\\fkp12\\Desktop\\application.yml")))).get(0);
                    applicationEnvironmentPreparedEvent.getEnvironment().getPropwww.devze.comertySources().addFirst(propertySource);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        需要将该类的全限定名配置到spring.factories中

        org.springframework.context.ApplicationListener=com.fkp.springboot_listener.listener.MyApplicationListener

        备注:通过Environment取Spring配置中的值

        Environment或实现该接口的类可以通过多种方式获取,例如上述ApplicationEnvironmentPreparedEvent#getEnvironment()获取ConfigurableEnvironment

        通用的一种方法是通过ApplicationContext获取,ApplicationContext#getEnvironment(),ApplicationContext可以从Spring容器中取。

        通过Environment的getProperty方法可以取Spring配置中属性的值。

        总结

        以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

        0

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        关注公众号