• springboot如何使用自定义配置文件


      从前边《springboot竟然有5种默认的加载路径,你未必都知道》我们知道,springboot会默认加载application.properties/application.yml配置文件,且会从下面5个默认的路径下加载,其优先级依次升高,后面的会覆盖前边的配置。我们平时使用resources/application.properties其实优先级是最低。

    // Note the order is from least to most specific (last one wins)
    private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/";

      既然知道了springboot会从默认的路径加载默认的配置文件application.properties/application.yml,那么必然可以自定义。

    一、如何自定义

      这里分为两部分,一个是自定义配置文件,一个是自定义配置文件的路径。秘密就藏在上篇文章提到的一个类中:ConfigFileApplicationListener,再来看下该类的注释,下面仅贴出部分,

     * <p>
     * The 'spring.config.name' property can be used to specify an alternative name to load
     * and the 'spring.config.location' property can be used to specify alternative search
     * locations or specific files.
     * <p>

    这段注释是什么意思呐,大体意思是“通过指定spring.config.name属性来替代默认的配置文件名称,通过指定spring.config.location属性来替代默认配置文件的加载路径”。再来看ConfigFileApplicationListener类中的属性,

    /**
    * The "config name" property name.
     */
    public static final String CONFIG_NAME_PROPERTY = "spring.config.name";
    
    /**
    * The "config location" property name.
    */
    public static final String CONFIG_LOCATION_PROPERTY = "spring.config.location";

    可以看到在该类中定义了两个常量来接收“spring.config.name”和“spring.config.location”属性的值。 

    二、如何使用

      上面已经了解到可以通过配置“spring.config.name”和“spring.config.location”属性值来自定义默认配置文件和默认配置文件的加载路径。现在就来试试,使用properties文件来演示,在resources文件夹下建myconfig/custom.properties,

    现在,如果启动服务肯定不会使用端口“9099”,因为前边说到springboot有自己的默认加载路径及默认的配置文件名,现在自定义的文件是resources/myconfig/custome.properties,springboot不会加载到,前边又说到springboot定义了“spring.config.name”和“spring.config.location”两个属性,现在就需要使用这两个属性指定自定义的配置文件。

    2.1、从源码中学习如何使用

    要指定如何使用“spring.config.name”和“spring.config.location”两个配置,还是得去源码中寻找,前面说到这两个属性在ConfigFileApplicationListener类中,在该类中在下面的地方使用了这两个属性,

    private Set<String> getSearchNames() {
               //使用CONFIG_NAME_PROPERTY常量也就是spring.config.name
    			if (this.environment.containsProperty(CONFIG_NAME_PROPERTY)) {
    				String property = this.environment.getProperty(CONFIG_NAME_PROPERTY);
    				Set<String> names = asResolvedSet(property, null);
    				names.forEach(this::assertValidConfigName);
    				return names;
    			}
    			return asResolvedSet(ConfigFileApplicationListener.this.names, DEFAULT_NAMES);
    		}
    
    private Set<String> getSearchLocations() {
    			Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY);
                //使用CONFIG_LOCATION_PROPERTY常量也就是spring.config.location
    			if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) {
    				locations.addAll(getSearchLocations(CONFIG_LOCATION_PROPERTY));
    			}
    			else {
    				locations.addAll(
    						asResolvedSet(ConfigFileApplicationListener.this.searchLocations, DEFAULT_SEARCH_LOCATIONS));
    			}
    			return locations;
    		}

    从上面的代码中得出这样一个规律都是调用this.environment 中的方法,那么这个environment到底是什么,如下

    完全看不出来,这时候只有通过debug了,在ConfigFileApplicationListener类中打上断点,看到environment是一个StandardServletEnvironment实例,

    那就好办了,找到该类即可,该类中有这样的一个方法:customizePropertySources,直译过来是“自定义属性来源”,

    @Override
    	protected void customizePropertySources(MutablePropertySources propertySources) {
    		propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
    		propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
    		if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
    			propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));
    		}
    		super.customizePropertySources(propertySources);
    	}

    从该类中可以看到向propertySources中新加了好几个属性,我们看下面这句,

    super.customizePropertySources(propertySources);

    调用的是父类的方法,父类方法如下,

    @Override
    	protected void customizePropertySources(MutablePropertySources propertySources) {
    		propertySources.addLast(
    				new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
    		propertySources.addLast(
    				new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
    	}

    看到又向propertySources中放入了两个值,分别是下面两个常量,

    /** System environment property source name: {@value}. */
    public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";
    
    /** JVM system properties property source name: {@value}. */
    public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";

    根据注释我们知道,

    SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME  表示的是系统环境参数

    SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME  表示的是JVM系统参数

    也就是说springboot会从系统环境变量和JVM参数中读取配置信息,结合前边的分析,“spring.config.name”和“spring.config.location”会从系统环境变量和JVM参数中获取。

    2.2、配置系统环境变量和JVM参数

    前边已经从源码中知道了“spring.config.name”和“spring.location”应该如何配置,现在看下配置效果。

    2.2.1、配置JVM参数

    配置JVM参数看下效果,配置如下,

    -Dspring.config.name=custom
    -Dspring.config.location=classpath:myconfig/

    配置好的效果如下,

    看下服务在哪个端口启动,

    服务在端口“9099”启动,使用到了我们自定义的配置文件:resources/myconfig/custom.properties。

    2.2.2、配置系统环境变量

    配置的信息如下,

    spring.config.name=custom
    spring.config.location=classpath:myconfig/

    配置好的效果,

    测试结果,我就不再贴了,服务使用的我们自定义的配置文件。

    读到这里不知道小伙伴们是否有个疑惑,JVM参数和系统环境变量有优先级吗,当然是有的,咱们继续。

    2.3、优先级之争

    在resources下再建myconfig2/custom.properties文件,端口为9098,

    分别配置JVM参数和系统环境变量,

    最后服务是在端口“9099”启动,

    由此我们可以得出结论,JVM参数的优先级大于系统环境变量

    三、总结

      本文主要分享了在springboot中如何使用自定义的配置文件,主要有以下几点

      1、定义自己的配置文件;

      2、使用“spring.config.name”、“spring.config.location”定义文件名称、文件位置;

      3、可以在JVM参数、系统环境变量配置“spring.config.name”、“spring.config.location”;JVM参数的优先级大于系统环境变量;

    不知道有没有小伙伴还存在一个疑问,我是有疑问的,什么是JVM参数?什么是系统环境变量?后续咱们继续分享。

    推荐阅读

    springboot竟然有5种默认的加载路径,你未必都知道

    5分钟快速搭建一个springboot的项目

    springboot:读取application.yml文件

  • 相关阅读:
    单词统计-续
    “帮你APP”团队冲刺10
    软件工程周总结15
    梦断代码阅读笔记03
    个人课程总结
    梦断代码阅读笔记02
    梦断代码阅读笔记01
    软件工程周总结14
    计算最长英语单词链
    软件工程周总结13
  • 原文地址:https://www.cnblogs.com/teach/p/16322420.html
Copyright © 2020-2023  润新知