天天看點

Maven和Gradle差別

分享知識 傳遞快樂

Java中主要有三大建構工具:Ant、Maven和Gradle。Ant用的比較少、Maven用的相對普遍,而Gradle的發展則将是未來的一種趨勢。使用Maven需要有pom.xml檔案,使用Gradle需要有一個對應的build.gradle檔案。

依賴管理系統

Maven中用groupId、artifactId、version組成的Coordination(坐标)唯一辨別一個依賴。任何基于Maven建構的項目自身也必須定義這三項屬性,生成的包可以是Jar包,也可以是war包。一個典型的依賴引用如下所示:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
</dependency>      

從上面可以看出當引用一個依賴時,version可以省略掉,這樣在擷取依賴時會選擇最新的版本。而存儲這些元件的倉庫有遠端倉庫和本地倉庫之分。遠端倉庫可以使用世界公用的central倉庫,也可以使用Apache Nexus自建私有倉庫;本地倉庫則在本地計算機上。通過Maven安裝目錄下的settings.xml檔案可以配置本地倉庫的路徑,以及采用的遠端倉庫的位址。

Gradle在設計的時候基本沿用了Maven的這套依賴管理體系。然後我将其轉換成Gradle腳本,結果是驚人,在引用依賴方面變得非常簡潔。

dependencies {
    compile 'org.hibernate:hibernate-core:3.6.7.Final'
    testCompile ‘junit: junit: 4. + '
}      

Maven和Gradle對依賴項的scope有所不同。在Maven世界中,一個依賴項有6種scope,分别是complie(預設)、provided、runtime、test、system、import。而grade将其簡化為了4種,compile、runtime、testCompile、testRuntime。

Gradle支援動态的版本依賴。在版本号後面使用+号的方式可以實作動态的版本管理。

Maven中央倉庫已經成為了Java開發者不可或缺的資源,Gradle既然有依賴管理,那必然也得用到倉庫,這當然也包括了Maven中央倉庫,就像這樣:

repositories {
    mavenLocal()
    mavenCentral()
    mavenRepo urls: "http://repository.sonatype.org/content/groups/forge/"
}      

多子產品建構

Maven将一個項目分解為多個子產品已經是很通用的一種方式,在Maven中需要定義個parent POM作為一組module的聚合POM。在該POM中可以使用<modules>标簽來定義一組子子產品。parent POM不會有什麼實際建構産出。而parent POM中的build配置以及依賴配置都會自動繼承給子module。

maven建立多子產品

maven父工程pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.xh</groupId>
  <artifactId>ssm</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>ssm</name>


  <modules>
    <module>ssm-mapper</module>
    <module>ssm-service</module>
    <module>ssm-web</module>
  </modules>

  <properties>
    <module.name>${project.artifactId}</module.name>
    <project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
    <spring.version>4.3.13.RELEASE</spring.version>
  </properties>

  <dependencies>
    <!-- spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    .......
  </dependencies>
</project>      

maven子工程pom.xml

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xh</groupId>
    <artifactId>ssm</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <groupId>com.xh.ssm.web</groupId>
  <artifactId>ssm-web</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>ssm-web Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <dependencies>
    <!-- 引入ssm-service項目,這樣項目ssm-web就可以調用ssm-service裡邊的類了 -->
    <dependency>
      <groupId>com.xh.ssm.service</groupId>
      <artifactId>ssm-service</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>
  </dependencies>

  <!-- 打包時把需要的xml檔案一塊打進去 -->
  <!-- 不配置以下内容,項目在tomcat下會報找不檔案等錯誤 -->
  <build>
    <finalName>${project.name}</finalName>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**</include>
        </includes>
        <filtering>true</filtering>
      </resource>
    </resources>
    <pluginManagement>
      <plugins>
        <!-- 編譯Java源碼,一般隻需設定編譯的jdk版本 -->
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.6.0</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <encoding>UTF-8</encoding>
            <testIncludes>
              <testInclude>none</testInclude>
            </testIncludes>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>      

而Gradle也支援多子產品建構。而在parent的build.gradle中可以使用allprojects和subprojects代碼塊來分别定義裡面的配置是應用于所有項目還是子項目。對于子子產品的定義是放置在setttings.gradle檔案中的。在gradle的設計當中,每個子產品都是Project的對象執行個體。而在parent build.gradle中通過allprojects或subprojects可以對這些對象進行各種操作。這無疑比Maven要靈活的多。

gradle建立多子產品

第一種:

1、建立多個獨立gradle項目

Maven和Gradle差別

2、編輯子產品gradle-api的settings.gradle檔案:

rootProject.name = 'gradle-api'

include ':gradle-core'
project(':gradle-core').projectDir = new File(settingsDir, '../gradle-core')      

3、編輯子產品gradle-api的build.gradle檔案:

apply plugin: "java" //Java的JDK
apply plugin: "eclipse" //eclipse項目插件
apply plugin: "war" //項目建構輸出war

repositories {
    // Use jcenter for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter()
}

dependencies {
   compile project(':gradle-core')
}      

4、完成後,執行 Gradle  -> Refresh Gradle Project

Maven和Gradle差別

5、結果

Maven和Gradle差別

第二種:

1.建立Java項目

Maven和Gradle差別

2.添加build.gradle、settings.gradle檔案

build.gradle

subprojects {
  apply plugin: "java" //Java的JDK

}      

settings.gradle

rootProject.name = 'gradle-parent'

include 'gradle-core'      

3、建立空檔案夾

Maven和Gradle差別

4、将項目轉換成Gradle項目

Maven和Gradle差別
Maven和Gradle差別

5、複制項目路徑,右擊gradle-parent,導入Gradle項目

Maven和Gradle差別

總的來說,gradle相比于maven有很大的靈活性,目前gradle的使用者越來越多。而由于maven之前處于主流,并且在某些方面maven較gradle還有一些優點,是以maven和gradle并存。在github上大多數優秀的開源項目會同時提供maven和gradle兩種添加依賴的方式。

繼續閱讀