添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

聊一聊springboot项目配置参数的三个来源

大家好,我是G探险者,今天我们聊一聊,springboot的参数的三个来源。 平时我们部署项目后,难免都会进行一下配置修改,有的是在修改环境变量,有的是直接通过命令行参数进行修改,有的是直接改,配置文件,那么这三种不同来源的参数修改,都是如何生效的,以及他们之间的一些区别是啥样的,下面我就写问题聊一聊。

1. 配置参数的三个来源

当配置一个应用程序时,可以从多个来源获取配置参数。下面是三个常见的配置参数来源:

命令行参数: 命令行参数是在启动应用程序时通过命令行传递的参数。这些参数可以用来修改应用程序的行为或配置。在Java中,可以使用 main() 方法中的 args 参数来接收命令行参数。例如,以下命令行启动应用程序并传递参数:

java MyApp --param1=value1 --param2=value2

在这个例子中,--param1=value1--param2=value2就是命令行参数。应用程序可以通过解析命令行参数来获取这些值,并根据需要进行配置。

环境变量: 环境变量是在操作系统级别设置的全局变量。它们包含有关操作系统和正在运行的应用程序的信息。应用程序可以读取环境变量以获取配置参数。在大多数操作系统中,可以使用特定的命令来设置和获取环境变量。例如,在Linux和Mac上,可以使用export命令设置环境变量,如下所示:

export MY_VAR=value

应用程序可以通过读取MY_VAR环境变量来获取值。

Spring Boot自带的配置文件(application.propertiesapplication.yml): Spring Boot是一个用于构建Java应用程序的框架,提供了许多便捷的配置方式。其中一种方式是使用application.propertiesapplication.yml配置文件来定义应用程序的属性。这些文件通常位于应用程序的类路径下,可以包含键值对或层级结构的配置。应用程序在启动时会读取这些文件,并将其中定义的配置参数应用到应用程序中。例如,以下是一个application.properties文件的示例:

server.port=8080
database.url=jdbc:mysql://localhost:3306/mydb

在这个例子中,server.portdatabase.url是配置参数的键,8080jdbc:mysql://localhost:3306/mydb是对应的值。Spring Boot应用程序将读取这些值,并相应地配置嵌入式服务器的端口和数据库连接。

这些来源可以单独或组合使用,以提供应用程序的配置参数。在实际开发中,可以根据需要选择最适合的配置方式。例如,命令行参数适合临时修改配置,环境变量适合在不同环境中设置不同的配置,而配置文件则适合将配置集中管理并与代码一起打包部署。

2. 不通来源的参数配置区别

我们先通过以下这个表格直观的看一下,三种不同来源(命令行参数、环境变量和Spring Boot自带的配置文件)有以下区别:

来源用途和灵活性优先级和覆盖可读性和管理
命令行参数临时调整配置,特定操作最高优先级,覆盖其他来源易于理解和管理,但参数较多时可能冗长
环境变量在不同环境中设置不同配置高于配置文件,低于命令行参数需要操作系统级别的设置和管理
Spring Boot自带的配置文件长期配置,集中管理低于命令行参数和环境变量可读性高,易于维护和理解

请注意,以上表格提供了一般性的对比,并且在特定情况下可能会有例外或变化。对于每个项目和场景,最佳选择可能会有所不同,取决于特定的要求和偏好。

用途和灵活性:

  • 命令行参数:命令行参数通常用于在每次启动应用程序时提供临时的、特定于该次运行的配置。这些参数可以根据需要进行更改,因此在不同的运行实例中可以使用不同的参数。命令行参数对于临时调整配置或执行特定操作非常有用。但是,它们不适合长期或全局配置。
  • 环境变量:环境变量是在操作系统级别设置的全局变量。它们可以在不同的应用程序和进程之间共享,并且可以用于配置各种应用程序。环境变量通常用于在不同的环境(例如开发、测试、生产)之间设置不同的配置。它们提供了一种灵活且易于配置的方式,可以根据不同的部署环境进行调整。
  • Spring Boot自带的配置文件:Spring Boot的配置文件提供了一种在应用程序内部集中管理配置的方法。配置文件可以包含多个属性,并且支持层级结构。这种方式适合于将配置与代码分离,以便更好地组织和维护配置。配置文件通常与应用程序一起打包,并在应用程序启动时被读取和应用。它们适用于长期配置,不容易在每次运行时进行更改。
  • 优先级和覆盖:

  • 命令行参数:命令行参数通常具有最高优先级。如果在命令行参数中指定了某个配置,它将覆盖其他来源中的相同配置。这使得可以通过命令行参数临时覆盖应用程序的默认配置。
  • 环境变量:环境变量的优先级通常高于Spring Boot的配置文件。如果在环境变量中设置了某个配置,它将覆盖配置文件中的相同配置。这允许在不修改配置文件的情况下,通过设置环境变量来更改应用程序的配置。
  • Spring Boot自带的配置文件:配置文件中的配置参数提供了默认值,但可以通过命令行参数或环境变量进行覆盖。如果在配置文件中定义了某个配置,但在命令行参数或环境变量中也有相同的配置,后者将覆盖前者。
  • 可读性和管理:

  • 命令行参数:命令行参数是直接在启动命令中指定的,因此它们在启动命令中是可见的。这使得命令行参数易于理解和管理,因为可以清楚地看到应用程序在启动时使用了哪些参数。然而,当需要配置大量参数时,命令行参数可能会变得冗长和难以管理。
  • 环境变量:环境变量是在操作系统级别设置的,可以在操作系统中进行管理。这使得环境变量的设置和管理相对容易,可以在不同的部署环境中轻松配置和更改变量。然而,环境变量的设置和值不直接与应用程序相关联,因此在应用程序代码中可能需要额外的逻辑来读取和处理这些变量。
  • Spring Boot自带的配置文件:Spring Boot的配置文件可以集中管理应用程序的配置,并具有良好的可读性和可维护性。配置文件使用键值对或层级结构的方式组织配置参数,使得它们更易于理解和管理。此外,配置文件可以通过注释和文档来提供参数的说明,进一步提高可读性。配置文件与应用程序代码直接相关,因此在代码中可以直接使用配置参数,无需额外的处理。
  • 总结起来,命令行参数适合临时修改和调试配置,环境变量适合在不同环境中设置不同的配置,而Spring Boot自带的配置文件适合集中管理和维护应用程序的配置。 它们各自具有不同的优点和适用场景,可以根据具体需求选择最合适的配置方式。

    3. 不同来源的参数是如何被springboot识别并解析的?

    在Spring Boot中,配置参数的识别和解析是通过Spring Boot的配置处理机制完成的。这个机制可以自动识别并解析来自命令行参数、环境变量和配置文件的配置参数。以下是对每种来源的配置参数在Spring Boot中的处理方式:

    命令行参数:

    Spring Boot使用org.springframework.boot.ApplicationArguments接口来处理命令行参数。可以通过在Spring Bean中注入ApplicationArguments来访问命令行参数。

    可以使用getOptionValues(String name)方法获取指定名称的选项值,其中name是命令行参数的名称。

    例如,假设有一个命令行参数--param1=value1,可以使用以下方式在Spring Bean中获取该参数的值:

    @Autowired
    private ApplicationArguments applicationArguments;
    public void someMethod() {
        List<String> param1Values = applicationArguments.getOptionValues("param1");
        // 使用param1Values进行后续处理
    

    Spring Boot使用org.springframework.core.env.Environment接口来处理环境变量。可以通过在Spring Bean中注入Environment来访问环境变量。

    可以使用getProperty(String key)方法获取指定键的环境变量值,其中key是环境变量的键。

    例如,假设有一个环境变量MY_VAR=value,可以使用以下方式在Spring Bean中获取该环境变量的值:

    @Autowired
    private Environment environment;
    public void someMethod() {
        String myVarValue = environment.getProperty("MY_VAR");
        // 使用myVarValue进行后续处理
    

    Spring Boot使用org.springframework.boot.context.properties.ConfigurationProperties注解来绑定配置文件中的属性到Java对象上。可以通过在Spring Bean上使用@ConfigurationProperties注解来实现属性绑定。

    配置文件中的属性会自动与带有相同名称的Java对象的属性进行绑定。

    例如,假设有一个配置文件中的属性server.port=8080,可以使用以下方式在Spring Bean中绑定该属性:

    @Component
    @ConfigurationProperties(prefix = "server")
    public class ServerProperties {
        private int port;
        public int getPort() {
            return port;
        public void setPort(int port) {
            this.port = port;
    

    在上述示例中,server.port属性会自动绑定到ServerProperties对象的port属性上。可以通过注入ServerProperties Bean 来访问该属性的值。

    通过上述方式,Spring Boot能够自动识别并解析来自命令行参数、环境变量和配置文件的配置参数,使开发者可以方便地使用这些配置参数来配置应用程序的行为。

    了解了三种不同来源的参数是如何被解析的,感兴趣的可以读一下源码,观察一下他们是如何解析的,这里我就不分析源码了。

    4. springboot里面集成的第三方组件,他们的配置参数如何被管理的?

    现在,很多开源组件库都基本集成到springboot里了,也就是按照springboot的starter规范做了一些自动化配置,并抽离出自身的一些配合参数到application.properties里面。

    有一些组件有他们特有的配置,可能是考虑到配置在application.properties配置文件里面显的太过于冗长,不容易维护,所以需要独立出一个单独的配置文件来管理。

    比如mybatis,log4j2等等这些组件。

    mybatis的独立配置文件:

    mybatis有一个设置文件,一般都是叫做,xxx-config.xml,内容基本如下:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 设置全局属性 -->
        <settings>
            <!-- 开启驼峰命名自动映射 -->
            <setting name="mapUnderscoreToCamelCase" value="true"/>
            <!-- 其他配置项 -->
        </settings>
        <!-- 配置插件 -->
        <plugins>
            <!-- 自定义插件1 -->
            <plugin interceptor="com.example.MyPlugin1">
                <!-- 自定义插件1的配置项 -->
            </plugin>
            <!-- 自定义插件2 -->
            <plugin interceptor="com.example.MyPlugin2">
                <!-- 自定义插件2的配置项 -->
            </plugin>
            <!-- 其他插件 -->
        </plugins>
        <!-- 加载映射文件 -->
        <mappers>
            <!-- 单个映射文件的配置 -->
            <mapper resource="com/example/mapper/SomeMapper.xml"/>
            <!-- 批量加载映射文件的配置 -->
            <package name="com.example.mapper"/>
        </mappers>
    </configuration>
    

    这是一个简单的示例,展示了 MyBatis 的配置文件结构。你可以根据自己的需求进行配置。其中包含了以下几个重要的元素和属性:

  • <settings>:用于配置全局属性和设置,例如开启驼峰命名自动映射。
  • <plugins>: 中配置自定义插件。每个插件都使用 标签表示,其中的 interceptor 属性指定了插件的实现类的完全限定名。
  • <mappers>:用于加载映射文件的配置,可以单个配置或者批量配置。
  • <mapper resource="com/example/mapper/SomeMapper.xml"/>:指定单个映射文件的路径。
  • <package name="com.example.mapper"/>:指定一个包名,MyBatis 会自动扫描该包下的映射文件。
  • log4j2的独立配置文件

    以下是一个Log4j2 配置文件示例:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN" monitorInterval="30">
        <Properties>
            <Property name="logDir">logs</Property>
        </Properties>
        <Appenders>
            <Console name="Console" target="SYSTEM_OUT">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
            </Console>
            <RollingFile name="File" fileName="${logDir}/application.log"
                         filePattern="${logDir}/application-%d{yyyy-MM-dd}.log">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
                <Policies>
                    <TimeBasedTriggeringPolicy interval="1" modulate="true" />
                </Policies>
                <DefaultRolloverStrategy max="10" />
            </RollingFile>
        </Appenders>
        <Loggers>
            <Root level="info">
                <AppenderRef ref="Console" />
                <AppenderRef ref="File" />
            </Root>
            <Logger name="com.example" level="debug" additivity="false">
                <AppenderRef ref="File" />
            </Logger>
        </Loggers>
    </Configuration>
    

    在这个示例中,添加了一些新的配置选项,你可以根据实际需求,调整日志级别、输出格式、文件路径等配置项:

  • <Properties>:在此部分可以定义属性,供后面引用。示例中定义了 logDir 属性,用于指定日志文件目录。
  • monitorInterval:配置文件的监视间隔,单位为秒。如果监视间隔内的配置文件更改,Log4j2 将重新配置自己。在示例中设置为 30 秒。
  • RollingFile Appender:使用滚动文件策略,可以按时间滚动日志文件。示例中的文件名为 application.log,并使用 %d{yyyy-MM-dd} 进行日期格式化。
  • <Policies>:用于配置日志文件滚动策略,示例中使用 TimeBasedTriggeringPolicy,每天滚动一次日志文件。
  • <DefaultRolloverStrategy>:配置日志文件滚动的策略,默认为最多保留 10 个日志文件。
  • 以上尽管这些组件都有独立配置文件,但是,这些独立配置文件依然和springboot的application.properties有关联。

    比如mybatis,在application.properties指定独立配置的加载路径:

    mybatis-plus.config-location=classpath:xxx-config.xml
    

    比如log4j2:

    logging.config=classpath:log.xml
    

    所以,如果我们在开发一个组件集成到springboot里面的时候,尽可能的遵循它的规范,用application.properties来管理你的配置,如果你的配置比较多且比较杂,比如像mybatis,log4j2这样的组件,有自己独立的配置,尽量将这些独立配置文件也和application.properties建立着关联。

    以上,我一直在强调要和application.properties建立关联是因为,后期我们的项目比如进行容器化部署,这些配置那面要修改,那就方便多了。

    具体可以参照我的这篇文章 : Docker和Kubernetes部署Spring Boot项目:如何灵活修改配置文件?

    全部评论
    国泰君安
    校招火热招聘中
    官网直投

    相关推荐

    点赞 评论 收藏
    分享
    点赞 评论 收藏
    分享
    点赞 收藏 评论
    分享

    全站热榜

    正在热议
    # 牛客帮帮团来啦!有问必答 #
    1349972次浏览 18859人参与
    # 非技术岗薪资爆料 #
    55030次浏览 737人参与
    # 不去互联网可以去金融科技 #
    48663次浏览 508人参与
    # 和牛牛一起刷题打卡 #
    48189次浏览 3724人参与
    # 产品每日一题 #
    3002次浏览 144人参与
    # 互联网公司评价 #
    107726次浏览 1389人参与
    # 极具前瞻性,现代汽车编程题 #
    10973次浏览 212人参与
    # 晒一晒我的offer #
    4056083次浏览 60571人参与
    # 你会选择考研还是直接就业 #
    91239次浏览 1066人参与
    # 来聊聊你目前的求职进展 #
    231991次浏览 2935人参与
    # 春招你拿到offer了吗 #
    421743次浏览 5967人参与
    # 硬件兄弟们 甩出你的华为奖状 #
    38719次浏览 227人参与
    # 现在还是0offer,延毕还是备考 #
    433771次浏览 4982人参与
    # 如果可以选,你最想去哪家公司 #
    564105次浏览 9404人参与
    # 写简历别走弯路 #
    362634次浏览 4576人参与
    # 运营人的第一份offer应该如何选 #
    42081次浏览 696人参与
    # 软件开发2024笔面经 #
    1577230次浏览 36138人参与
    # 24届软开秋招面试经验大赏 #
    1247889次浏览 18732人参与
    # 华子oc时间线 #
    12111次浏览 61人参与
    # 机械制造笔面经 #
    17598次浏览 428人参与
    # 如果可以选,你最想从事什么工作 #
    222733次浏览 3425人参与
    # 参加过提前批的机械人,你们还参加秋招么 #
    17250次浏览 386人参与