Gradle是什么:
一個開源的
項目自動化構建工具
,建立在 Apache Ant 和 Apache Maven 概念的基礎上,并引入了基于 Groovy 的特定領域語言(DSL),而不是使用 XML 形式管理構建腳本。(構建工具:依賴管理、自動化運行測試、打包到指定位置)
目錄結構:
- bin:Gradle的可執(zhí)行文件
- init.d:初始化執(zhí)行腳本
- lib:Gradle本身依賴的jar包
- media:圖標文件
Groovy是什么
Groovy是用于Java虛擬機的一種敏捷的動態(tài)語言,它是一種成熟的面向?qū)ο缶幊陶Z言,既可以用于面向?qū)ο缶幊蹋挚梢杂米骷兇獾哪_本語言。使用該語言不必編寫過多的代碼,同時又具有閉包和動態(tài)語言中的其他特征。
與Java比較
- Groovy完全兼容Java的語法
- 分號是可選的
- 類、方法默認是public的
- 編譯器給屬性自動添加getter/setter方法
- 屬性可以直接用點號獲取
- 最后一個表達式的值會被作為返回值
- ==等同于equals(),不會有NullPointerExceptions
高效的Groovy特性
- assert語句,斷言操作
- 可選類型定義
- 可選的括號
- 字符串
- 集合API
- 閉包
Groovy編程案例
public class ProjectVersion{
private int major;
private int minor // 分號可選
public ProjectVersion(int major, int minor){
this.major = major
this.minor = minor ;
}
public int getMajor(){
major // return可省
}
public int setMajor(int major){
this.major = major ;
}
}
ProjectVersion v1 = new ProjectVersion(1, 1) ;
println v1.minor
ProjectVersion v2 = null ;
println v2 == v1 ;
// 1、可選的類型定義
def version = 1
// 2、assert
assert version == 2
// 3、括號是可選的
println(version) // 可以寫成 println version
// 4、字符串
def s1 = 'imooc'
def s2 = "gradle version is ${version}"
def s3 = '''my name
is
imooc''' // 支持換行
println s1
println s2
println s3
// 5、集合api
// list
def buildTools=['ant', 'maven']
buildTools << 'gradle' // 追加一個元素
assert buildTools.getClass() == ArrayList
assert buildTools.size() == 3
// map
def buildYears = ['ant':2000, 'maven':2004]
buildYears.gradle = 2009
println buildYears.ant
println buildYears['gradle']
println buildYears.getClass()
// 6、閉包(代碼塊)
def c1 = {
v ->
print v
}
def c2 = {
print 'hello'
}
def method1(Closure closure){
closure('param')
}
def method2(Closure closure){
closure()
}
method1(c1) ;
method2(c2) ;
groovy構建腳本
// 構建腳本中默認都是有個Project實例的,構建腳本中的代碼默認作用域都是Project
apply plugin: 'java' // plugin: 'java'是命名參數(shù),apply 是Project實例上有一個方法,省略了括號
version = '0.1' // Project實例有個屬性version
repositories { // 一個閉包作為參數(shù)調(diào)用此方法
mavenCentral()
}
dependencies { // 同樣是一個閉包
compile 'commons-codec : commons-codec : 1.6 '
}
Gradle工程目錄結構
group 'com.imooc.gradle'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'war' // 使用插件構建war包,注釋改行可構建jar包
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name:'junit', version: '4.11'
}
構建腳本概要
構建塊
Gradle構建中的兩個基本概念是項目(project)和任務(task),每個構建至少包含一個項目,項目中包含一個或多個任務。在多項目構建中,一個項目可以依賴于其他項目;類似的,任務可以形成一個依賴關系圖來確保他們的執(zhí)行順序。
項目(project)
一個項目代表一個正在構建的組件(比如一個jar文件),當構建啟動后,Gradle會基于build.gradle實例化一個org.gradle.api.Project類,并且能夠通過project變量使其隱式可用。
- 屬性:group、name、version(組件坐標)
- 重要方法:apply(應用插件)、 dependencies(申明項目依賴的jar或其他項目)、repositories(去哪個倉庫獲取jar包)、task(申明項目里的人物)
- 屬性的其他配置方式:ext(定義屬性)、gradle.properties(以鍵值對申明屬性)
任務(task)
任務對應org.gradle.api.Task。主要包括任務動作和任務依賴。任務動作定義了一個最小的工作單元??梢远x依賴于其他任務、動作序列和執(zhí)行條件。
- dependsOn(申明任務依賴)
- doFirst(task動作列表最前面添加動作)、doLast (簡寫方式:<<,動作列表末尾添加動作)
自定義任務
// 2、創(chuàng)建一個閉包,根據(jù)路徑創(chuàng)建文件
def createDir = {
path ->
File dir = new File(path) ;
if(!dir.exists()){
dir.mkdirs() ;
}
}
// 1、自定義任務,自動創(chuàng)建目錄結構的功能
task makeJavaDir(){
def paths = ['src/main/java', 'src/main/resources', 'src/test/java', 'src/test/resources'] ;
doFirst{
paths.forEach(createDir) ;
}
}
task makeWebDir(){
dependsOn = 'makeJavaDir' ; // 依賴
doLast{
paths.forEach(createDir) ;
}
}
- 初始化:Gradle會根據(jù)構建腳本創(chuàng)造一個Project類,并且在這個腳本內(nèi)隱式可用。多項目構建中,初始化所有將要參與構建中的項目。
- 配置:根據(jù)配置代碼(簡單說:除了動態(tài)代碼都是配置代碼),生成task依賴順序以及執(zhí)行順序。
- 執(zhí)行階段:執(zhí)行動作代碼
依賴管理
幾乎所有的基于JVM的軟件項目都需要依賴外部類庫來重用現(xiàn)有的功能。自動化的依賴管理可以明確依賴的版本,可以解決因傳遞性依賴帶來的版本沖突。
工件坐標
- group、name、version
常用倉庫
- mavenLocal/mavenCentral/jcenter
- mavenCentral/jcenter:公共倉庫
- mavenLocal:本機使用過的jar的倉庫
- 自定義maven倉庫
- 文件倉庫(本地文件路徑作為倉庫:不建議使用)
依賴的傳遞性
- B依賴A,如果C依賴B,那么C依賴A(造成版本沖突的原因)
依賴管理的階段
依賴階段配置
- compile、runtime(源代碼)
- testCompile、testRuntime(測試代碼)
repositories { // 倉庫,依賴倉庫按順序進行依賴優(yōu)先級
maven{ // 私服
url '私服地址'
}
mavenLocal()
mavenCentral()
}
dependencies {
compile 'ch.qos.logback:logback-classic:1.2.1'
testCompile group: 'junit', name:'junit', version: '4.11'
}
依賴沖突
解決沖突
查看依賴報告
排除傳遞性依賴
強制一個版本
-
修改默認解決策略(Gradle默認依賴最高版本來解決版本沖突)
configurations.all{ resolutionStrategy{ failOnVersionConflict() // 使構建失敗,可以知道哪些出現(xiàn)版本沖突 } }
-
排除傳遞性依賴
compile('org.hibernate:hibernate-core:3.6.3.Final'){ exclude group:"org.slf4j", module:"slf4j-api" // transitive=false }
-
強制指定一個版本
configurations.all{ resolutionStrategy{ force 'org.slf4j:slf4j-api:1.7.24' } }
項目模塊化
在企業(yè)項目中,包層次和類關系比較復雜,把代碼拆分成模塊通常是最佳實踐,這需要你清晰的劃分功能的邊界,比如把業(yè)務邏輯和數(shù)據(jù)持久化拆分開來。項目符合高內(nèi)聚低耦合時,模塊化就變得很容易,這是一條非常好的軟件開發(fā)實踐。
配置要求
- 所有項目應用Java插件
- web子項目打包成WAR
- 所有項目添加logback日志功能
-
統(tǒng)一配置公共屬性
項目范圍
settings.gradle:管理多項目構建
rootProject.name = 'todo' // 根項目
include 'repository' // 子項目
include 'model'
include 'web'
web項目:
dependencies {
compile project(":repository")
testCompile group: 'junit', name:'junit', version: '4.11'
}
todo項目:
allprojects{ // 全局配置
apply plugin: 'java'
sourceCompatibility = 1.8
}
// 所有項目添加logback日志功能
subprojects{
repositories{
mavenCentral()
}
dependencies{
compile 'ch.qos.logback:logback-classic:1.2.1'
testCompile group: 'junit', name:'junit', version: '4.11'
}
}
統(tǒng)一配置group和version
根項目添加:gradle.properties文件
group = 'com.imooc.gradle'
version = 1.0-SNAPSHOT
自動化測試
一些開源的測試框架,比如JUnit,TestNG能夠幫助你編寫可復用的結構化的測試,為了運行這些測試,你要先編譯它們,就像編譯源代碼一樣。測試代碼的作用僅僅用于測試的情況,不應該被發(fā)布到生產(chǎn)環(huán)境中,需要把源代碼和測試代碼分開來。
項目布局
測試配置
dependencies{
testCompile 'junit:junit:4.11'
}
測試發(fā)現(xiàn)
- 任何繼承自junit.framework.TestCase或groovy.util.GroovyTestCase的類
- 任何被@RunWith注解的類
- 任何至少包含一個被@Test注解的類
發(fā)布到本地倉庫和遠程倉庫
allprojects{
apply plugin: 'java'
sourceCompatibility = 1.8
apply plugin: 'maven-public'
publishing{
publications{
myPublish(MavenPublication){ // 自定義函數(shù)
from components.java
}
}
repositories{
maven{
name "myRepo" // 自定義倉庫名
url "" // 自己倉庫
}
}
}
}