关键词: spring-boot 依赖管理, spring-boot-dependencies,spring-boot-parent
问题
maven 工程, 依赖管理是非常基本又非常重要的功能, 现在的工程越来越庞大, 依赖越来越多, 各种二方包, 三方包太多太多, 依赖冲突处理起来真是让人头疼, 经常需要涉及到多个地方需要调整.
微信公众号: 逸飞兮(专注于 java 知识领域的源码分析, 从源码中理解框架 / 工具原理, 验证 CS 专业知识)
解决方案
使用统一的依赖管理模块来管理工程中的所有依赖.
spring-boot 工程常使用 spring-boot-dependencies,spring-boot-starter-parent 管理工程依赖.
spring-boot 的最上级工程是 spring-boot-build, 以下开始一步一步深入了解 spring-boot 依赖解决方案.
spring-boot 中的方案
spring-boot-build
spring-boot 的最上层工程, 指定了 maven profiles,maven repositories,maven pluginRepositories,maven build pluginManagement.
profiles: 中包含代码风格检查, 代码风格 format; 更方便导入 eclipse;maven 仓库
repositories: 允许在开发过程中导入快照和里程碑 BOM. 这个部分在 install/deploy 期间被 flatten 插件删除. 包含 maven 中央仓库, spring 快照仓库, spring 里程碑仓库
pluginRepositories: 插件仓库, 包含 maven 中央仓库, spring 快照仓库, spring 里程碑仓库
pluginManagement: 构建插件管理, 这个插件的配置只用于存储 Eclipse m2e 设置, 它对 Maven 构建本身没有影响.
spring-boot-dependencies
dependencies 的父工程是 spring-boot-build, 不包含代码, 只用 pom 来管理依赖, pom.xml 如下:
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-build</artifactId>
- <version>${revision}</version>
- <relativePath>../..</relativePath>
- </parent>
- <artifactId>spring-boot-dependencies</artifactId>
- <packaging>pom</packaging>
- <dependencyManagement>
- <!-- 省略具体依赖管理 -->
- </dependencyManagement>
- <build>
- <pluginManagement>
- <!-- 省略具体构建插件管理 -->
- </pluginManagement>
- <plugins>
- <!-- 省略具体构建插件 -->
- </plugins>
- </build>
从 pom 中可以看出, spring-boot-dependencies 中除了引入了 (3 个) 插件, 更多的是做版本的管理.
其中, 引入的插件是:
flatten-maven-plugin: 对 pom 精简插件
xml-maven-plugin:1. 根据 schema 验证 xml 文件; 2. 使用 XSLT 样式转换 xml 文件
build-helper-maven-plugin: 指定多个源码目录
dependencyManagement 中差不多管理了 spring-boot 工程中所有的依赖.
pluginManagement 中管理了常用的各种 maven 插件, 这里就不详述了.
其中包含了 maven-clean-plugin,maven-compiler-plugin,maven-assembly-plugin,maven-war-plugin,maven-jar-plugin,spring-boot-maven-plugin, 其中 spring-boot-maven-plugin 插件对于 spring-boot 工程非常重要, 会把 maven 打包成的 jar 重新打包成可执行 jar.
spring-boot-starter-parent(重要)
既然有了 spring-boot-dependencies 这么丰富的依赖, 插件版本管理, 那么还搞一个 spring-boot-starter-parent 呢?
spring-boot-starter-parent 的父工程是 spring-boot-dependencies, 不包含代码, 只用 pom 来管理依赖, pom.xml 如下:
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-dependencies</artifactId>
- <version>${revision}</version>
- <relativePath>../../spring-boot-dependencies</relativePath>
- </parent>
- <artifactId>spring-boot-starter-parent</artifactId>
- <packaging>pom</packaging>
- <name>Spring Boot Starter Parent</name>
- <description>Parent pom providing dependency and plugin management for applications
- built with Maven</description>
- <properties>
- <main.basedir>${basedir}/../../..</main.basedir>
- <java.version>1.8</java.version>
- <!-- 资源分隔符 -->
- <resource.delimiter>@</resource.delimiter> <!-- delimiter that doesn't clash with Spring ${} placeholders -->
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <maven.compiler.source>${java.version}</maven.compiler.source>
- <maven.compiler.target>${java.version}</maven.compiler.target>
- </properties>
- <build>
- <resources>
- <resource>
- <directory>${basedir}/src/main/resources</directory>
- <filtering>true</filtering>
- <includes>
- <include>**/application*.YAML</include>
- <include>**/application*.YAML</include>
- <include>**/application*.properties</include>
- </includes>
- </resource>
- <resource>
- <directory>${basedir}/src/main/resources</directory>
- <excludes>
- <exclude>**/application*.YAML</exclude>
- <exclude>**/application*.YAML</exclude>
- <exclude>**/application*.properties</exclude>
- </excludes>
- </resource>
- </resources>
- <pluginManagement>
- <plugins>
- <!-- 省略其它不用太关心的 plugin -->
- <!-- spring-boot 提供的 maven 重打包插件, 重要!!! -->
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>repackage</id>
- <goals>
- <goal>repackage</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <mainClass>${start-class}</mainClass>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- <plugins>
- <!-- 引入公共插件: flatten-maven-plugin,xml-maven-plugin -->
- </plugins>
特性
默认编译版本: Java 1.8
源码编码: UTF-8
继承自 spring-boot-dependencies 的 dependencyManagement
spring-boot-maven-plugin 的 goal 设置为 repackage
maven 资源过滤(application*.YAML,application*.YAML,application*.properties 等), 插件配置
资源分隔符:"@", 在 application*.YAML 中使用 @来引用 maven 属性, 常见用法如下: spring.application.name=@artifactId@
Note that, since the application.properties and application.YAML files accept Spring style placeholders (${...}), the Maven filtering is changed to use @..@placeholders. (You can override that by setting a Maven property called resource.delimiter.)
译:
注意, 由于 application.properties 和 application.YAML 文件接受 spring 样式的占位符($...), 所以 maven filter 将更改为使用 @...@占位符.(可以通过设置名为 resource.delimiter 的 maven 属性来覆盖该属性.)
- spring-boot-parent
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-dependencies</artifactId>
- <version>${revision}</version>
- <relativePath>../spring-boot-dependencies</relativePath>
- </parent>
- <artifactId>spring-boot-parent</artifactId>
- <packaging>pom</packaging>
- <dependencyManagement>
- <!-- 省略具体依赖管理 -->
- </dependencyManagement>
- <dependencies>
- <!-- 省略具体依赖 -->
- </dependencies>
- <build>
- <pluginManagement>
- <!-- 省略具体构建插件管理 -->
- </pluginManagement>
- <plugins>
- <!-- 省略具体构建插件 -->
- </plugins>
- <profiles>
- <!-- 省略具体 profile -->
- </profiles>
- </build>
- dependencyManagement
包含两个部分:
内部未发布的 spring-boot 依赖
附加的 Spring 引导依赖项 (对用户无效)
因此, 这里所加入的依赖管理, 用户不需要关心, 很好, 省心.
dependencies
公共的依赖, 主要是一些测试依赖, 如: junit,hamcrest,mockito,spring-test, 还有断言依赖: assertj.
plugins
添加了 spring-boot 公用的一些插件, 如: maven-compiler-plugin,maven-jar-plugin,maven-war-plugin,maven-source-plugin 等
profiles
用户基本不用关心. 省略
选择
spring-boot-dependencies 和 spring-boot-starter-parent, spring-boot-parent 都提供了依赖管理的功能, 那我们在开发的过程中, 到底使用哪个呢?
spring-boot-parent : 目的不是提供给用户使用的, 使用 spring-boot 开源项目用于管理 spring-boot-project 整个大工程中的除了 spring-boot-starters (提供给我们使用的各个开箱即用的三方包) 的其他模块的.
spring-boot-starter-parent: 我们通过 Spring Initializr 构建一个 spring-boot 项目的时候, 官方默认是让我们使用的 spring-boot-starter-parent , 大致可以认为官方建议使用此方式管理依赖, 毕竟此方式提供的依赖, 插件管理更多, 更适合使用.
spring-boot-dependencies: 若在使用的时候, 工程不想指定父工程, 或者必须使用公司的父工程, 可以通过 dependencyManagement 引入此依赖管理.
使用 spring-boot-dependencies, 相比较 spring-boot-starter-parent 的时候特别注意要加上 spring-boot-maven-plugin, 如下:
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <version>${springboot.version}</version>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
至于 spring-boot-starter-parent 的其他额外指定的 jar, 按需添加.
实际使用
在工程中使用的时候, 所有的二方, 三方 jar 都应该统一管理, 除了 spring-boot 提供的依赖, 我们还有很多 jar 需要管理, 如: MySQL 驱动包, mybatis 包, 各种工具包或者公司内的二方包等. 因此, 最好使用一个单独的模块来构建自己的 dependencies 或 parent.
待续
em...... 写到这里就结束了吗? 似乎还没有, 还需要细致分析下一些具体依赖是如何选择的, 比如: spring-boot 选择的是什么日志框架, logback?log4j2?log4j? 那对于代码中不是用 spring-boot 指定的日志实现时, spring-boot 又是怎么做的呢? 期待后续更新? 更或者不更新, 谁知道呢?
专注于 java 知识领域的源码分析, 从源码中理解框架 / 工具原理, 验证 CS 专业知识的应用
来源: https://www.cnblogs.com/lw5946/p/11444634.html