Spring的依賴管理

SpringBoot依賴管理的能力

SpringBoot管理的依賴有1000多個,詳見Dependency Versions (spring.io)。這些組件,在和SpringBoot一起使用的時候,可以不指定版本,因爲SpringBoot預定義了合適的版本。這樣做的好處是大大降低了依賴衝突的概率。

例如,對於這樣一個項目(使用了web和kafka-clients):

plugins {
    id 'org.springframework.boot' version '2.6.4'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'cn.whu.wy'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    maven { url 'https://maven.aliyun.com/repository/public' }
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation group: 'org.apache.kafka', name: 'kafka-clients', version: '2.6.0'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

指定了kafka-clients使用2.6.0版本,依賴面板顯示:

實際上,由於kafka-clients也納入了SpringBoot的依賴管理,可以不指定版本號。去掉version: '2.6.0'之後,依賴面板顯示:

可見,SpringBoot 2.6.4預定義的Kafka版本爲3.0。

SpringBoot的依賴

Spring Initializr上創建一個簡單的SpringBoot項目(web+jdbc),生成的依賴爲:

plugins {
  id 'org.springframework.boot' version '2.7.0'
  id 'io.spring.dependency-management' version '1.0.11.RELEASE'
  id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
  compileOnly {
    extendsFrom annotationProcessor
  }
}

repositories {
  mavenCentral()
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-jdbc'
  implementation 'org.springframework.boot:spring-boot-starter-web'
  compileOnly 'org.projectlombok:lombok'
  runtimeOnly 'mysql:mysql-connector-java'
  annotationProcessor 'org.projectlombok:lombok'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
  useJUnitPlatform()
}

SpringCloud的依賴

如果還勾選了SpringCloud的組件(如openfeign),生成的依賴爲:

plugins {
  id 'org.springframework.boot' version '2.7.0'
  id 'io.spring.dependency-management' version '1.0.11.RELEASE'
  id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
  compileOnly {
    extendsFrom annotationProcessor
  }
}

repositories {
  mavenCentral()
}

ext {
  set('springCloudVersion', "2021.0.3")
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-jdbc'
  implementation 'org.springframework.boot:spring-boot-starter-web'
  implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
  compileOnly 'org.projectlombok:lombok'
  runtimeOnly 'mysql:mysql-connector-java'
  annotationProcessor 'org.projectlombok:lombok'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
  imports {
    mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
  }
}

tasks.named('test') {
  useJUnitPlatform()
}

可見,比起只使用SpringBoot的組件,多了以下內容:

ext {
  set('springCloudVersion', "2021.0.3")
}

dependencyManagement {
  imports {
    mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
  }
}

org.springframework.boot與io.spring.dependency-management的區別

上面的幾個示例都使用了兩個插件:org.springframework.boot(以下簡稱springboot插件)和io.spring.dependency-management(以下簡稱dependency-management插件)。這倆有什麼區別?

springboot插件表示這是一個SpringBoot項目,可以build爲一個可執行的jar包(使用下圖build面板下的bootJar命令),項目裏面必須有一個使用@SpringBootApplication標記的類,該類是可執行jar的入口類。

dependency-management插件,從名字就能看出來是管理依賴的。如下圖,help下面的dependencyXXX等命令就是該插件提供的:

雙擊運行dependencyManagement命令,會打印出Default dependency management for all configurations:

這些配置就是你正在用的SpringBoot版本所管理的依賴,與docs.spring.io上提供的是一致的。比如我正在使用SpringBoot 2.6.4,dependencyManagement命令打印的內容與https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/dependency-versions.html相同。

兩個插件的聯繫

When you apply the io.spring.dependency-management plugin, Spring Boot’s plugin will automatically import the spring-boot-dependencies bom from the version of Spring Boot that you are using.

非SpringBoot項目如何使用SpringBoot管理依賴

Ref:Using Spring Boot's Dependency Management in Isolation

有些項目並不是SpringBoot項目(不需要build爲可執行的jar包),又想使用SpringBoot的依賴管理功能,該怎麼做?

plugins {
    // configure the project to depend on the Spring Boot plugin but do not apply it:
    id 'org.springframework.boot' version '2.6.4' apply false // look here!
    id 'java'
}

// add this
apply plugin: 'io.spring.dependency-management'

dependencyManagement {
    imports {
        mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
    }
}

gradle legacy plugin application(老式寫法)

以下是一個具備依賴管理功能的可運行的SpringBoot項目:

buildscript {
  repositories {
    maven { url "https://plugins.gradle.org/m2/" }
  }
  dependencies {
    classpath "org.springframework.boot:spring-boot-gradle-plugin:2.7.0"
    classpath "io.spring.gradle:dependency-management-plugin:1.0.11.RELEASE"
  }
}

apply plugin: "org.springframework.boot" 
apply plugin: "io.spring.dependency-management"

// 下面的group、version、sourceCompatibility、repositories{}、dependencyManagement{}、dependencies{} 等是一樣的,略

以下是一個具備依賴管理功能的不可運行的SpringBoot項目:

buildscript {
  repositories {
    maven { url "https://plugins.gradle.org/m2/" }
  }
  dependencies {
    classpath "org.springframework.boot:spring-boot-gradle-plugin:2.7.0"
  }
}

apply plugin: "io.spring.dependency-management"
dependencyManagement {
    imports {
        mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
    }
}

// 下面的group、version、sourceCompatibility、repositories{}、dependencyManagement{}、dependencies{} 等是一樣的,略

maven spring-boot-starter-parent

依賴 spring-boot-starter-parent

  • 方便快捷
  • 自動引入 spring-boot-dependencies
  • 自動配置 spring-boot-maven-plugin
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

不依賴 spring-boot-starter-parent

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.1.1.RELEASE</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Reference

  1. Dependency Versions (spring.io)
  2. Dependency Management Plugin (spring.io)
  3. Spring Boot Gradle Plugin Reference Guide
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章