SpringBoot配置加载顺序和SpringBoot分离打包:将jar包与lib依赖、配置文件分开

文章目录


一、SpringBoot配置加载顺序

  • 官方文档
  • SpringBoot 允许在代码之外,提供应用程序运行的数据,以便在不同的环境中使用相同的应用程序代码。避免硬编码,提供系统的灵活性。可使用各种外部配置源,包括 配置文件环境变量命令行参数

1.SpringBoot配置优先级

  • 以下是常用的Spring Boot 配置形式及其加载顺序(优先级由高到低):
    • ① 命令行参数
    • ② 来自 java.comp/envJNDI 属性
    • ③ Java 系统属性(System.getProperties()
    • ④ 操作系统环境变量
    • RandomValuePropertySource 配置的 random.* 属性值
    • ⑥ 配置文件(YAML文件、Properties 文件)
    • @Configuration 注解类上的 @PropertySource 指定的配置文件
    • ⑧ 通过SpringApplication.setDefaultProperties 指定的默认属性
  • 以上所有形式的配置都会被加载,当存在相同配置内容时,高优先级的配置会覆盖低优先级的配置;存在不同的配置内容时,高优先级和低优先级的配置内容取并集,共同生效,形成互补配置。

(1)命令行参数

  • Spring Boot 中的所有配置,都可以通过命令行参数进行指定,其配置形式如下。
bash 复制代码
java -jar {Jar文件名} --{参数1}={参数值1} --{参数2}={参数值2}
例如:java -jar olive-0.1.jar --server.port=8800 --server.servlet.context-path=/olive

(2)配置文件

  • Spring Boot 启动时,会自动加载 JAR 包内部及 JAR 包所在目录指定位置的配置文件(Properties 文件、YAML 文件),下图中展示了 Spring Boot 自动加载的配置文件的位置及其加载顺序,同一位置下,Properties 文件优先级高于 YAML 文件。
  • springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
    • ① Jar包外同级目录的config目录
    • ② Jar包外同级目录
    • ③ jar包内classPath(即resources目录)的config目录
    • ④ jar包内的classpath目录
  • 配置文件的优先级顺序,遵循以下规则:
    • ① 先加载 JAR 包外的配置文件,再加载 JAR 包内的配置文件;
    • ② 先加载 config 目录内的配置文件,再加载 config 目录外的配置文件;
    • ③ 先加载 config 子目录下的配置文件,再加载 config 目录下的配置文件
    • ④ 先加载 appliction-{profile}.properties/yml,再加载application.properties/yml;
    • ⑤ 先加载 .properties 文件,再加载 .yml 文件。

二、SpringBoot分离打包:将jar包与lib依赖、配置文件分开

  • 之前一直使用SpringBoot初始化建立项目默认的spring-boot-maven-plugin插件,进行项目打包,这个插件会将项目所有的依赖打入BOOT-INF/lib下,这就导致了jar包的体积非常臃肿,尤其涉及到几十个子项目时,整个项目的体积可想而知。但是,各项目之间有非常多的公共依赖,因此,分离打包还是比较有意义的。

1.pom文件配置

  • properties标签中定义依赖的输出目录、jar包的输出目录、resources中配置文件的输出目录。

    xml 复制代码
    <properties>
        <!--依赖输出目录-->
        <output.dependence.file.path>lib/</output.dependence.file.path>
        <!--jar输出目录-->
        <output.jar.file.path>bin/</output.jar.file.path>
        <!--配置文件输出目录-->
        <output.resource.file.path>/</output.resource.file.path>
        <!--配置项目输出目录-->
        <env.LEARN_HOME>olive</env.LEARN_HOME>
    </properties>
  • build标签:plugins标签中一共包含三个插件:maven-jar-plugin、maven-dependency-plugin和maven-resources-plugin。

    xml 复制代码
    <build>
    	<plugins>
            <!-- 打JAR包,不包含依赖文件;显式剔除配置文件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <!--${env.LEARN_HOME}为项目配置的环境变量,下同-->
                    <outputDirectory>${env.LEARN_HOME}/${output.jar.file.path}</outputDirectory>
                    <!-- 将配置文件排除在jar包 -->
                    <excludes>
                        <exclude>**/*.properties</exclude>
                        <exclude>**/*.yml</exclude>
                        <exclude>**/*.xml</exclude>
                        <exclude>**/*.txt</exclude>
                    </excludes>
                    <archive>
                        <!-- 生成的jar中,包含pom.xml和pom.properties这两个文件 -->
                        <addMavenDescriptor>true</addMavenDescriptor>
                        <!-- 生成MANIFEST.MF的设置 -->
                        <manifest>
                            <!--这个属性特别关键,如果没有这个属性,有时候我们引用的包maven库 下面可能会有多个包,并且只有一个是正确的,
                            其余的可能是带时间戳的,此时会在classpath下面把那个带时间戳的给添加上去,然后我们在依赖打包的时候,
                            打的是正确的,所以两头会对不上,报错。 -->
                            <useUniqueVersions>false</useUniqueVersions>
                            <!-- 为依赖包添加路径, 这些路径会写在MANIFEST文件的Class-Path下 -->
                            <addClasspath>true</addClasspath>
                            <!-- MANIFEST.MF 中 Class-Path 各个依赖加入前缀 -->
                            <!--这个jar所依赖的jar包添加classPath的时候的前缀,需要 下面maven-dependency-plugin插件补充-->
                            <!--一定要找对目录,否则jar找不到依赖lib,前边加../是因为jar在bin下,而bin与lib是平级目录-->
                            <classpathPrefix>../${output.dependence.file.path}</classpathPrefix>
                            <!--指定jar启动入口类 -->
                            <mainClass>com.gdb.main.MainApplication</mainClass>
                        </manifest>
                        <manifestEntries>
                            <!-- 假如这个项目可能要引入一些外部资源,但是你打包的时候并不想把 这些资源文件打进包里面,这个时候你必须在
                            这边额外指定一些这些资源文件的路径,假如你的pom文件里面配置了 <scope>system</scope>,就是你依赖是你本地的
                            资源,这个时候使用这个插件,classPath里面是不会添加,所以你得手动把这个依赖添加进这个地方 -->
                            <!--MANIFEST.MF 中 Class-Path 加入自定义路径,多个路径用空格隔开 -->
                            <!--此处resources文件夹的内容,需要maven-resources-plugin插件补充上-->
                            <Class-Path>../${output.resource.file.path}</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
    
            <!-- 复制依赖的jar包到指定的文件夹里 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <!-- 拷贝项目依赖包到指定目录下 -->
                            <outputDirectory>${env.LEARN_HOME}/${output.dependence.file.path}</outputDirectory>
                            <!-- 是否排除间接依赖,间接依赖也要拷贝 -->
                            <excludeTransitive>false</excludeTransitive>
                            <!-- 是否带上版本号 -->
                            <stripVersion>false</stripVersion>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!-- 用于复制指定的文件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <!-- 复制配置文件 -->
                    <execution>
                        <id>copy-resources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <resources>
                                <resource>
                                    <directory>src/main/resources</directory>
                                    <includes>
                                        <!--将如下格式配置文件拷贝-->
                                        <!-- 将resouces包下的所有文件 -->
                                        <exclude>**/*.*</exclude>
                                    </includes>
                                </resource>
                            </resources>
                            <!--输出路径-->
                            <outputDirectory>${env.LEARN_HOME}/${output.resource.file.path}</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
  • 在上面的配置中会看到有.../这种相对路径的配置,这是为了让程序能够找到它依赖的lib和配置文件。即一切从最终的jar包出发,考虑如何让它能够找到它所依赖的lib和配置文件即可。

  • 注意:maven-jar-plugin插件中启动类的位置需要根据自己的项目设置。

2.打包后的目录结构


相关推荐
Minyy112 小时前
SpringBoot程序的创建以及特点,配置文件,LogBack记录日志,配置过滤器、拦截器、全局异常
xml·java·spring boot·后端·spring·mybatis·logback
武昌库里写JAVA3 小时前
39.剖析无处不在的数据结构
java·vue.js·spring boot·课程设计·宠物管理
画个大饼4 小时前
Go语言实战:快速搭建完整的用户认证系统
开发语言·后端·golang
李白的粉8 小时前
基于springboot的在线教育系统
java·spring boot·毕业设计·课程设计·在线教育系统·源代码
小马爱打代码9 小时前
SpringBoot原生实现分布式MapReduce计算
spring boot·分布式·mapreduce
iuyou️9 小时前
Spring Boot知识点详解
java·spring boot·后端
一弓虽9 小时前
SpringBoot 学习
java·spring boot·后端·学习
姑苏洛言10 小时前
扫码小程序实现仓库进销存管理中遇到的问题 setStorageSync 存储大小限制错误解决方案
前端·后端
光而不耀@lgy10 小时前
C++初登门槛
linux·开发语言·网络·c++·后端
方圆想当图灵10 小时前
由 Mybatis 源码畅谈软件设计(七):SQL “染色” 拦截器实战
后端·mybatis·代码规范