Gradle和Maven有很多類似的地方,比如採用座標Maven中採用groupId,Gradle中採用group
來配置和管理依賴,但不得不說Gradle確實比Maven強大,總的來說Gradle採納了Maven和Ant兩者的優點,下面這篇官方教程將帶你入門Gradle。
這樣子講可能會通熟一點,我儘量結合Gradle和Maven之間的差異來進行講解,因為很多人基本上都是從Maven轉到Gradle,或者說之前有了解過Maven,小編是之前一直使用Maven,現在使用Gradle。
一、Gradle中的Project
1、Project
是什麼?
首先我們應該明白一點,Maven和Gradle都是專案管理工具,那麼很明顯專案
是它們的基本元件,或者也可以將專案
說成工程
,本質上也是一樣的。在Gradle中,一個工程就是一個Project
,這樣講可能會很抽象,如果我告訴你Project
是Gradle原始碼的一個介面以及我們可以通過程式設計的方式來和Gradle的所有特性,(如依賴管理)打交道,你可能就會明白了。
2、我們怎麼使用Project
?
有一個很明顯的問題就是我們必須要程式設計才能和Gradle打交道嗎?答案是否定的,如果你已經閱讀了上面那篇入門教程,你應該知道Gradle工程下會有一個叫build.gradle
的檔案,沒錯,這個檔案就是Gradle工程的配置檔案,而且是一對一的,一個Gradle工程有且只有一個build.gradle
配置檔案。
這和Maven一樣,每個工程對應一個pom.xml
檔案
3、Gradle是如何根據build.gradle
配置檔案管理我們的工程的,即生命週期是什麼?
在構建初始化階段,Gradle根據build.gradle
組裝工程的大致流程如下:
- 1、建立一個
Settings
例項,如果Gradle工程下的settings.gradle
檔案存在,則該檔案將被解析成一個Settings
例項 - 2、根據
settings.gradle
檔案對工程進行配置 - 3、使用
Settings
例項建立Project
例項的結構 - 4、最後,通過對專案執行build.gradle檔案(如果存在)來評估每個專案
4、build.gradle
檔案如何配置
你可能很想知道我該如何對一個build.gradle
進行配置,首先你已經知道一個工程對應一個build.gradle
檔案,也就是說一個build.gradle
檔案就對應一個Project
例項,那麼Project
例項具有的屬性你都可以使用。
在build.gradle
檔案中採用DSL
進行配置,下面是你可以在build.gradle
檔案中配置的內容:
-
Task
Task
是一種任務,任務是Gradle中的基本元件,Task
的概念也是收到了Ant
的啟發而設計的 -
Dependencies
依賴管理
-
Plugins
外掛,就像我們在Maven的
pom.xml
檔案中增加外掛一樣,Gradle也可以新增外掛,常見的外掛有java
,eclipse
,我們可以使用apply plugin: `java`
載入外掛 -
Properties
屬性配置
-
Methods
配置一個方法,納尼,配置檔案可以配置一個方法,你特麼在逗我!沒錯,這就是
DSL
的魅力,DSL
內建支Groovy
這種指令碼語言,因此,我們可以在build.gradle
檔案中編寫相關符合groovy
語法的程式碼,因此,換句話說,build.gradle
檔案已經超出了配置檔案的範疇,看起來更像是一個指令碼檔案,比配置檔案更加強大。 -
Script Blocks
指令碼塊是個很強大的特性,也是Gradle特有的。上面說到其實
build.gradle
檔案相當於一個指令碼檔案,因此指令碼塊的出現也就不足為奇了。常用的指令碼塊有以下幾種:-
allprojects
在多專案工程中對所有專案(包括子專案)的通用配置
-
ant
對ant提供支援
-
artifacts
對生成構件的支援,如生產一個jar包
-
buildscript
執行
gradle build
命令的相關配置,主要配置構建的輸出目錄,引用的倉庫等資訊 -
configurations
提供對依賴管理的支援
-
dependencies
依賴的宣告和配置
-
repositories
倉庫配置
-
subprojects
在多專案中對所有子專案的通用配置
-
二、Gradle中的Properties
1、Gradle中的屬性
Gradle根據Project
例項執行專案的構建檔案以配置專案。你的指令碼使用的任何屬性或方法都被委託給關聯的Project
物件。什麼意思呢?也就是說你可以直接在指令碼中使用Project
介面上的任何方法和屬性。
舉個例子:
defaultTasks(`some-task`) // Delegates to Project.defaultTasks()
reportsDir = file(`reports`) // Delegates to Project.file() and the Java Plugin
複製程式碼
上面在指令碼中配置了一個方法和一個屬性,這兩個配置都將會被應用到Project
例項上去。
當然,你也可以使用project
屬性來表示Project
,即使用project
直接對Project
例項的相關屬性方法進行呼叫,這可以在某些情況下使指令碼更清晰。例如,你可以使用project.name
而不是name
來訪問專案名稱。
一個project
將從5個作用域來查詢相關屬性,你可以在構建檔案中按名稱訪問或通過呼叫專案的Project.property(java.lang.String)
方法這些屬性,5個作用域分別如下:
-
1、
Project
本身。此作用域包括由
Project
實現類宣告的任何屬性setter
和getter
方法。例如,我們可以通Project.getRootProject()
可以作為rootProject
屬性值。根據相應的getter
或setter
方法的存在,此作用域的屬性是可讀或可寫的。 -
2、
project
的extra
屬性每個專案都維護一個
extra
屬性的對映,其中可以包含任意名稱->值對。一旦定義,這個作用域的屬性也是可讀寫的。 -
3、外掛新增到專案的擴充套件屬性
每個副檔名都可用作只讀屬性,其名稱與副檔名相同。
-
4、由外掛新增到專案中的約定屬性
外掛可以通過專案的
Convention
物件將屬性和方法新增到專案中。該範圍的屬性可能是可讀或可寫的,具體取決於約定物件。 -
5、
task
當成一個屬性通過使用其名稱作為屬性名稱可以訪問任務。這個範圍的屬性是隻讀的。 例如,一個名為
compile
的任務可以作為compile
屬性訪問。
extra
屬性和約定屬性從專案的父項繼承,遞迴到根專案。 此作用域的屬性是隻讀的。
讀取屬性時,專案按順序搜尋上述範圍,並從找到該屬性的第一個範圍返回值。如果沒有找到屬性,Gradle就會報錯。
在設定屬性時,專案按順序搜尋上述範圍,並將屬性設定在第一個找到該屬性的範圍中。
2、Extra
屬性
所有Extra
屬性必須通過ext
名稱空間來定義。 一旦定義了一個Extra
屬性,它就直接在擁有的物件上(在下面的例子中分別是專案,任務和子專案)可用,並且可以被讀取和更新。 Extra
屬性只有通過名稱空間ext
進行宣告和初始化後才能使用。
比如下面列出了3個不同作用域下的Extra
屬性:
// Project本身
project.ext.prop1 = "foo"
// 任務
task doStuff {
ext.prop2 = "bar"
}
// 子專案下
subprojects { ext.${prop3} = false }
複製程式碼
讀取Extra
屬性是通過ext
或通過擁有的物件完成的。
ext.isSnapshot = version.endsWith("-SNAPSHOT")
if (isSnapshot) {
// do snapshot stuff
}
複製程式碼
更多屬性可以查閱這裡
三、Gradle配置簡單的多專案工程
該工程為Spring boot
工程,大家可以通過http://start.spring.io/
配置下載,主工程包含三個子工程,分別是myapp-controller
,myapp-service
,myapp-dao
專案結構圖如下:
根目錄下的settings.gradle
rootProject.name = `myapp`
include `myapp-controller`
include `myapp-service`
include `myapp-dao`
複製程式碼
build.gradle
// 構建指令碼
buildscript {
ext {
springBootVersion = `2.0.2.RELEASE`
}
repositories {
mavenCentral()
maven { url `http://maven.aliyun.com/nexus/content/groups/public/` }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
// 所有專案共有的配置
allprojects {
apply plugin: `java`
apply plugin: `eclipse`
apply plugin: `org.springframework.boot`
apply plugin: `io.spring.dependency-management`
group = `com.example`
version = `0.0.1-SNAPSHOT`
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url `http://maven.aliyun.com/nexus/content/groups/public/` }
}
dependencies {
compile(`org.springframework.boot:spring-boot-starter-web`)
testCompile(`org.springframework.boot:spring-boot-starter-test`)
}
}
複製程式碼
每個子工程下的buide.gradle
description = `myapp-controller`
dependencies {
// 該子工程包含另外一個子工程
compile project(`:myapp-dao`)
}
複製程式碼