关键词: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 的最上层工程,指定了 maven profiles、maven repositories、maven pluginRepositories、maven build pluginManagement。
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 个)插件,更多的是做版本的管理。
其中,引入的插件是:
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-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*.yml</include> <include>**/application*.yaml</include> <include>**/application*.properties</include> </includes> </resource> <resource> <directory>${basedir}/src/main/resources</directory> <excludes> <exclude>**/application*.yml</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>
Note that, since the application.properties
and application.yml
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.yml 文件接受 spring 样式的占位符($…),所以 maven filter 将更改为使用@…@占位符。(可以通过设置名为 resource.delimiter 的 maven 属性来覆盖该属性。)
<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>
包含两个部分:
因此,这里所加入的依赖管理,用户不需要关心,很好,省心。
公共的依赖,主要是一些 测试 依赖,如:junit、hamcrest、mockito、spring-test,还有断言依赖:assertj。
添加了 spring-boot 公用的一些插件,如:maven-compiler-plugin、maven-jar-plugin、maven-war-plugin、maven-source-plugin 等
用户基本不用关心。省略
spring-boot-dependencies 和 spring-boot-starter-parent、 spring-boot-parent 都提供了依赖管理的功能,那我们在开发的过程中,到底使用哪个呢?
使用 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专业知识的应用