美文网首页
Gradle第13课:Gradle 中常用插件的介绍-下

Gradle第13课:Gradle 中常用插件的介绍-下

作者: 米饭超人 | 来源:发表于2018-08-28 11:09 被阅读337次

    需要准备

    • 一个熟悉的 IDE 开发工具
    • JDK 7及以上
    • Gradle 3.2以上

    通过五步聚来使用 Java 插件

    第一步,Java 插件的引用

    在 build.gradle 中添加以下语句,表示对 java 插件的引用。

    apply plugin:'java'  
    
    

    第二步,Java 插件的任务

    任务名称 依赖 类型 描述
    compileJava 依赖类路径下所有的编辑任务 JavaCompile 使用javac来编译工程的java源文件
    processResources - Copy 将项目的资源文件复制到项目生产的class目录中
    classes 依赖compileJava和processResource两个任务,一些插件添加的额外编译任务 Task 组装产生的classes和resources目录
    compileTestJava 依赖compile和一些产生测试编译环境的任务 JavaCompile 使用javac编译java测试源码
    processTestResources - Copy 将测试资源文件复制到项目产生的test资源文件目录中
    testClasses 依赖compileTestJava和processTestResource和一些添加测试的编译任务 Task 组装测试的classes和资源目录
    jar 依赖compile Jar 组装成jar文件
    javadoc 依赖compile Javadoc 生成java帮助文档
    test 依赖compile,compileTest等 Test 使用JUnit和TestNG执行单元测试
    uploadArchives 依赖那些在归档配置过程中产生镜像的任务,比如jar。属于UpLoad类型 Upload 上传归档文件,包括JAR文件
    clean - Delete 删除项目的build目录
    cleanTaskName - Delete 删除由任务所产生的文件,比如cleanJar就是删除有任务jar产生的文件,cleanTest就是删除由test产生的文件

    工程中添加的每一个资源集合( source set ),Java 插件将会为它们添加以下编译任务,在“定义一个新的资源集合”一节中还会具体用到这些任务的。

    任务名称 依赖 类型 描述
    compileSourceSetJava 依赖所有产生sourceset编译类路径的任务 JavaCompile 使用javac编译sourceset定义的源文件
    processSourceSetResources - Copy 将sourceset定义的资源文件复制到resources目录
    sourceSetClasses 依赖compileSourceSetJava和processSourceSetResources两个任务 Task 组装sourceset中定义的文件目录

    而 Java 插件添加的这些任务组成了工程的生命周期。

    任务名称 依赖 类型 描述
    assemble 依赖所有的归档文件,包括Jar任务 Task 组装工程中所有的归档文件
    check 依赖所有验证类任务,包括test Task 在工程中执行所有的验证类任务
    build 依赖check和assemble Task 执行工程的完全构建
    buildNeeded 不仅依赖当前工程的build和buildNeeded任务,也依赖那些作为当前工程运行时依赖库的所有工程中的build和buildNeeded任务 Task 执行工程的完全构建,也包括那些作为当前工程运行时依赖库的所有工程的构建
    buildDependents 不仅依赖当前工程的build和buildDependents任务,也依赖那些把当前工程当作运行时依赖库的所有工程中的build和buildDependents任务 Task 执行工程的完全构建,也包括那些把当前工程当作运行时依赖库的所有工程的构建,该任务正好与buildNeeded依赖相反
    buildConfigName 依赖配置configName指定的任务 Task 组装那些特殊配置的镜像,该任务被Java插件隐式添加的
    uploadConfigName 依赖configName定义的任务 Upload 组装和上传那些特殊配置的镜像,该任务被Java插件隐式添加的

    下面的图展示了各任务之间的关系:

    enter image description here

    第三步,工程目录结构

    Java 插件约定的工程目录结构,在进行 java 编译的时候,会访问下面所有的目录,但是这些目录并不要求必须存在。

    目录 意义
    src/main/java java源文件
    src/main/resources 项目资源文件
    src/test/java 测试源文件
    src/test/resources 测试资源文件
    src/sourceSet/java source set定义的java源文件
    src/sourceSet/resources source set定义的资源文件

    我们可以通过 sourceSets 来修改这些默认的目录结构,比如修改 src/main/java为src/java、然后修改 src/main/resources 为 src/resources,更多 sourceSets 的配置将在“source sets属性介绍”一节中详细介绍,其示例代码如下:

    sourceSets{  
        main{  
            java{  
                srcDir 'src/java'  
            }  
            resources{  
                srcDir 'src/resources'  
            }  
        }  
    }  
    

    第四步,依赖管理

    Java 插件为工程添加了一些依赖配置,并且把这些配置指绑定到任务中,比如 compileJava 和 test 任务。下面为依赖配置列表。

    名称 继承 被什么任务使用 作用
    compile - - 编译时的依赖
    compileOnly compile - 仅在编译时的依赖,不在运行时依赖
    compileClasspath compileOnly compileJava 编译类路径,在编译资源(source)时使用
    runtime compile - 在运行时使用
    testCompile compile - 在编译测试时的额外依赖
    testCompileOnly testCompile - 仅在编译测试时的额外依赖,不在测试运行时依赖
    testCompileClasspath testCompileOnly compileTestJava 测试编译类路径,在编译测试资源(source)时使用
    testRuntime runtime, testCompile test 仅在测试运行时的额外依赖
    archives - uploadArchives 工程生成归档文件时,比如生成jars文件时
    default runtime - 在工程运行时的默认依赖配置

    以下是依赖配置关系图,浅蓝色的代表 java 任务,绿色代表 gradle 任务。

    enter image description here

    资源集合( source set )的依赖配置,在“定义一个新的资源集合”一节中会使用到这些任务。

    名称 继承 被什么任务使用 作用
    sourceSetCompile - - 为指定的资源集合在编译时的依赖
    sourceSetCompileOnly sourceSetCompile - 为指定的资源集合仅在编译时的依赖,不在运行时依赖
    sourceSetCompileClasspath sourceSetCompileOnly compileSourceSetJava 编译类路径,在编译资源(source)时使用
    sourceSetRuntime sourceSetCompile - 为指定的资源集合在运行时依赖

    第五步,常用的属性

    Java 插件会为工程添加一些常用的属性,我们可以直接在编译脚本中直接使用。

    属性名称 类型 默认值 描述
    reportsDirName String reports 生成报告的目录名称
    reportsDir File(只读) buildDir/reportsDirName 生成报告的目录
    testResultsDirName String test-results 生成测试result.xml文件的目录名称
    testResultsDir File(只读) reportsDir/testReportDirName 生成测试报告的目录
    libsDirName String libs 生成lib库的目录名称
    libsDir File(只读) buildDir/libsDirName 生成lib库的目录
    distsDirName String distributions 生成发布文件的目录名称
    distsDir File(只读) buildDir/distsDirName 生成发布文件的目录
    docsDirName String docs 生成帮助文档的目录名称
    docsDir File(只读) buildDir/docsDirName 生成帮助文档的目录
    dependencyCacheDirName String dependency-cache 存储缓存资源依赖信息的目录名称
    dependencyCacheDir File(只读) buildDir/dependencyCacheDirName 存储缓存资源依赖信息的目录

    其它属性

    属性名称 类型 默认值 描述
    sourceSets SourceSetContainer (只读) Not null 包含工程的资源集合(source sets.)
    sourceCompatibility JavaVersion,也可以使用字符串或数字,比如 '1.5' 或者 1.5 根据使用的JVM定 编译java文件时指定使用的java版本
    targetCompatibility JavaVersion,也可以使用字符串或数字,比如 '1.5' 或者 1.5 sourceCompatibility 生成classes的java版本
    archivesBaseName String projectName 作为归档文件的默认名称,如JAR或者ZIP文件的名称
    manifest Manifest 空的Manifest 所有JAR包的Manifest文件

    Java 插件中的任务和属性详讲

    source sets 属性介绍

    我们可以使用 sourceSets 属性来访问工程的资源集合,它是 SourceSetContainer 类形的容器。我们还可以使用 sourceSets{ } 这样的代码块,它可以通过闭包来设置资源集合( source set )容器。

    首先如何访问资源集合呢?我们可以通过如下展示的几种方式来访问,代码示例如下:

    apply plugin:'java' 
    
    // 几种访问main资源集合的方式
    println sourceSets.main.output.classesDir // 1
    println sourceSets['main'].output.classesDir // 2
    
    sourceSets {
        println main.output.classesDir // 3
    }
    
    sourceSets {
        main {
            println output.classesDir // 4
        }
    }
    
    // 遍历资源集合
    sourceSets.all {
        println name // 5
    }
    

    任意执行一个命令,比如执行gradle tasks输出结果如下:

    /Users/bill/multiprojects/build/classes/main // 1
    /Users/bill/multiprojects/build/classes/main // 2
    /Users/bill/multiprojects/build/classes/main // 3
    /Users/bill/multiprojects/build/classes/main // 4
    main // 5
    test // 5
    

    同样,我们也可以使用上面的方法来修改默认属性值,示例代码如下:

    sourceSets {
        main {
            java {
                srcDirs = ['src/java']
            }
            resources {
                srcDirs = ['src/resources']
            }
        }
    }
    

    下表中列出了资源集合中重要的属性,更多的可以参照官网 SourceSet

    属性名称 类型 默认值 描述
    name String(只读) Not null 资源集合的名称,用来辨别它
    output SourceSetOutput(只读) Not null 资源集合的输出文件,它包括编译后的classes和resources
    output.classesDir File buildDir/classes/name 生成classes资源的目录
    output.resourcesDir File buildDir/resources/name 生成resources资源的目录
    compileClasspath FileCollection compileSourceSet的配置 当编译资源的时候使用的类路径地址
    runtimeClasspath FileCollection output + runtimeSourceSet的配置 执行classes文件的类路径地址
    java SourceDirectorySet(只读) Not null Java源文件的目录集合,它仅仅包括.java文件,其它所有的文件都被排除了。
    java.srcDirs Set<File> [projectDir/src/name/java] 指定包含java源代码的目录
    resources SourceDirectorySet(只读) Not null 资源resources目录集合,它仅仅包含资源文件,其它任务.java文件将会被排除掉。
    resources.srcDirs Set<File> [projectDir/src/name/resources] 指定包含资源的目录
    allJava SourceDirectorySet(只读) java 所有的.java文件的集合
    allSource SourceDirectorySet(只读) resources + java 所有资源文件的集合,它包含了.java文件集合和resource资源文件集合。

    定义一个新的资源集合( source set )

    使用 sourceSets{ } 代码块来定义新的资源集合,代码如下:

    sourceSets {
        intTest
    }
    

    当我们定义新的资源集合时,Java 插件会为该新资源集合添加相关依赖配置任务,具体见“第二步,Java 插件的任务”。

    我们可以使用这些配置去定义 compile 和 runtime 的依赖,示例代码如下:

    sourceSets {
        intTest
    }
    
    dependencies {
        intTestCompile 'junit:junit:4.12'
        intTestRuntime 'org.ow2.asm:asm-all:4.0'
    }
    

    Java 插件同时还会为资源集合添加组装类的任务,具体见“第二步,Java 插件的任务”。例如,我们新定义的资源集合名为 intTest,所以我们可以使用命令gradle intTestClasses来编译该资源类,其执行结果如下:

    $ gradle intTestClasses
    :compileIntTestJava
    :processIntTestResources
    :intTestClasses
    
    BUILD SUCCESSFUL
    
    Total time: 1 secs
    

    接下来介绍一些资源集合其它的例子:

    // 为资源集合组装jar包
    task intTestJar(type: Jar) {
        from sourceSets.intTest.output
    }
    
    // 为资源集合生成Javadoc帮忙文档
    task intTestJavadoc(type: Javadoc) {
        source sourceSets.intTest.allJava
    }
    
    // 为资源集合进行单元测试
    task intTest(type: Test) {
        testClassesDir = sourceSets.intTest.output.classesDir
        classpath = sourceSets.intTest.runtimeClasspath
    }
    

    重要的几个任务介绍

    • Javadoc 任务
    任务属性 类型 默认值
    classpath FileCollection sourceSets.main.output + sourceSets.main.compileClasspath
    source FileTree sourceSets.main.allJava
    destinationDir File docsDir/javadoc
    title String 工程的名称和版本号
    • Clean 任务
    任务属性 类型 默认值
    dir File buildDir
    * Resources 任务
    任务属性 类型 默认值
    ------ ------- -------
    srcDirs Object sourceSet.resources
    destinationDir File sourceSet.output.resourcesDir
    * CompileJava 任务
    任务属性 类型 默认值
    ------ ------- -------
    classpath FileCollection sourceSet.compileClasspath
    source FileTree sourceSet.java
    destinationDir File sourceSet.output.classesDir
    * Jar 任务
    它会把工程的 class 文件和 resources 文件打包成一个 Jar 文件。每一个 jar 或 war 文件都会包含一个 manifest 属性,当打包时会同时生成一个相应的 MANIFEST.MF 文件。我们可以自定义 MANIFEST.MF,示例代码如下:
    jar {
        manifest {
            attributes("Implementation-Title": "Gradle",
                       "Implementation-Version": version)
        }
    }
    

    单元测试介绍

    测试( test )任务能够自动检测并执行测试资源集合中所有的单元测试类,当测试执行完成后会生成测试报告,目前支持 JUnit 和 TestNG。

    当使用 JUnit3 或 JUnit4 时,任务能自动检测到以下几种情况的单元测试。

    • 继承自 TestCase 或 GroovyTestCase 的类
    • 类或者父类上有@RunWith注解的类
    • 类或父类中包含的方法上有@Test注解的类

    如果使用的是 TestNG 时,会自动扫描方法上有@Test注解的类。

    而 Gradle 默认是使用的 JUnit 测试,我们可通过指定使用 TestNG 测试,代码如下:

    test {  
        useTestNG()  
    }
    

    接下来我们可以实现分组测试,首先需要在单元测试方法上使用 groups 指定分组,代码如下:

    public class GroupTest {  
        @BeforeClass  
        public void setUp() {  
            System.out.println("setUp");  
        }  
    
        @Test(groups = { "groupA" })  
        public void groupATest() {  
            System.out.println("group A test");  
        }  
    
        @Test(groups = { "groupB" })  
        public void groupBTest() {  
            System.out.println("group B test");  
        }  
    }  
    

    然后在 test 任务中指定执行哪一组单元测试,代码如下:

    test {  
        useTestNG{  
            includeGroups 'groupA'  
        } 
    } 
    

    测试完成后可以生成以下三种方式的报告。

    • HTML 格式的测试报告
    • XML 格式的测试报告,可以结合 CI 工具使用
    • 可以生成二进制格式的测试报告

    具体的示例代码如下:

    subprojects {
        apply plugin: 'java'
    
        // 禁用了测试任务独立生成测试报告
        test {
            reports.html.enabled = false
        }
    }
    
    task testReport(type: TestReport) {
        destinationDir = file("$buildDir/reports/allTests")
        // 包括了子项目中的测试报告结果
        reportOn subprojects*.test
    }
    

    在上面示例代码中,我们使用自定义的 testReport 任务可以把多个子项目的测试报告整合拷贝到指定目录输出。

    小结

    在本章中我们详细介绍了 Java 插件的使用方法,首先通过五步聚完成了 Java 插件的基本用法,然后再重点介绍了资源集合( source set )、几个重要的任务和单元测试等内容。

    相关文章

      网友评论

          本文标题:Gradle第13课:Gradle 中常用插件的介绍-下

          本文链接:https://www.haomeiwen.com/subject/yrjfwftx.html