一、Gradle相比Maven的優勢
-
配置簡潔
Maven是用pom.xml管理,引入一個jar包至少5行程式碼,Gradle只需要一行。
-
構建速度快
Gradle支援daemon方式執行,啟動速度快,同時有基於daemon的增量構建,充分利用JVM的執行時優化,和快取資料構建速度相比Maven快很多。
-
更好的靈活性、擴充套件性
Gradle 相對於 Maven 等構建工具, 其提供了一系列的 API 讓我們有能力去修改或定製專案的構建過程。
二、基本配置
-
設定本地倉庫地址
預設本地倉庫地址是:~/.gradle,Windows下會佔用大量C盤空間。
設定環境變數,GRADLE_USER_HOME=/your/path
-
複用Maven本地倉庫
在repositories配置mavenLocal()即可,如果是init.gradle全域性配置,參考以下init.gradle檔案
Maven本地倉庫查詢路徑:
(1)USER_HOME/.m2/settings.xml
(2)M2_HOME/conf/settings.xml
(3)USER_HOME/.m2/repository
-
國內映象加速
國內訪問國外倉庫地址很慢,第一種方法是在每個專案中設定repositories
repositories { mavenLocal() 'maven(http://maven.aliyun.com/nexus/content/groups/public/)' mavenCentral() }
更推薦的方式是類似的Maven的settings.xml全域性的配置,在上一步配置的GRADLE_USER_HOME路徑下,新增init.gradle檔案,以下配置檔案中使用了阿里雲的Gradle代理,支援jcenter、google、maven倉庫。
gradle.projectsLoaded { rootProject.allprojects { buildscript { repositories { def JCENTER_URL = 'https://maven.aliyun.com/repository/jcenter' def GOOGLE_URL = 'https://maven.aliyun.com/repository/google' def NEXUS_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter' all { ArtifactRepository repo -> if (repo instanceof MavenArtifactRepository) { def url = repo.url.toString() if (url.startsWith('https://jcenter.bintray.com/')) { project.logger.lifecycle "Repository ${repo.url} replaced by $JCENTER_URL." println("buildscript ${repo.url} replaced by $JCENTER_URL.") remove repo } else if (url.startsWith('https://dl.google.com/dl/android/maven2/')) { project.logger.lifecycle "Repository ${repo.url} replaced by $GOOGLE_URL." println("buildscript ${repo.url} replaced by $GOOGLE_URL.") remove repo } else if (url.startsWith('https://repo1.maven.org/maven2')) { project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL." println("buildscript ${repo.url} replaced by $REPOSITORY_URL.") remove repo } } } jcenter { url JCENTER_URL } google { url GOOGLE_URL } maven { url NEXUS_URL } } } repositories { def JCENTER_URL = 'https://maven.aliyun.com/repository/jcenter' def GOOGLE_URL = 'https://maven.aliyun.com/repository/google' def NEXUS_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter' all { ArtifactRepository repo -> if (repo instanceof MavenArtifactRepository) { def url = repo.url.toString() if (url.startsWith('https://jcenter.bintray.com/')) { project.logger.lifecycle "Repository ${repo.url} replaced by $JCENTER_URL." println("buildscript ${repo.url} replaced by $JCENTER_URL.") remove repo } else if (url.startsWith('https://dl.google.com/dl/android/maven2/')) { project.logger.lifecycle "Repository ${repo.url} replaced by $GOOGLE_URL." println("buildscript ${repo.url} replaced by $GOOGLE_URL.") remove repo } else if (url.startsWith('https://repo1.maven.org/maven2')) { project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL." println("buildscript ${repo.url} replaced by $REPOSITORY_URL.") remove repo } } } jcenter { url JCENTER_URL } google { url GOOGLE_URL } maven { url NEXUS_URL } } } }
三、最佳實踐
-
多模組配置
稍微大點的專案都會分模組開發,Gradle相比Maven的一個優勢是用IDEA執行一個專案的程式碼時,會自動編譯其依賴的其他模組。
在專案一級目錄下新增settings.gradle配置檔案:
rootProject.name = 'my-roject-name' include 'module1' include 'module2'
其中module1、module2就是子模組的資料夾名,在子模組裡需要有一個配置子模組的build.gradle
模組內依賴,比如module2依賴module1,在module2的build.gradle配置檔案裡新增:
dependencies { compile project(":module1") }
-
profile支援
profile用來載入不同環境的的配置檔案,在筆者所在公司,推薦dev、test、staging、prod四套環境。
新增gradle.properties配置檔案指定預設profile
profile=dev
啟動profile,載入不同路徑下的配置,在build.gradle裡新增配置:
ext { profile = project['profile'] } sourceSets { main { resources { srcDirs = ["src/main/resources/", "src/main/profiles/${profile}"] } } }
命令列引數指定profile:
gradle build -Pprofile=prod
-
初始化gradle專案
安裝gradle,並在專案頂級目錄下執行:
gradle init
如果當前目錄有pom.xml,接下來會提示是否從Maven專案初始化Gradle專案,選擇yes回車執行。
引數文件:https://docs.gradle.org/current/userguide/build_init_plugin.html
-
引入bom檔案
pom檔案在Maven中是一個很有用的功能,方便多個專案統一版本號,在Maven中配置方式如下:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Gradle有外掛支援類似操作:
//引入外掛 plugins { id "io.spring.dependency-management" version "1.0.10.RELEASE" } //引入bom dependencyManagement { imports { mavenBom 'org.springframework.boot:spring-boot-dependencies:${spring-boot.version}' } } //使用bom,不需要執行版本號 dependencies { implementation "org.springframework.boot:spring-boot-starter-web" }
-
引入parent檔案
在maven中執行parent是管理多個專案常用的方式,parent指定了專案的基本配置,配置方式如下:
<parent> <groupId>com.lesofn.blog</groupId> <artifactId>test-parent</artifactId> <version>0.0.1</version> </parent>
Maven中的parent有兩個作用,一個是類似bom的統一管理版本,即parent中的:dependencyManagement,另一個是基礎jar包的引用,即父pom中的:dependencies
在Gradle可通過上面的io.spring.dependency-management外掛實現類似的效果:
//引入外掛 plugins { id "io.spring.dependency-management" version "1.0.10.RELEASE" } //引入parent,實現maven中dependencyManagement的功能,不用指定版本號 dependencyManagement { imports { mavenBom 'com.lesofn.blog:test-parent:0.0.1' } } //再次引入parent,實現maven中dependencies的功能 dependencies { implementation 'com.lesofn.blog:test-parent:0.0.1' }
四、總結
經過以上配置,基本覆蓋了Gradle開發過程中的大部分問題,如果還有什麼問題,歡迎留言討論。
本文作者:木小豐,美團Java高階工程師,關注架構、軟體工程、全棧等,不定期分享軟體研發過程中的實踐、思考。
部落格地址:https://lesofn.com/archives/gradle-zui-jia-shi-jian
公共號:Java研發