主頁 > 後端開發 > 不好意思, Maven 該換了!

不好意思, Maven 該換了!

2022-09-15 06:25:10 後端開發

來源:https://www.toutiao.com/article/6824937779193971207/

相信使用Java的同學都用過Maven,這是一個非常經典好用的專案構建工具,但是如果你經常使用Maven,可能會發現Maven有一些地方用的讓人不太舒服:

  • 一來Maven的組態檔是XML格式的,假如你的專案依賴的包比較多,那么XML檔案就會變得非常非常長;
  • 二來XML檔案不太靈活,假如你需要在構建程序中添加一些自定義邏輯,搞起來非常麻煩;
  • 第三就是Maven非常的穩定,但是相對的就是對新版java支持不足,哪怕就是為了編譯java11,也需要更新內置的Maven插件,

如果你對Maven的這些缺點也有所感觸,準備嘗試其他的構建工具,那么你可以試試gradle,這是一個全新的java構建工具,解決了Maven的一些痛點,

如果你喜歡用 Maven,我博客還更新了更多 Maven 教程:https://www.javastack.cn/devtools/maven/

安裝gradle

最傳統的安裝方法就是去gradle官網下載二進制包,解壓,然后將路徑添加到環境變數中,如果你沒什么其他需求,可以使用這種安裝方式,但是,gradle是一個非常新潮的專案,每隔幾個月就會發布一個新版本,這種方式可能跟不上gradle的更新速度,

所以我更加推薦使用包管理器來安裝gradle,如果你使用linux系統,那么不必多說,如果你使用Windows系統,我推薦使用scoop包管理器來安裝gradle,它安裝方便,而且使用SHIM目錄來管理環境變數,在各種工具中配置gradle也很方便,

當然,如果你完全不喜歡安裝這么多亂七八糟的東西,那也可以使用gradle,gradle提供了一個名為gradle wrapper的工具,可以在沒有安裝gradle的情況下使用gradle,好吧,其實它就是個腳本檔案,當你運行wrapper腳本的時候,如果腳本發現你電腦里沒有gradle,就會自動替你下載安裝一個,現在甚至還出現了Maven wrapper,也是個腳本檔案,可以自動安裝Maven,

之前相信一些朋友聽說過gradle,然后嘗試使用它,結果因為速度太慢,最后放棄了,之前我也因為gradle的速度,放棄了它一段時間,不過現在使用gradle的話會方便很多,gradle官方在中國開設了,CDN,使用gradle wrapper的時候下載速度非常快,可以說現在是一個學習使用gradle的好時候,

使用gradle wrapper

這里我使用的IDEA來創建和使用gradle專案,

在IDEA中創建gradle專案

Spring Boot 基礎推薦看這個免費教程:

https://github.com/javastacks/spring-boot-best-practice

IDEA默認就會使用gradle wrapper來創建專案,所以無需安裝gradle也可以正常運行,這時候專案結構應該類似下圖所示,使用Maven的同學應該比較熟悉,因為這和Maven的專案結構幾乎完全一致,gradle檔案夾和gradlew那幾個檔案就是gradle wrapper的檔案,而.gradle后綴名的檔案正是gradle的組態檔,對應于Maven的pom.xml,

gradle專案結構

gradle wrapper的優點之一就是可以自定義下載的gradle的版本,如果是團隊協作的話,這個功能就非常方便,簡單設定即可統一團隊的構建工具版本,這里我就設定成目前最新的gradle 6.4.默認下載安裝的是bin版,僅包含二進制,如果你使用IDEA的話,它會推薦下載all版,包含源代碼,這樣IDEA就可以分析源代碼,提供更加精確的gradle腳本支持,

依賴管理

下面來看看gradle的依賴管理功能,這也算是我們使用構建工具的主要目的之一了,這點也是gradle相較maven的優勢之一了,相較于maven一大串的XML配置,gradle的依賴項僅需一行,

dependencies {
    testImplementation 'junit:junit:4.13'
    implementation 'com.google.code.gson:gson:2.8.6'
}

這里推薦一下Jetbrains的package search網站,是尋找maven和gradle依賴包的最佳網站,可以非常輕松的搜索和使用依賴項,

package search網站

gradle依賴的粒度控制相較于Maven也更加精細,maven只有compile、provided、test、runtime四種scope,而gradle有以下幾種scope:

  • implementation,默認的scope,implementation的作用域會讓依賴在編譯和運行時均包含在內,但是不會暴露在類別庫使用者的編譯時,舉例,如果我們的類別庫包含了gson,那么其他人使用我們的類別庫時,編譯時不會出現gson的依賴,
  • api,和implementation類似,都是編譯和運行時都可見的依賴,但是api允許我們將自己類別庫的依賴暴露給我們類別庫的使用者,
  • compileOnly和runtimeOnly,這兩種顧名思義,一種只在編譯時可見,一種只在運行時可見,而runtimeOnly和Maven的provided比較接近,
  • testImplementation,這種依賴在測驗編譯時和運行時可見,類似于Maven的test作用域,
  • testCompileOnly和testRuntimeOnly,這兩種類似于compileOnly和runtimeOnly,但是作用于測驗編譯時和運行時,

通過簡短精悍的依賴配置和多種多樣的作用與選擇,Gradle可以為我們提供比Maven更加優秀的依賴管理功能,

gradle的任務和插件

gradle的組態檔是一個groovy腳本檔案,在其中我們可以以編程方式自定義一些構建任務,因為使用了編程方式,所以這帶給了我們極大的靈活性和便捷性,打個比方,現在有個需求,要在打包出jar的時候順便看看jar檔案的大小,在gradle中僅需在構建腳本中撰寫幾行代碼即可,而在Maven中則需要撰寫Maven插件,復雜程度完全不在一個水平,

當然,Maven發展到現在,已經存在了大量的插件,提供了各式各樣的功能可以使用,但是在靈活性方面還是無法和Gradle相比,而且Gradle也有插件功能,現在發展也十分迅猛,存在了大量非常好用的插件,例如gretty插件,gretty原來是社區插件,后來被官方吸收為官方插件,可以在Tomcat和jetty服務器上運行web專案,比Maven的相關插件功能都強大,

雖然gradle可以非常靈活的撰寫自定義腳本任務,但是其實一般情況下我們不需要撰寫構建腳本,利用現有的插件和任務即可完成相關功能,在IDEA里,也可以輕松的查看當前gradle專案中有多少任務,基本任務如build、test等Maven和Gradle都是相通的,

gretty插件的任務

配置鏡像

Maven官方倉庫的下載速度非常慢,所以一般我們要配置國內的鏡像源,gradle在這方面和Maven完全兼容,因此只需稍微配置一下鏡像源,即可使用Maven的鏡像,如果你用gradle構建過專案,應該就可以在用戶目錄的.gradle檔案夾下看到gradle的相關配置和快取,

之前wrapper下載的gradle也存放在該檔案夾下,位置是wrapper/dists,

wrapper下載的gradle保存位置

而依賴的本地快取在caches\modules-2\files-2.1檔案夾下,目錄結構和Maven的本地快取類似,都是包名+版本號的方式,但是gradle的目錄結構最后一層和Maven不同,這導致它們無法共用本地快取,

言歸正傳,在gradle中配置下載鏡像需要在.gradle檔案夾中直接新建一個init.gradle初始化腳本,腳本檔案內容如下,這樣一來,gradle下載鏡像的時候就會使用這里配置的鏡像源下載,速度會快很多,再加上gradle wrapper在中國設定了CDN,現在使用gradle的速度應該會很快,

allprojects {
   repositories {
       maven {
           url "https://maven.aliyun.com/repository/public"
       }
       maven {
           url "https://maven.aliyun.com/repository/jcenter"
       }
       maven {
           url "https://maven.aliyun.com/repository/spring"
       }
       maven {
           url "https://maven.aliyun.com/repository/spring-plugin"
       }
       maven {
           url "https://maven.aliyun.com/repository/gradle-plugin"
       }
       maven {
           url "https://maven.aliyun.com/repository/google"
       }
       maven {
           url "https://maven.aliyun.com/repository/grails-core"
       }
       maven {
           url "https://maven.aliyun.com/repository/apache-snapshots"
       }
   }
}

當然,如果你有代理的話,其實我推薦你直接為gradle設定全域代理,因為gradle腳本實在是太靈活了,有些腳本中可能依賴了github或者其他地方的遠程腳本,這時候上面設定的下載鏡像源就不管用了,

所以有條件還是干脆直接使用全域代理比較好,設定方式很簡單,在.gradle檔案夾中新建gradle.properties檔案,內容如下,中間幾行即是設定代理的配置項,當然其他幾行我也建議你設定一下,把gradle運行時的檔案編碼設定為UTF8,增加跨平臺兼容性,

org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=10800
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=10800
systemProp.file.encoding=UTF-8
org.gradle.warning.mode=all

為什么使用gradle?

看到這里,你應該對gradle有了基本的了解, 也可以將其用于你的專案之中,但是如果你Maven已經非常熟悉了,可能不太愿意使用gradle,因為貌似沒有必要,但是既然gradle出現了,就說明有很多人對Maven還是有一定的意見,因此在這里我來總結一下gradle相比maven的優勢,

首先第一點也就是最重要的一點就是速度,gradle使用構建快取、守護行程等方式提高編譯速度,結果就是gradle的編譯速度要遠超maven,平均編譯速度比Maven快好幾倍,而且專案越大,這個差距就越明顯,

圖中是大型多模塊專案Maven和Gradle編譯時間的對比,來自gradle官網

第二點就是靈活性,gradle要比Maven靈活太多,雖然有時候靈活并不是一件好事情,但是大部分情況下,靈活一點可以極大的方便我們,Maven死板的XML檔案方式做起事情來非常麻煩,很多Maven專案都通過執行外部腳本的方式來完成一些需要靈活性的作業,而在gradle中組態檔就是構建腳本,構建腳本就是編程語言(groovy編程語言),完全可以自給自足,無需外部腳本,

第三點就是gradle DSL帶來的簡潔性,完成同樣的功能,gradle腳本的長度要遠遠短于maven組態檔的長度,雖然很多人都說XML維護起來不麻煩,但是我覺得,維護一個光是依賴就有幾百行的XML檔案,不見得就比gradle腳本簡單,

也許是因為我上面說的原因,也許有其他原因,不得不承認的一件事情就是gradle作為一個新興的工具已經有了廣泛的應用,spring等專案已經從Maven切換到了gradle,開發安卓程式也只支持gradle了,因此不管是否現在需要將專案從maven切換到gradle,但是至少學習gradle是一件必要的事情,

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了,,,

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/508046.html

標籤:Java

上一篇:Java Date(日期)物件如何進行格式化呢?

下一篇:MyBatis(九):結果集映射ResultMap

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more