Gradle學習系列—-多專案構建

擁抱心中的夢想發表於2019-03-04

Gradle和Maven有很多類似的地方,比如採用座標Maven中採用groupId,Gradle中採用group來配置和管理依賴,但不得不說Gradle確實比Maven強大,總的來說Gradle採納了Maven和Ant兩者的優點,下面這篇官方教程將帶你入門Gradle。

Gradle入門(翻譯自Graddle官網)

這樣子講可能會通熟一點,我儘量結合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也可以新增外掛,常見的外掛有javaeclipse,我們可以使用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實現類宣告的任何屬性settergetter方法。例如,我們可以通Project.getRootProject()可以作為rootProject屬性值。根據相應的gettersetter方法的存在,此作用域的屬性是可讀或可寫的。

  • 2、projectextra屬性

    每個專案都維護一個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

專案結構圖如下:

Gradle學習系列—-多專案構建

根目錄下的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`)
}
複製程式碼

相關文章