大家好,我是G探险者,今天我们聊一聊,springboot的参数的三个来源。
平时我们部署项目后,难免都会进行一下配置修改,有的是在修改环境变量,有的是直接通过命令行参数进行修改,有的是直接改,配置文件,那么这三种不同来源的参数修改,都是如何生效的,以及他们之间的一些区别是啥样的,下面我就写问题聊一聊。
当配置一个应用程序时,可以从多个来源获取配置参数。下面是三个常见的配置参数来源:
命令行参数: 命令行参数是在启动应用程序时通过命令行传递的参数。这些参数可以用来修改应用程序的行为或配置。在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.properties
或application.yml
): Spring Boot是一个用于构建Java应用程序的框架,提供了许多便捷的配置方式。其中一种方式是使用application.properties
或application.yml
配置文件来定义应用程序的属性。这些文件通常位于应用程序的类路径下,可以包含键值对或层级结构的配置。应用程序在启动时会读取这些文件,并将其中定义的配置参数应用到应用程序中。例如,以下是一个application.properties
文件的示例:
server.port=8080
database.url=jdbc:mysql://localhost:3306/mydb
在这个例子中,server.port
和database.url
是配置参数的键,8080
和jdbc:mysql://localhost:3306/mydb
是对应的值。Spring Boot应用程序将读取这些值,并相应地配置嵌入式服务器的端口和数据库连接。
这些来源可以单独或组合使用,以提供应用程序的配置参数。在实际开发中,可以根据需要选择最适合的配置方式。例如,命令行参数适合临时修改配置,环境变量适合在不同环境中设置不同的配置,而配置文件则适合将配置集中管理并与代码一起打包部署。
我们先通过以下这个表格直观的看一下,三种不同来源(命令行参数、环境变量和Spring Boot自带的配置文件)有以下区别:
来源 | 用途和灵活性 | 优先级和覆盖 | 可读性和管理 |
---|---|---|---|
命令行参数 | 临时调整配置,特定操作 | 最高优先级,覆盖其他来源 | 易于理解和管理,但参数较多时可能冗长 |
环境变量 | 在不同环境中设置不同配置 | 高于配置文件,低于命令行参数 | 需要操作系统级别的设置和管理 |
Spring Boot自带的配置文件 | 长期配置,集中管理 | 低于命令行参数和环境变量 | 可读性高,易于维护和理解 |
请注意,以上表格提供了一般性的对比,并且在特定情况下可能会有例外或变化。对于每个项目和场景,最佳选择可能会有所不同,取决于特定的要求和偏好。
用途和灵活性:
优先级和覆盖:
可读性和管理:
总结起来,命令行参数适合临时修改和调试配置,环境变量适合在不同环境中设置不同的配置,而Spring Boot自带的配置文件适合集中管理和维护应用程序的配置。
它们各自具有不同的优点和适用场景,可以根据具体需求选择最合适的配置方式。
在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 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自带的配置文件(application.properties
或application.yml
):
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能够自动识别并解析来自命令行参数、环境变量和配置文件的配置参数,使开发者可以方便地使用这些配置参数来配置应用程序的行为。
了解了三种不同来源的参数是如何被解析的,感兴趣的可以读一下源码,观察一下他们是如何解析的,这里我就不分析源码了。
现在,很多开源组件库都基本集成到springboot里了,也就是按照springboot的starter规范做了一些自动化配置,并抽离出自身的一些配合参数到application.properties里面。
有一些组件有他们特有的配置,可能是考虑到配置在application.properties配置文件里面显的太过于冗长,不容易维护,所以需要独立出一个单独的配置文件来管理。
比如mybatis,log4j2等等这些组件。
mybatis有一个设置文件,一般都是叫做,xxx-config.xml,内容基本如下:
这是一个简单的示例,展示了 MyBatis 的配置文件结构。你可以根据自己的需求进行配置。其中包含了以下几个重要的元素和属性:
:用于配置全局属性和设置,例如开启驼峰命名自动映射。
: 中配置自定义插件。每个插件都使用
:用于加载映射文件的配置,可以单个配置或者批量配置。
:指定单个映射文件的路径。
:指定一个包名,MyBatis 会自动扫描该包下的映射文件。以下是一个Log4j2 配置文件示例:
logs
在这个示例中,添加了一些新的配置选项,你可以根据实际需求,调整日志级别、输出格式、文件路径等配置项:
:在此部分可以定义属性,供后面引用。示例中定义了 logDir
属性,用于指定日志文件目录。monitorInterval
:配置文件的监视间隔,单位为秒。如果监视间隔内的配置文件更改,Log4j2 将重新配置自己。在示例中设置为 30 秒。RollingFile
Appender:使用滚动文件策略,可以按时间滚动日志文件。示例中的文件名为 application.log
,并使用 %d{yyyy-MM-dd}
进行日期格式化。
:用于配置日志文件滚动策略,示例中使用 TimeBasedTriggeringPolicy
,每天滚动一次日志文件。
:配置日志文件滚动的策略,默认为最多保留 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项目:如何灵活修改配置文件?_G探险者的博客-CSDN博客