Spring Boot Starter Parent
每次使用Spring Initialize 初始化專案的時候pom.xml 發現都會多一項parent 宣告
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.7</version> <relativePath/> <!-- lookup parent from repository --> </parent>
那spring-boot-starter-parent 到底是幹什麼的呢?
一、 Spring Boot Starter Parent
spring-boot-starter-parent 是一個特殊的starter 專案,它為我們提供了專案預設配置和完整的依賴樹,以便快速建立一個spring boot 專案
同時也為maven 外掛提供了預設配置,如:maven-compiler-plugin, maven-failsafe-plugin, maven-jar-plugin, maven-surefire-plugin, maven-war-plugin
二、 專案功能
spring-boot-starter-parent 提供了以下功能:
-
Java 1.8 作為預設的編譯版本
-
原始碼使用UTF-8 格式編碼
-
繼承自spring-boot-dependencies,這裡管理了常見依賴的版本。可以讓我們在專案的pom.xml中省略這些依賴的
標籤。 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
-
自動化的資源過濾:預設把src/main/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>
-
自動化的外掛管理:預設為maven 外掛提供了預設配置,如:maven-compile-plugin, maven-war-plugin
-
自動對application.properties和application.yml進行資源過濾,包括通過profile 定義的不同環境的配置(如:application-dev.properties和application-dev.yml)
注意:由於application.properties和application.yml檔案接受Spring樣式佔位符 $ {...}
,因此 Maven 過濾更改為使用 @ .. @
佔位符,當然開發者可以通過設定名為 resource.delimiter 的Maven 屬性來覆蓋 @ .. @
佔位符。
三、配置覆蓋
我們可以用properties 標籤來重寫spring-boot-starter-parent 中定義的版本資訊
例如,如果想用Java 11 以及不同版本的SLF4J 可以在pom.xml 中新增以下內容
<properties>
<java.version>11</java.version>
<slf4j.version>1.7.30</slf4j.version>
</properties>
所有的版本依賴列表:Dependency versions Appendix
同樣也可以指定依賴的version 進行版本覆蓋:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
四、不依賴Parent 的專案
如果因為種種原因不能使用spring-boot-starter-parent,但是仍然可以通過自定義dependencyManagement 來獲取spring boot 的依賴樹
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
這樣我們仍然可以像之前一樣,只在dependencies 中宣告依賴,而不要申明version 資訊。但是其他的,比如:打包外掛、編譯的Java 版本、檔案的編碼格式等就需要自己去配置了。
五、原理
在本地倉庫找到spring-boot-starter-parent-2.6.7.pom 檔案,內容大致如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.7</version>
</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>
<java.version>1.8</java.version>
<resource.delimiter>@</resource.delimiter>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<url>https://spring.io/projects/spring-boot</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<developers>
<developer>
<name>Pivotal</name>
<email>[email protected]</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>https://www.spring.io</organizationUrl>
</developer>
</developers>
<scm>
<url>https://github.com/spring-projects/spring-boot</url>
</scm>
<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>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>
...
</plugins>
</pluginManagement>
</build>
</project>
可以看到外掛的配置、資源的宣告以及Java 版本、編碼格式等資訊
spring-boot-starter-parent 同時又繼承自spring-boot-dependencies.pom,spring-boot-dependencies-2.6.7.pom 檔案如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.7</version>
<packaging>pom</packaging>
<name>spring-boot-dependencies</name>
<description>Spring Boot Dependencies</description>
<url>https://spring.io/projects/spring-boot</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<developers>
<developer>
<name>Pivotal</name>
<email>[email protected]</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>https://www.spring.io</organizationUrl>
</developer>
</developers>
<scm>
<url>https://github.com/spring-projects/spring-boot</url>
</scm>
<properties>
<activemq.version>5.16.4</activemq.version>
...
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-amqp</artifactId>
<version>${activemq.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-blueprint</artifactId>
<version>${activemq.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>${activemq.version}</version>
</dependency>
...
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
...
</plugins>
</pluginManagement>
</build>
</project>
在這裡可以看到所有依賴的版本定義,以及dependencyManagement、pluginManagement 節點,這就是專案依賴可以省略version 的原因