1. 程式人生 > 其它 >Spring Boot Starter Parent

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 提供了以下功能:

  1. Java 1.8 作為預設的編譯版本

  2. 原始碼使用UTF-8 格式編碼

  3. 繼承自spring-boot-dependencies,這裡管理了常見依賴的版本。可以讓我們在專案的pom.xml中省略這些依賴的標籤。

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
  4. 自動化的資源過濾:預設把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>
    
  5. 自動化的外掛管理:預設為maven 外掛提供了預設配置,如:maven-compile-plugin, maven-war-plugin

  6. 自動對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 的原因

六、參考文件