1. 程式人生 > 實用技巧 >6.Gradle多模組專案

6.Gradle多模組專案

假設有一個專案,它由3個模組組成:model、repository、web;

三個模組之間的依賴關係是:web -> repository -> model

1. Settings

settings檔案聲明瞭所需的配置來例項化專案的層次結構。在預設情況下,這個檔案被命名為 settings.gradle,並且和根專案的build.gradle檔案放在一起。

1.1 settings檔案

下面的清單顯示了 settings 檔案的內容。若想使每個子專案都成為構建的一-部分,則可以呼叫帶有專案路徑引數的 include 方法。

settings.gradle

// 將給定的子專案新增到構建中,傳給include方法的引數是專案路徑,不是檔案路徑
include 'model'
// 將專案的字串陣列傳給方法呼叫,而不是為每個單獨的子專案呼叫include方法
include 'repository', 'web'

1.2 settings api

Gradle組裝構建之前,它會建立- - 個Settings型別的例項。Settings 介面是settings檔案的直接表示。它的主要作用是新增Project例項參與多專案構建。
除了組裝多專案構建之外,你可以在build.gradle指令碼中做任何事情,因為你可以直接訪問Gradle和Project介面。下圖顯示了Settings介面的相關方法及其聯絡。

1.3 settings 執行

2. 配置子專案

2.1 Project API

為了宣告特定的專案構建程式碼,使用了project方法。至少必須提供專案路徑(例如,:model)。

很多時候,你想要為所有的專案或只有子專案定義一些公 共的行為。為實現這些用例,Project API提供了兩個專門的方法: allprojects和subprojects.假設你想要把Java外掛應用到所有子專案中,因為你需要編譯Java原始碼。你可以通過在subprojects閉包引數中定義程式碼來實現。

在多專案構建中專案的預設執行順序是基於它們的字母名稱的。為了顯式地控制在構建生命週期的配置階段的執行順序,你可以使用專案執行方法 evaluationDependsOn和evaluationDependsOnChildren。對於需要確保為一個專案設定的屬性可以被其他專案使用的情況尤其如此。

2.2 定義特定行為

可以通過 project 方法來定義特定的專案行為。為了給三個子專案 model、repository、web 搭建構建基礎環境,你需要為它們分別建立--個專案配置塊。下面的清單顯示了在 build.gradle 檔案中的專案定義。

build.gradle

ext.projectIds = ['group': 'com.manning.gia', 'version': '0.1']

group = projectIds.group
version = projectIds.version

project(':model') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'
}

project(':repository') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'
}

project(':web') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'
    apply plugin: 'war'
    //apply plugin: 'jetty'

    repositories {
        mavenCentral()
    }

    dependencies {
        providedCompile 'javax.servlet:servlet-api:2.5'
        runtime 'javax.servlet:jstl:1.1.2'
    }
}

2.3 專案間依賴

project(':model') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'
}

project(':repository') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'

    dependencies {
        compile project(':model')
    }
}

project(':web') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'
    apply plugin: 'war'
    //apply plugin: 'jetty'

    repositories {
        mavenCentral()
    }

    dependencies {
        compile project(':repository')
        providedCompile 'javax.servlet:servlet-api:2.5'
        runtime 'javax.servlet:jstl:1.1.2'
    }
}

2.4 多專案部分構建

擁有幾十個甚至上百個依賴的子專案的複雜多專案構建,將大大影響平均執行時間。Gradle 會遍歷所有的專案依賴並確保它們是最新的。在開發階段,通常知道在什麼子專案中哪些原始檔發生了變化。從技術上講,不需要重新構建沒有發生變化的子專案。

針對這些情況,Gradle 提供了部分構建特性。部分構建是通過命令 行選項- a 或 --no-rebuild 啟用的。假設在子專案 repository 中只改變了 程式碼,但不想重新構建子專案 model。通過使用部分構建,可以省去檢查子專案model的成本並且降低構建執行時間。如果你正工作在-一個擁有上百個子專案依賴的企業級專案中,你會感激在執行構建時節省的每一秒。

gradle :repository:build -a

gradle :repository:buildNeeded

2.5 跨專案task

假設在根專案和子專案中定義了一個名為 hello 的 task

build.gradle

ext.projectIds = ['group': 'com.manning.gia', 'version': '0.1']

group = projectIds.group
version = projectIds.version

task hello {
    doLast {
        println 'Hello from root project'
    }
}

project(':model') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'

    task hello {
        doLast {
            println 'Hello from model project'
        }
    }
}

project(':repository') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'

    dependencies {
        compile project(':model')
    }

    task hello {
        doLast {
            println 'Hello from repository project'
        }
    }
}

project(':web') {
    group = projectIds.group
    version = projectIds.version
    apply plugin: 'java'
    apply plugin: 'war'

    repositories {
        mavenCentral()
    }

    dependencies {
        compile project(':repository')
        providedCompile 'javax.servlet:servlet-api:2.5'
        runtime 'javax.servlet:jstl:1.1.2'
    }
}

控制task執行順序

task hello {
    doLast{
        println 'Hello from root project'
    }
}

project(':model') {
     //...
    task hello(dependsOn: ':repository:hello') {
        doLast{
            println 'Hello from model project'
        }
    }
}

project(':repository') {
    //...
    dependencies {
        compile project(':model')
    }

    task hello {
        doLast{
            println 'Hello from repository project'
        }
    }
}

2.6 定義公共行為

allprojects {
    group = 'com.manning.gia'
    version = '0.1'
}

subprojects {
    apply plugin: 'java'
}

project(':repository') {
    dependencies {
        compile project(':model')
    }
}

project(':web') {
    apply plugin: 'war'
    apply plugin: 'jetty'

    repositories {
        mavenCentral()
    }

    dependencies {
        compile project(':repository')
        providedCompile 'javax.servlet:servlet-api:2.5'
        runtime 'javax.servlet:jstl:1.1.2'
    }
}

2.7 每個專案建立構建檔案

root -> build.gradle

allprojects {
    group = 'com.manning.gia'
    version = '0.1'
}

subprojects {
    apply plugin: 'java'
}

model-> build.gradle

repository-> build.gradle

dependencies {
    compile project(':model')
}

web-> build.gradle

apply plugin: 'war'
//apply plugin: 'jetty'

repositories {
    mavenCentral()
}

dependencies {
    compile project(':repository')
    providedCompile 'javax.servlet:servlet-api:2.5'
    runtime 'javax.servlet:jstl:1.1.2'
}

3. 參考

  1. 《實戰Gradle 中文版》