使用 Gradle+buildSrc 更好的管理多模块项目
作为两种常见的构建管理工具,Maven及Gradle的使用非常广泛,前者使用xml作为配置文件,而后者使用Grovvy或Kotlin语言作为构建脚本,可以提供更灵活、更强大的配置功能,并且IDEA的智能补全也更强大。
创建多Module项目
-
在IDEA中点击New - Project,选择Gradle(右侧的Additional Library...可以不用选择,如果是单Module的则需要),然后点击Next,在对话框中配置项目的相关信息,点击Finish;此时根目录下会有
settings.gradle
和build.gradle
文件; -
右键项目名,新建目录,目录名便是Module名,假设Module名为
infra
,然后在新建的目录下再新建一个build.gradle
文件; -
编辑根目录的
settings.gradle
文件,在其中添加include(":infra")
; -
打开IDEA右侧边栏的Gradle面板,点击左上角的刷新按钮(Reload All Gradle Projects);
重复上述几个步骤,可以创建多个Module,但是还没有sourceSet目录,我们需要手动创建配置一下:
- 分别在上面的几个Module目录下新建
src/main/java
目录和src/main/resources
目录,如果需要测试则再创建src/test/java
目录和src/test/resources
目录; - 如果IDEA没有识别出上面步骤创建的文件夹,可以点击File - Project Structure,在Module栏分别对几个Module下的文件夹进行指定:
之后,我们就可以在java
目录下新建包名进行开发了。
settings.gradle
文件中可以对项目结构进行更灵活的配置,比如我们想将几个Module放在一个单独的目录中,可以在settings.gradle
中进行设置:
include(":infra")
project(":infra").projectDir = file("base/infra")
在根目录下的build.gradle
文件中,可以对其他子Module进行共同的配置,比如为所有Module启动Lombok支持,引用共同的依赖,以下是一个示例:
//noinspection GroovyAssignabilityCheck
allprojects {
apply plugin: 'java'
version = '0.0.1-SNAPSHOT'
java.sourceCompatibility = JavaVersion.VERSION_1_8
repositories {
mavenCentral()
}
dependencies {
annotationProcessor "org.projectlombok:lombok:1.18.12"
implementation "org.projectlombok:lombok:1.18.12"
}
}
使用buildSrc管理依赖
buildSrc
目录与build.gradle
和settings.gradle
文件一样,是Gradle预设的目录,目录下的文件会被Gradle自动添加到构建脚本的classpath中。buildSrc
目录必须在根目录下,且其结构与普通的Module类似。
要使用buildSrc
,首先需要在根目录下创建buildSrc
文件夹,并在其中创建build.gradle
文件,然后刷新项目即可,不需要在settings.gradle
进行修改;然后在其中创建src/main/java
或src/main/kotlin
或src/main/groovy
目录,并创建包名以及声明依赖,我们这里以Kotlin为例:
// buildSrc/build.gradle
apply plugin: 'java-gradle-plugin'
apply plugin: 'kotlin'
buildscript {
ext.kotlin_version = '1.5.30'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
接着创建com.example.build.Deps
类:
package com.example.build
object Deps {
object Spring {
private const val version = "2.3.3.RELEASE"
const val mail = "org.springframework.boot:spring-boot-starter-mail:$version"
const val web = "org.springframework.boot:spring-boot-starter-web:$version"
const val thymeleaf = "org.springframework.boot:spring-boot-starter-thymeleaf:$version"
const val devTools = "org.springframework.boot:spring-boot-devtools:$version"
const val jpa = "org.springframework.boot:spring-boot-starter-data-jpa:$version"
const val validation = "org.springframework.boot:spring-boot-starter-validation:$version"
}
const val lombok = "org.projectlombok:lombok:1.18.12"
}
这样,我们就可以在其他Module下使用这些依赖,比如在根目录下的build.gradle
为所有Module启用Lombok支持:
import com.example.build.Deps
plugins {
id 'java'
}
group("com.example")
allprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
annotationProcessor Deps.lombok
implementation Deps.lombok
}
}
或者在Module中使用这些依赖:
import com.example.build.Deps
repositories {
mavenCentral()
}
dependencies {
implementation project(":infra")
implementation project(":remote")
implementation Deps.Spring.web
}
从Maven迁移
官方提供了从Maven迁移的文档,说的比较详细,可能有一些不需要的内容,简单来说,可以通过以下步骤迁移:
一、为Maven项目创建build scan。首先在项目根目录下的.mvn/extensions.xml
文件添加以下内容(如果没有则创建即可):
<extensions>
<extension>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<version>1.11</version>
</extension>
</extensions>
然后在项目根目录下运行命令mvn install
。运行过程中会询问是否接受协议,输入yes
,完成后会有一个URL,浏览器中打开此URL,输入自己的邮箱,邮件里的网址里便是项目的构建信息。
二、运行自动迁移命令。在根目录下运行命令gradle init
。此命令可以完成大部分的迁移工作,不过对于一些比较复杂的构建配置,仍然需要人工进行校验核对,以确保迁移前后没有影响,Maven的依赖声明:
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
对应了Gradle的以下声明方式:
dependencies {
implementation 'log4j:log4j:1.2.12'
}
对于Maven不同的依赖scope,可以参考下面的Gradle函数:
Maven Dependency Scope | Gradle Scope | 说明 |
---|---|---|
compile | implementation 或api | api 只有在用Java Library插件的时候才可以使用 |
runtime | runtimeOnly | |
test | testImplementation 或testRuntimeOnly | |
provided | compileOnly |
更复杂的情形可以查看官方文档。
三、为Gradle创建Build Scan。对于Gradle 4.3及以上,可以通过运行命令gradle build --scan
完成,若在4.3以下,则需要将以下代码放在任意一个buildscript { ... }
代码块中,并运行命令gradle build --scan
:
plugins {
id 'com.gradle.enterprise' version '1.16'
}
buildScan {
licenseAgreementUrl = 'https://gradle.com/terms-of-service'
licenseAgree = 'yes'
}
四、对比第一步和第三步两次的build scan,修复依赖和问题;
五、迁移插件。
迁移完成后,仍然可以通过上面的步骤,使用buildSrc
管理依赖,来更方便的管理依赖版本以及借助IDEA的智能补全功能提高开发效率。