Springboot配置加载方式的优先级实验(部分)

前两天面试碰到面试官问Springboot有哪几种加载配置的方式,这些方式的优先级如何排列,一下子把只想到Apollo、bootstrap.properties和命令行参数的我给问闷了,故在此文中整理部分配置加载方法,并设计了验证它们优先级的实验。

官方文档Springboot配置加载方式的优先级实验(部分)https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config

目录

测试代码(总)

命令行参数(Command line arguments)

ServletContext

application.properties

@PropertySources

实验结果


测试代码(总)

配置类:

@Component
@PropertySource("/demo/demo.properties")
@ConfigurationProperties("prioritytest")
public class ConfigProperties {
    private String p1;
    private String p2;
    private String p3;
    private String p4;

    //省略getter setter
}

负责输出结果的Controller类:

@RestController
public class BookController {

    @Autowired
    ConfigProperties configProperties;

    @GetMapping("/testprop")
    public String testProp(){
        String strBuild = configProperties.getP1() +
                " " +
                configProperties.getP2() +
                " " +
                configProperties.getP3() +
                " " +
                configProperties.getP4();
        return strBuild;
    }

}

命令行参数(Command line arguments)

描述:命令行参数

By default, SpringApplication converts any command line option arguments (that is, arguments starting with --, such as --server.port=9000) to a property and adds them to the Spring Environment.

 SpringApplication会将命令行参数转换为property并存入Spring的Environment中。

If you do not want command line properties to be added to the Environment, you can disable them by using SpringApplication.setAddCommandLineProperties(false).

 可通过上述方式阻止Spring将命令行参数加入Environment。


关于Spring Environment,可以参考官方文档

或参考这篇文章

简单来理解的话,把其当作是JDK环境、Servlet环境及Spring环境的整合体。


测试代码:由于笔者的测试项目使用Maven来启动Springboot应用,所以首先参考相关文档确认了参数的写法,其次在IDEA-项目视窗右键-Run Maven- new goal中添加如图中所示的两个Goal,都能够正常使用。

Springboot配置加载方式的优先级实验(部分)

ServletContext

描述:ServletContext的优先级介于命令行参数与application.properties之间,不少博客提到了通过xml文件在ServletContext中添加属性的办法,当然,也有不依赖xml文件的方法。

笔者暂时没有发现ServletContext有什么特别的应用场景...

测试代码:

参考

@Bean
    public ServletContextInitializer servletContextInitializer() {

        return new ServletContextInitializer() {

            @Override
            public void onStartup(ServletContext servletContext) throws ServletException {

                servletContext.setInitParameter("prioritytest.p2",
                        "p2_servlet_context");
                servletContext.setInitParameter("prioritytest.p1",
                        "p1_servlet_context");
            }
        };
    }

application.properties

描述:比较灵活、常见的配置方法。本文仅仅简单地演示了其用法,实际上,application.properties的相关使用技巧包括:支持复合结构的yaml文件,jar包外部的application.properties文件、jar包内部的application.properties文件、以及application-{profile}.properties用法...等等。

测试代码:

在application.properties中写入

prioritytest.p1 = p1_resources_application_properties
prioritytest.p2 = p2_resources_application_properties
prioritytest.p3 = p3_resources_application_properties

@PropertySources

描述:该注解允许某个配置类(@Configuration classes)从指定文件中读取配置信息,其优先级低于上面提及的几种配置方法。

此外,官方文档就该注解将值填入属性的时机进行了解说:

Please note that such property sources are not added to the Environment until the application context is being refreshed. This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.

测试代码:

项目结构图:

Springboot配置加载方式的优先级实验(部分)

代码:

prioritytest.p1 = p1_resources_propertysource
prioritytest.p2 = p2_resources_propertysource
prioritytest.p3 = p3_resources_propertysource
prioritytest.p4 = p4_resources_propertysource

实验结果

符合文档中对于配置优先级的描述。

Springboot配置加载方式的优先级实验(部分)

上一篇:解决接口的数据显示空值,循环出现问题~


下一篇:redis操作