Gradle初探

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gradle初探相关的知识,希望对你有一定的参考价值。

(一):创建一个Gradle项目

1. 环境准备

1.1. 先上Gradle官网下载最新版的程序,地址:https://gradle.org/gradle-download/

1.2. 配置环境变量

GRADLE_HOME:值为gradle根目录路径,并在PATH中添加 "%GRADLE_HOME%\bin"

1.3. 配置IDE工具的Gradle环境

这里我使用IDEA进行创建(eclipse应该也有对应的gradle插件)。

首先在IDEA的settings中找到Gradle选项,配置gradle home路径。

技术分享
图1.3 在IDEA中配置Gradle

2. 创建Gradle项目

在当前Project中(可以当做eclipse中的workspace),创建一个gradle的java项目。并和Maven项目一样需要设置项目的GroupId、ArtifactId和Version。如下图所示:

技术分享
图2.1 创建一个Gradle的JAVA项目
技术分享
图2.2 设置项目GroupId、ArtifactId和Version
技术分享
图2.3 gradle相关设置
技术分享
图2.4 定义项目所在物理路径的文件夹名称

点击"Finish",gralde-demo项目就创建好了。

技术分享
图2.5

但是idea又抽风了,我明明勾了自动创建空文件夹,但结果还是得自己动手。。。

Gradle的文件结构和Maven基本一致:

src/main/java:存放java代码;

src/main/resources:存放资源和配置文件;

src/test/java:存放测试用的java代码;

src/test/resources:存放测试用的资源和配置文件;

src/main/webapp:存放WEB的代码和资源(如果是web项目的话需要);

手动创建完成后的结构如图所示:

技术分享
图2.6 目录结构

那这个创建的项目究竟能不能用呢,现在我们写一个很单纯的代码,代码如下:

 

下面可以使用IDEA内建的gradle命令工具执行一下,gradle的build命令,看看能否构建成功。

技术分享
图2.7 执行build命令构建项目

"BUILD SUCCESSFUL" 看来是成功了。项目目录下多了build文件夹,在libs中已经有了打包好的jar文件。

和Maven的pom.xml一样,Gradle可以这么构建出项目也是有着自己的构建配置文件。

下面我们就打开build.gradle文件看看这里面究竟写了啥。

 

 

(二):build.gradle常用配置(java和web项目)

 

3. 常用配置(针对JAVA和WEB项目)

 

打开build.gradle文件,由于是IDEA创建的,所以里面已经有了一些内容。

技术分享
图3.1

group和version分别为项目的所在组和版本信息。和Maven类似,而artifactId在gradle则是项目的name,值保存在settings.gradle文件的rootProject.name中。

针对java项目和web项目,根据官方文档,我将build.gradle进行了如下修改,如图所示:

技术分享
图3.2

 

apply plugin: ‘java‘//添加Java插件

apply plugin :‘maven‘//添加Maven插件

添加Java和Maven插件,可以使用两者的相关配置。


sourceCompatibility=1.7

targetCompatibility =1.7

分别指定开发环境和编译使用的JDK版本。根据Maven项目经验,在不同IDE间导入Maven项目时,经常会出错,通过指定JDK可以有效解决此问题,故保险起见,这里也加上。


task createJavadoc(type: Javadoc)  {

      source = sourceSets.main.allJava

}

配置了这个任务后,执行gradle的javadoc命令,可以自动生产javaDoc文档。前提当然你自己有给类和方法按规范添加注解。


tasks.withType(JavaCompile) {

        options.encoding ="UTF-8"

}

设置编码为UTF-8,如果不设置,则注释有中文等情况时,生成javaDoc会出现乱码,并且执行build命令时会出现警告和错误。


repositories {

      mavenLocal()//添加Maven本地资源库

      mavenCentral()//添加Maven中央资源库

}

配置获取资源的资源库

mavenLocal()表示会从本地获取资源,获取资源的顺序为

%USER_HOME%/.m2/settings.xml中指定的路径 > 

%M2_HOME%/conf/settings.xml中指定的路径 >

 %USER_HOME%/.m2/repository。

注:这里发现一个BUG,按照官方文档说,如果系统用户文件夹下的.m2中不存在settings.xml文件会自动去找%M2_HOME%的settings.xml文件,实际却不会,然后直接指向了%USER_HOME%/.m2/repository。建议自定义maven本地库的,把%M2_HOME%的settings.xml文件COPY一份到%USER_HOME%/.m2目录下即可。


mavenCentral()表示会从Maven中央库获取数据。

除这2种,gradle还可以从指定的URL获取资源,比如:

repositories {

    maven {

        url"http://127.0.0.1:8081/nexus/content/repositories/"

    }

     mavenLocal()//添加Maven本地资源库

     mavenCentral()//添加Maven中央资源库

}

这里除了本地和中央库,还会从我本地的Maven私服中获取资源。


dependencies {

     testCompile ‘junit:junit:4.12‘//添加单元测试

     testCompile ‘org.springframework:spring-test:4.2.5.RELEASE‘// Spring测试支持

     compile ‘org.springframework:spring-context:4.2.5.RELEASE‘

}

添加依赖包,和Maven类似。上面我采用的是简写语法,还有一种是完整的写法,如下:

testCompile group:‘junit‘, name:‘junit‘, version:‘4.12‘

和Maven类似,gradle导入依赖包也可以定义其作用的生命周期:

compile:编译时必须。

runtime:运行时必须,包括编译时。

testCompile:测试编译时必须。

testRuntime:测试运行时必须,包括编译时。

注:此外配置依赖包,还可以模块化配置、导入list、配置是否传递等。还没细看。

以上这些已经可以支撑平常的java或web项目开发了。接下来还有一个问题,项目开发时,经常会模块化开发,有时候有些jar可以复用,或者项目需要按不同版本(SNAPSHOT/RELEASE等)发布到Maven私服中,下面就说说如何发布项目到Maven私服等资源库中。

 

(三):发布项目到Nexus资源库

 

4. 发布项目

在公司开发中,如果采取Maven这种项目构建方式的,一般都会架设一个Nexus Maven私服在公司服务器上,一些公司积累的资源组件和中央库没有提供的资源,以及一些项目都会发布到私服中,然后开发人员可以通过Maven在具体开发时导入内部资源。那么既然现在要用gradle替换Maven,那么这个需求则需要满足,通过查看官方文档,可以通过引入‘maven-publish‘实现。具体添加的配置如下:

.......

apply plugin: ‘maven-publish‘//添加Maven发布插件

.......

//上传资源配置

uploadArchives {

     repositories {

        mavenDeployer {

           //上传资源到Maven私服

            repository(url: "http://localhost:8081/nexus/content/repositories/releases/") {

                authentication(userName:"admin",password:"admin123")

            }

        pom.version ="$project.version"

        pom.artifactId ="$project.name"

        pom.groupId ="$project.group"

     }

   }

}

通过添加以上配置,通过upload命令,已经可以把项目发布到我的本地私服http://localhost:8081/nexus/content/repositories/releases/中。但是问题又来了,这里我只能把项目发布到本地的releases库中,但是如果我这个项目还是dev版或者snapshot版怎么办?

这里就是体现gradle构建方式比maven灵活的地方。整个build.gradle文件其实就是一段groovy语言的代码。说到这里大家就都懂了吧,根据不同版本发布到不同的库,这不就是一个条件判断的事嘛。

将url提取为变量,加入相关判断代码,如下:

//默认发布到Maven Nexus私服的发行库

def nexusUrl ="http://localhost:8081/nexus/content/repositories/releases/"

//如果为快照版本发布到Maven Nexus私服的快照库

if(version.endsWith("-SNAPSHOT")) {

     nexusUrl ="http://localhost:8081/nexus/content/repositories/snapshots/"

}

......

uploadArchives {

......

        //上传资源到Maven私服

      repository(url: nexusUrl) {

             authentication(userName:"admin",password:"admin123")

       }

......

}

好了,现在所有版本号为"-SNAPSHOT"的都会被发布到快照库,而其他的则会发布到发行库,现在执行下upload看下效果吧。。。。

技术分享
图4.1 upload命令执行结果
技术分享
图4.2 Nexus
技术分享
图4.3 资源详情

另外,在引入了‘maven-publish‘后,如果配置了mavenLocal(),在upload时也会把资源提交到本地Maven资源库中。

技术分享
图4.4 本地资源库

总结

几个小时的试玩,说明不了什么问题,但是gradle的灵活性确实还是让我印象深刻,非常能体现它约定优于配置的原则。但是如果要玩转它还需要学习一定的groovy语言。和程序猿都了解XML相比,这里有个时间成本。并且由于非常灵活,而很有可能出现配置的混乱,但是总体还是觉得利大于弊。写腻了配置XML的方式,在配置里写代码,想着都有趣。。。

 

(四):3.x新版本发布资源的方式

 

说来惭愧,敲代码这么多年都没写半篇文章,本来想着好好写一回笔记,结果因为工作繁忙、生活琐事又落下了(其实是笔者范懒 >_<!)。这下“初探”这词是没法用了,想着就是写写平常使用时的心得,就改叫“日常”吧。

??扯了扯闲话,言归正传。公司要开发一个框架型的项目,本来想用Maven的,我想着之前写过一个多项目的Gradle配置就拿来直接用了。由于强迫症又发了,上官网下个新版本,结果发现3.1版本的文档里多了以下两篇:

34. Ivy Publishing (new)
35. Maven Publishing (new)

lvy 暂时没用过,不提。这里写一下使用Gradle发布资源到 Maven 仓库的方式,在新版本中Gradle在“maven-publish”插件中增加了发布的功能,用来取代旧版本中Task的方式(旧版本发布方式详见上一篇:Gradle初探(三):发布项目到Nexus资源库)。官方文档原文如下:

This chapter describes the new incubating Maven publishing support provided by the “maven-publish” plugin. Eventually this new publishing support will replace publishing via the Upload task.
If you are looking for documentation on the original Maven publishing support using the Upload task please see Chapter 31, Publishing artifacts.

1. 创建项目以新版本的方式发布

创建一个Gradle项目(以多项目Gradle为例)

build.gradle文件内容:

group ‘z99‘ version ‘1.0-SNAPSHOT‘ subprojects { group ‘z99‘ version ‘1.0-SNAPSHOT‘ // 引用的插件 apply plugin: ‘java‘ apply plugin: ‘maven‘ apply plugin: ‘maven-publish‘ // 编译环境 sourceCompatibility = jdkVer targetCompatibility = jdkVer // 字符集 tasks.withType(JavaCompile) { options.encoding = encoding } // 资源库 repositories { mavenLocal() maven { // 啊哈,配上阿里云的资源库,速度杠杠的 url "http://maven.aliyun.com/nexus/content/groups/public/" } jcenter() mavenCentral() } // 依赖 dependencies { testCompile group: ‘junit‘, name: ‘junit‘, version: junitVer compile group: ‘org.slf4j‘, name: ‘slf4j-log4j12‘, version: slf4jLog4j12Ver // 添加 libs 文件夹下的 jar compile fileTree(dir: ‘libs‘, include: [‘*.jar‘]) } // 打包 publishing { publications { mavenJava(MavenPublication) { from components.java } } } // 如果是发行版本,则上传到发行库。否则上传到快照库。 def postfixUrl = "repository/maven-snapshots" if (project.version.endsWith("-RELEASE")) { postfixUrl = "repository/maven-releases" } // 发布到本地Maven库和远程Maven服务器 publishing { repositories { mavenLocal() maven { credentials { username ossUserName password ossPwd } url "$ossHost/$postfixUrl/" } } } }

gradle.properties文件内容:

\# 基本信息配置 jdkVer=1.8 encoding=UTF-8 \# 资源库配置 ossRepoUrl=http://127.0.0.1:9001/repository/maven-public/ \# 用于上传的资源库配置 ossHost=http://127.0.0.1:9001 ossUserName=admin ossPwd=admin123 \# 依赖包版本配置 junitVer=4.12 slf4jLog4j12Ver=1.7.21 servletApiVer=3.1.0

settings.gradle文件内容:

rootProject.name = ‘gradle-demo‘ include ‘sub-a‘, ‘sub-b‘

build之后,文件结构如下:

技术分享
QQ图片20161027000602.png
技术分享
QQ图片20161027000556.png

之后执行“publish”命令,则可以将两个子项目分别都发布到maven私服和本地maven资源库中。

命令执行控制台输出:

技术分享
QQ图片20161027003023.png

Maven私服库:

技术分享
QQ图片20161027003132.png

Maven本地库:

技术分享
QQ图片20161027003211.png

2. 子项目单独配置时的发布

写到这里,其实流程和旧版用Task的步骤差不多,但是这是在多项目中,各版本用统一的版本号发布的情况,但实际开发中主项目下各子模块项目的版本号不可能一致,之前旧版时,这种情况下就会出现一个比较难受的写法,如下:

为了主配置文件简洁,我引入一个subprojects.gradle文件来专门写子模块的部分。
subprojects.gradle文件具体内容如下:

project(‘:sub-a‘) { version ‘1.0-SNAPSHOT‘ } project(‘:sub-b‘) { version ‘2.0-SNAPSHOT‘ }

然后再build.gradle中,去掉子项目的版本配置,在文件尾部加上

apply from: ‘subprojects.gradle‘

即可。

用旧版本的方式发布一下看看:

首先修改build.gradle,注释掉publish的部分,加上upload的代码:

// 打包 /*publishing { publications { mavenJava(MavenPublication) { from components.java } } }*/ // 如果是发行版本,则上传到发行库。否则上传到快照库。 def postfixUrl = "repository/maven-snapshots" if (project.version.endsWith("-RELEASE")) { postfixUrl = "repository/maven-releases" } // 发布到本地Maven库和远程Maven服务器 /*publishing { repositories { mavenLocal() maven { credentials { username ossUserName password ossPwd } url "$ossHost/$postfixUrl/" } } }*/ uploadArchives.repositories.mavenDeployer { repository(url: "$ossHost/$postfixUrl/") { authentication(userName: ossUserName, password: ossPwd) } pom.version = project.version pom.artifactId = project.name pom.groupId = project.group }

然后执行“upload”(注意:不是3.x版本的“publish”)命令执行发布,结果如下:

技术分享
Paste_Image.png

纳尼,发生了什么?这就是旧版本的问题所在了,通过截图可以知道版本号的位置变成了“unspecified”,也就是说“pom.version = project.version”时拿不到版本号的信息,这原因就在于旧版本中upload的配置是作为一个task进行配置,而在主配置文件中,我是先配置了upload,才引用了子项目的配置文件,因此,要想配置生效则只能改为:

subprojects {
// 之前的其他配置
}
apply from: ‘subprojects.gradle‘
subprojects {
// upload的配置
}

如此才能正常上传发布(这里就不演示了),这写法对于代码强迫症重症患者简直不能忍啊,所以一度有想换回Maven的念头。直到发现了新版本中的publish之后。
那么新版本的中,只需在原主配置的末尾加上‘apply from: ‘subprojects.gradle‘‘即可。发布后控制台显示成功,如下图所示:

技术分享
Paste_Image.png

3. 子项目包含jar、war等不同打包方式时的发布方法

一般子项目中也存在既有纯java的项目,也有web项目的情况。在例子中,比如把子项目2改为web项目,现在做下列的修改。

subprojects.gradle文件内容:

project(‘:sub-a‘) { version ‘1.0-SNAPSHOT‘ // 打包 publishing { publications { mavenJava(MavenPublication) { from components.java } } } } project(‘:sub-b‘) { version ‘2.0-SNAPSHOT‘ apply plugin: ‘war‘ dependencies { providedCompile group: ‘javax.servlet‘, name: ‘javax.servlet-api‘, version: servletApiVer } publishing { publications { mavenJava(MavenPublication) { from components.web } } } }

build.gradle文件内容:

group ‘z99‘ version ‘1.0-SNAPSHOT‘ subprojects { group ‘z99‘ // 引用的插件 apply plugin: ‘java‘ apply plugin: ‘maven‘ apply plugin: ‘maven-publish‘ // 编译环境 sourceCompatibility = jdkVer targetCompatibility = jdkVer // 字符集 tasks.withType(JavaCompile) { options.encoding = encoding } // 资源库 repositories { mavenLocal() maven { // 啊哈,配上阿里云的资源库,速度杠杠的 url "http://maven.aliyun.com/nexus/content/groups/public/" } jcenter() mavenCentral() } // 依赖 dependencies { testCompile group: ‘junit‘, name: ‘junit‘, version: junitVer compile group: ‘org.slf4j‘, name: ‘slf4j-log4j12‘, version: slf4jLog4j12Ver // 添加 libs 文件夹下的 jar compile fileTree(dir: ‘libs‘, include: [‘*.jar‘]) } // 如果是发行版本,则上传到发行库。否则上传到快照库。 def postfixUrl = "repository/maven-snapshots" if (project.version.endsWith("-RELEASE")) { postfixUrl = "repository/maven-releases" } // 发布到本地Maven库和远程Maven服务器 publishing { repositories { mavenLocal() maven { credentials { username ossUserName password ossPwd } url "$ossHost/$postfixUrl/" } } } } // 引入子项目的配置 apply from: ‘subprojects.gradle‘

执行结果,如下图:

技术分享
Paste_Image.png

要点就是一个是“from components.java”,另一个是“from components.web”,目前3.1版官方貌似只给了这两种。
有一点要注意的是publishing这个配置不能覆盖(或者是我没找到方法),我一开始是没有删去打包java的publishing配置,想直接在war的独立配置里直接配一个打包为war的publishing配置,结果报错,说是不能配置多个components。目前尚未找到解决方案,先这么着吧。

有点犯困了,后面写的有点草率。今天就这样吧,明天还得加班 >_<!。引用一句老婆常说的话结尾吧:

哎,苦逼的程序猿。。。

转载自:http://www.jianshu.com/u/c69205324efe

































以上是关于Gradle初探的主要内容,如果未能解决你的问题,请参考以下文章

HarmonyOS初探04——使用DevEco Studio时设置Gradle仓库镜像

HarmonyOS初探04——使用DevEco Studio时设置Gradle仓库镜像

HarmonyOS初探04——使用DevEco Studio时设置Gradle仓库镜像

Gradle初探:发布项目到Nexus资源库

初探JSP与LEeclipse

Bugly热更新——初探