Java构建工具:Maven与Gradle的对比

野性酷女 2022-05-30 02:28 345阅读 0赞

由Xander发表在天码营

在Java码农的世界里,构建工具一直是一个不可或缺的元素。一开始,世上是只有一个构建工具的那就是Make后来发展为GNU Make。但是由于需求的不断涌现,这个小圈子里又逐渐衍生出其他千奇百怪的构建工具。

在这个小圈子中影响力最大的角色莫过于Maven了。它使用XML作为配置文件,改进了前辈Ant的复杂的构建配置,提供了一些现成的目标,而不需要我们一个个的将构建任务的每个命令一一列出。另外它提供了一个杀手锏功能,那就是依赖管理,它通过简单的配置就可以自动从网络上下载项目所需的依赖,这革命性的改变了我们开发软件的方式。可以想象,如果你是一个大型软件开发项目组的成员,如果使用代码仓库管理依赖jar包会令仓库变得多么庞大!Maven的制品仓库设计实现了制品与代码间的解耦,为基于制品的协作提供了可能。

可是软件行业新旧交替的速度之快往往令人咋舌,不用多少时间,你就会发现曾经大红大紫的技术已经成了昨日黄花。在Java构建领域,我们能够看到一些新兴的工具在涌现。比如基于Groovy的Gradle。Hibernate就将自己的项目从Maven迁移到了Gradle,Google官方Android开发的IDE Android Studio也默认使用了Gradle进行构建。这些事件令Gradle吸引了不少眼球。Gradle真的要替代Maven了么?当然没有,Maven在如今仍然是Java构建技术的事实标准。Gradle也仍然使用了Maven的制品库来做依赖管理。但是从Gradle身上,我们确实看到了进步。简洁的Groovy语法和灵活的配置令我们眼前一亮。

那Maven和Gradle到底有何不同呢?就请读者和我一起探寻吧。

安装

在安装上两者大同小易。我们都需要从官网下载解压到本地目录。配置好MAVEN_HOME或Gradle_Home环境变量,并加入PATH环境变量中。我们就可以在命令行中使用maven和gradle了。

主流的Java IDE: Eclipse可以安装Maven和Gradle的插件。Intellij有内置的Gradle和Maven可以使用。

二者均有详尽的文档供用户参考。别看gradle是个新来的小子,它的文档也是有70章,500多页的内容的!

在这里附上Maven和Gradle的下载地址:

  • maven: Maven – Welcome to Apache Maven
  • gradle: https://gradle.org

依赖管理

Maven的配置文件是.pom文件。POM是项目对象模型(Project Object Model)的简称,它是Maven项目中的文件,使用XML表示。其中包含项目的基本信息,构建过程,环境信息,依赖信息等。我们可以看下面这个简单的例子:

  1. <project xmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.vs</groupId>
  7. <artifactId>com.vs.maven.gradle</artifactId>
  8. <version>1.0</version>
  9. <parent>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-parent</artifactId>
  12. <version>1.2.6.RELEASE</version>
  13. </parent>
  14. <dependencies>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-starter-web</artifactId>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework.boot</groupId>
  21. <artifactId>spring-boot-starter-security</artifactId>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework.boot</groupId>
  25. <artifactId>spring-boot-starter-data-jpa
  26. </artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>mysql</groupId>
  30. <artifactId>mysql-connector-java</artifactId>
  31. <version>5.1.25</version>
  32. </dependency>
  33. </dependencies>
  34. <properties>
  35. <java.version>1.8</java.version>
  36. </properties>
  37. <build>
  38. <plugins>
  39. <plugin>
  40. <groupId>org.springframework.boot</groupId>
  41. <artifactId>spring-boot-maven-plugin</artifactId>
  42. </plugin>
  43. </plugins>
  44. </build>
  45. </project>

这个例子构建了一个简单的spring-boot项目, 最开始定义了一些项目的基本信息,包括组名、制品名、版本等。parent标签表示我们继承了一个spring定义的一个制品的配置,这样我们不需要配置很多依赖的版本就可以引入依赖。dependencies标签间配置该项目所依赖的其他制品,分别配置每个依赖制品的groupId, artifactId和version。当我们执行mvn insall时,maven就会自动下载依赖,并帮我们将它编译打包放入本地仓库之中。我们就可以在用户目录下的.m2文件夹中找到我们的制品。

那如果我们使用Gradle来构建这个项目,我们该如何做呢?

  1. buildscript {
  2. repositories {
  3. mavenCentral()
  4. }
  5. dependencies {
  6. classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE")
  7. }
  8. }
  9. dependencies {
  10. compile("org.springframework.boot:spring-boot-starter-web") {
  11. exclude module: "spring-boot-starter-tomcat"
  12. }
  13. compile("org.springframework.boot:spring-boot-starter-security")
  14. compile("org.springframework.boot:spring-boot-starter-data-jpa")
  15. testCompile("mysql:mysql-connector-java:5.1.25")
  16. }

咦?冗长的代码怎么突然少了这么多?^?

仔细阅读下你会发现,原来是依赖管理所需的配置长度变短了。在pom.xml中我们需要引入一个依赖时需要将它的groupId, artifactId和version都用标签引起来。但是在build.gradle中你会发现,仅仅需要将三者的value用:连起来,并”调用compile函数”就可以啦。

比如,我们要引用spring-boot的starter-security,maven的配置是这样写的:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-security</artifactId>
  5. </dependency>
  6. </dependencies>

在gradle中的配置却是这样的:

  1. dependencies {
  2. compile("org.springframework.boot:spring-boot-starter-security")
  3. }

觉得怎么样?我反正感觉和写代码一样清爽!Gradle使用了groovy作为它的DSL,非常的易用。如果你使用了很久的Maven,你也许会发现Gradle的配置写起来实在是太爽了!

构建生命周期管理

除了依赖管理以外,构建工具的另一个主要用途就是构建的生命周期管理。

Maven有三个生命周期,每个生命周期又分为多个阶段:

  1. Clean:包含3个阶段,与清理上次构建生成的文件相关
  2. Default:Maven的核心生命周期,包含多个阶段如预处理、编译、测试、打包、安装到本地仓库、发布到远程仓库等。
  3. Site: 包含4个阶段,与生成项目报告,站点,发布站点相关。

这些生命周期都是系统自定义好的,如果我们需要修改现有的构建生命周期的话,我们就要编写一个Maven插件。因为Maven是通过插件发来完成大多数的构建任务。每个插件可以绑定一个生命周期。配置好绑定生命周期后,我们需要定义插件的任务,在Maven中每个任务的goal称作Mojo,每个Mojo我们都需要实现org.apache.maven.plugin.Mojo接口。也就是我们需要定义一个类来实现这个接口。使用时我们需要引入这个插件,并配置需要执行的goal。

比如我们要完成输出Hello world这个需求的话,我们需要:

  1. 新建GreeingMojo类:

    package sample.plugin;

    import org.apache.maven.plugin.AbstractMojo;
    import org.apache.maven.plugin.MojoExecutionException;
    import org.apache.maven.plugins.annotations.Mojo;

    /**

    • Says “Hi” to the user.
      /
      @Mojo( name = “sayhi”)
      public class GreetingMojo extends AbstractMojo
      {
      public void execute() throws MojoExecutionException
      {
      1. getLog().info( "Hello, world." );
      }
      }
  2. 定义pom文件:


    4.0.0

    sample.plugin
    hello-maven-plugin
    1.0-SNAPSHOT
    maven-plugin

    Sample Parameter-less Maven Plugin



    org.apache.maven
    maven-plugin-api
    2.0




    org.apache.maven.plugin-tools
    maven-plugin-annotations
    3.4
    provided


  3. 在项目pom文件目录运行install命令将插件安装到本地仓库

  4. 在使用插件的项目加入配置:




    sample.plugin
    hello-maven-plugin
    1.0-SNAPSHOT


  5. 执行:

    mvn groupId:artifactId:version:goal

即可完成Hello,world的输出。

那么在Gradle中我们该怎么做呢?Gradle中有一个基本概念叫Task,我们可以使用Task来完成这个需求:

  1. task hello << {
  2. println "hello world"
  3. }

执行Gradle hello,即可完成Hello, World的输出。是不是很简单?像写代码一样~

当然实际工程我们要完成的构建任务不仅仅是输出一个info这么简单,我们很可能会去做一些其他复杂的操作,比如初始化文件、数据库,检测系统环境等等。但由于Gradle使用了Groovy作为配置文件,在使用时会比Maven的xml配置灵活许多,更适合我们码农进行使用。

制品发布

在制品发布这个操作上,Maven要扳回一局。Maven原生支持maven jar的格式,发布很简单;而Gradle虽说既支持Maven又支持Gradle,但是就要我们自己做很多额外的工作。比如Maven要发布制品,只需要配置远程仓库的参数:

  1. <distributionManagement>
  2. <repository>
  3. <id>internal</id>
  4. <name>Internal Release Repository</name>
  5. <url>http://repository.springsource.com/maven/bundles/release</url>
  6. </repository>
  7. </distributionManagement>

而gradle发布制品,还需要生成pom文件:

  1. uploadArchives {
  2. repositories {
  3. mavenDeployer {
  4. //为Pom文件做数字签名
  5. beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
  6. repository(url: "http://repository.springsource.com/maven/bundles/release") {
  7. authentication(userName: username, password: password)
  8. }
  9. //构造项目的Pom文件
  10. pom.project {
  11. name project.name
  12. packaging 'jar'
  13. description 'description'
  14. }
  15. }
  16. }
  17. }

总结

因为时间关系,简单介绍了这么多,可能读者也对Gradle与Maven的差别有了一些了解。Gradle与Maven相比更为灵活,简单。但是Maven相比于Gradle的不灵活,是否也是它的优点呢?这就需要读者在工程中自己进行思考了。

除此之外Gradle的官方网站专门给出了一个专栏来讲Gradle与Maven的区别: Maven vs Gradle: Feature Comparison。

有耐心的读者可以看看这些对比。如果说你要说我没耐心看完这些,只想快点挑个构建工作开始我的项目! 那么我要说的是:Just have a try! Maven和Gradle都是非常优秀的构建工具,增加二者的使用经验不是一个很亏的事情。当然如果你要开发Android应用的话,还是推荐你使用Gradle做构建工具,因为Google官方推的Android Studio就使用了Gradle作为原生构建工具,这使得Gradle对Android各版本软件的构建支持得更好一些。其他项目的话,二者选其一吧~

欢迎关注天码营微信公众号: TMY-EDU

小编重点推荐:

Spring MVC实战入门训练

Spring Data JPA实战入门训练

Java Web实战训练

Node.js全栈开发

更多精彩内容请访问 天码营网站

发表评论

表情:
评论列表 (有 0 条评论,345人围观)

还没有评论,来说两句吧...

相关阅读

    相关 gradlemaven对比

    Gradle作为一款基于Groovy语言的构建工具,已经吸引众多的ant,maven使用者转投gradle的怀抱,和Gradle相比,ant显得冗余复杂,maven显得有些死板

    相关 MavenGradle对比

    因为最近在学习这Maven和Gradle的使用,就搜寻了一些资料,这是我看到的一篇比较好的关于Maven和Gradle作对比的资料,很详细也很易懂。因此想通过CSDN保存下来,