日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

为什么我们需要Maven

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么我们需要Maven 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/a724888/article/details/79882623

編程項目構建工具簡介

在進行編程操作的時候,我們常常會遇到很多與編程無關的項目管理工作,如下載依賴、編譯源碼、單元測試、項目部署等操作。一般的,小型項目我們可以手動實現這些操作,然而大型項目這些工作則相對復雜。構建工具是幫助我們實現一系列項目管理、測試和部署操作的工具。

軟件構建(Software Build)是指軟件開發過程中涉及到的一系列處理工作,如將源代碼編譯成二進制代碼,打包二進制代碼,運行自動化測試等。為了方便編程人員的操作,人們開發了自動構建(Build Automation)工具來幫助人們處理這些工作。這篇博客將簡單介紹構建工具的概念。

  • 一、為什么需要構建工具
  • 二、構建工具的功能
  • 三、流行的構建工具
  • 四、如何識別項目構建工具

一、為什么需要構建工具

在國內高校的編程課中,比如,以合肥工業大學管理學院電子商務專業的編程課為例。一般都是從Java編程基礎教起,在安裝好JDK之后,開始使用一個記事本編寫一個HelloWorld.java,里面內容是打印出Hello World。接下來教大家使用JCreator工具來編寫程序,實現輸出。之后的教學主要內容在Java知識上,對于項目開發的經驗和知識則很少描述。于是很多同學不理解,為什么要用JCreator編寫程序,或者是JCreator很好用,為什么后面大家用Eclipse、IntelliJ IDEA這種工具來開發Java。

這些工具都是IDE,也就是為了方便開發人員組織代碼文件,管理項目而開發的。IDE其實也可以實現編譯、打包的功能。既然如此為何還需要構建工具呢?為什么很多IDE軟件都提供了各種構建工具插件呢?個人認為,IDE本身是為了提供開發人員編程的工具,因此整合了項目管理和構建的一些功能。而構建工具的目標是為了管理依賴、編譯、打包和部署。因此,后者更像是提供編程的依賴環境和外部包,并幫助發布部署項目的。它的對項目管理支持的功能和目標比IDE更純粹也更強大(比如大部分構建工具都有中央庫,收集了幾乎所有開源的外部包提供給開發者自動導入外部包的功能,而一般IDE的這方面功能也是通過構建工具實現的。同時,構建工具幾乎都支持命令行運行,來幫助我們打包、編譯和發布等,證明它并不是提供一個編寫代碼的環境,而是作為管理的工具存在。而IDE幾乎都是有界面,可以提供代碼編寫的)。此外,網絡上還有一些說法(https://www.oschina.net/question/558461_117208):

一般而言.一個比較正規的項目都不會基于IDE 進行構建..一般會用ant, maven, gradle ,
為什么不用ide 呢?首先,是ide的選擇,有人喜歡,用vim,eclipse,intellijidea,收費的,免費的.
特別是公開的項目,你用什么IDE 相當于為這個IDE 打廣告了..
所以,一般而言都是用構建工具,而不是IDE .實際上各種IDE 也是基于各種構建系統,也正是不同的IDE,它們的構建方式不同,所以要讓不同的IDE間能一起開發,于是需要一個統一的構建工具,只是你平時不關注而已..

對于小型的項目而言,比如大學開始的Java課可能要求我們寫一個簡單的計算器等。該項目依賴的外部的代碼很少,幾乎使用Java自帶的SDK就可以了。但是,對于大中型的項目,都會依賴很多外部開發資源。網絡上開源了大量的代碼,在我們編寫程序的時候可以幫助我們減少重復性的工作,大大提升復用情況,降低編程難度。對于這種項目的代碼維護,以及依賴維護是很復雜的。什么程序依賴什么版本的什么外部包,如果不使用構建工具幫助我們管理這些依賴,那將增加開發人員大量的負擔。因此,包括上述編譯、打包和發布等功能,構建工具在幫助我們管理這些東西,大大提升編程效率。

二、構建工具的功能

基本上構建的自動化是編寫或使一大部分任務自動執行的一個動作,而這些任務則是軟件開發者的日常,像是

  • 下載依賴
  • 將源代碼編譯成二進制代碼
  • 打包生成的二進制代碼
  • 進行單元測試
  • 部署到生產系統
  • 三、流行的構建工具

    歷史上,自動構建工具主要是通過makefiles(環境變量文件)進行,它是一個文件,包含了自動構建的指令。大多數情況下,makefile都是指示如何編譯并連接項目的。目前,不同的編程語言有不同的構建工具。主要包括如下:

  • Java - Ant, Maven, Gradle
  • .NET Framework - NAnt
  • C# - MsBuild
  • 在Java的世界里,目前在被使用的常用構建工具有三個:Ant,Maven,Gradle。

    Ant的核心是由Java編寫,采用XML作為構建腳本,這樣就允許你在任何環境下,運行構建。Ant基于任務鏈思想,任務之間定義依賴,形成先后順序。缺點是使用XML定義構建腳本,導致腳本臃腫,Ant自身沒有為項目構建提供指導,導致每個build腳本都不一樣,開發人員對于每個項目都需要去熟悉腳本內容,沒有提供在Ant生態環境內的依賴管理工具。

    Maven團隊意識到Ant的缺陷,采用標準的項目布局,和統一的生命周期,采用約定由于配置的思想,減少構建腳本需要的編寫內容,活躍的社區,可以方便找到合適的插件,強大的依賴管理工具。缺點是采用默認的結構和生命周期,太過限制,編寫插件擴展麻煩,XML作為構建腳本。

    而Gradle同時擁有Ant和Maven的優點,它是基于Groovy的DSL,提供聲明式的構建語言,采用標準的項目布局,但擁有完全的可配置性,就是可以改,通過插件,提供默認的構建生命周期,也可以自己定義任務,單獨運行任務,定義任務間的依賴,強大的依賴管理工具,與Maven和Ivy倉庫結合,與Ant天生兼容,有效的重用Ant的任務,多種實現插件的方式,強大的官方插件庫,從構建級別,支持從Ant或者Maven的逐步遷移,通過包裝器,無縫的在各個平臺運行。

    四、如何識別項目構建工具

    一般地,一個項目的根目錄中就會包含構建工具的配置文件信息,也表明了該項目使用的構建工具,通常有如下的對應關系:

  • build.xml - 該項目使用Ant構建
  • pom.xml - 該項目使用Maven構建
  • build.gradle - 該項目使用Gradle構建


  • 接下來介紹一下Maven

    背景

      在使用Eclipse進行項目合作開發的時,我們是如何進行項目依賴管理的呢?

      我們通常會在新建項目的時候,同時建立一個lib目錄,在其中放著項目所依賴的各方類庫,這樣提交到SVN之后, 每個開發人員檢出項目到本地,得到項目的工作副本,這樣所有開發人員就會持有統一的項目依賴了。?
      【1】依賴冗余,浪費空間:但是,隨著項目的增多,模塊的增多,這種方式就會有問題。很多模塊都會引用相同的依賴,當每個模塊都把自己的依賴提交到SVN,那么相同的依賴就會占用服務器SVN的Repository很大的空間,造成空間浪費。?
      【2】版本問題:同時,如果一個項目中依賴的版本和另一個項目依賴的版本不一致。比如這個項目依賴hibernate2.x,而另一個可能依賴hibernate3.x, 當合并兩個項目發布的時候, 可能因為這種依賴類庫詳細版本信息的缺失,造成問題。

    是什么

      為了解決以上依賴管理過程中出現的問題, 我們尋求出一種集中式的依賴管理方式。各個項目只要通過統一的依賴描述文件(pom.xml)來指定自己需要的依賴就可以, 而不用自己來管理真正的依賴庫,因為所有的項目都使用同一個中央依賴庫(中央倉庫), 所以即使各個項目中有相同的依賴, 也不會出現依賴冗余的問題。?
      Maven是基于POM的一款進行項目依賴管理,構建管理和項目信息管理的工具。

    優點

    【1】“約定優于配置(Convention over Configuration)”,maven提供了約定的項目的目錄結構,自動創建項目目錄,提高開發效率。

    目錄結構:?
         main :源代碼?
         test : 放測試類?
         resource:資源文件

         src?
         –main?
         —-java?
         ——package?
         –test?
         —-java?
         ——package

    用命令自動創建目錄的兩種方式:如:mvn archetype:generate

    【2】簡單的構建過程:編譯、清理、測試、打包、部署等。通過輸入簡單的命令就可以完成這些工作。?
       compile:編譯?
       test:測試?
       package:打包?
       clean?:清理target文件,刪除maven生成的目標文件,target中存放的是編譯后的class文件和測試報告?
       install:安裝jar包到本地倉庫中

    Maven編譯項目流程


    最原始的java程序運行:

    Java 程序是由若干個 .class 文件組成的。這些 .class 文件必須根據它們所屬的包不同而分級分目錄存放;運行前需要把所有用到的包的根目錄指定給 CLASSPATH 環境變量或者通過 java 命令的 -cp 參數;運行時還要到控制臺下去使用 java 命令來運行。

    使用maven編譯項目的流程:

    1.執行mvn compile 編譯源代碼?
    2.如果用到其他jar包時會去pom.xml中的找坐標?
    3.根據坐標去本地倉庫中查找:?
    如果有,則將jar包加入到classpath中?
    如果沒有,會去maven的中央倉庫找,下載放到本地倉庫中,再加入到classpath中。

    基本概念

    倉庫:管理和存放項目依賴?
    坐標:項目依賴的唯一標示


    生命周期:?
      clean :清理項目 clean?
      default:構建項目 compile test package install?
      site:生成項目站點?
      【備注】:如果執行mvn package命令,會先自動執行compile 和test命令。


    依賴范圍:?
        有三種classpath(編譯,測試,運行),規定依賴范圍就是控制依賴與classpath的關系, 不同的范圍,就會尋找不同classpath下的jar包進行執行。?
    compile?【默認方式】:編譯,測試,運行,打包的時候都會加入依賴(默認方式)?
    provided編譯和測試的時候會加入依賴,運行時不會,打包時不會。如:項目依賴Servlet API,但是運行時不依賴。因為Web Container中已經有,這樣避免了沖突 。?
    runtime:在運行和測試的時候依賴,在編譯的時候不依賴?
    test:測試時依賴,編譯和打包時不依賴,測試時才有用的依賴。如:要把(如Junit)scope設置成test。?
    system:和provided一樣?編譯和測試時候有效,與本機系統相關聯,可移植性差?
    import:導入的范圍,表示如將項目B中的依賴導入到A當中,只是用在dependencyManagement中


    依賴:

    傳遞依賴:A–>B–>C,項目A對項目C是間接依賴,此時項目A中就會有項目C的jar包,可以通過exclution標簽排除jar包。?
    依賴沖突:?
    1.短路優先:A–>B–>C–>X(V1.0)同時A–>D–>X(V2.0),那么A會依賴V2.0的X。?
    2.先聲明優先:A–>B–>X(V1.0),A–>C–>X(V2.0),那么看在A的pom的xml文件中,先聲明的是B的依賴還是C的依賴,A會依賴先聲明者所依賴的該版本的X。?
    聚合:需要將多個項目同時安裝時,可以通過module進行配置?
    繼承:多個項目中含有共同的依賴,將這些依賴抽到父類中,用dependencyManagement標簽進行管理,子類中通過parent標簽進行繼承。

    一個Maven編譯實例

    ?<span?style="font-size:?small;">[INFO]?Scanning?for?projects...??

    2.?[INFO]?------------------------------------------------------------------------??

    3.?[INFO]?Building?Maven?Hello?World?Project??

    4.?[INFO]????task-segment:?[clean,?compile]??

    5.?[INFO]?------------------------------------------------------------------------??

    6.?[INFO]?[clean:clean?{execution:?default-clean}]??

    7.?[INFO]?Deleting?directory?D:\code\hello-world\target??

    8.?[INFO]?[resources:resources?{execution:?default-resources}]??

    9.?[INFO]?skip?non?existing?resourceDirectory?D:?\code\hello-world\src\main\resources??

    10.?[INFO]?[compiler:compile?{execution:?default-compile}]??

    11.?[INFO]?Compiling?1?source?file?to?D:?\code\hello-world\target\classes??

    12.?[INFO]?------------------------------------------------------------------------??

    13.?[INFO]?BUILD?SUCCESSFUL??

    14.?[INFO]?------------------------------------------------------------------------??

    15.?[INFO]?Total?time:?1?second??

    16.?[INFO]?Finished?at:?Fri?Oct?09?02:08:09?CST?2009??

    17.?[INFO]?Final?Memory:?9M/16M??

    18.?[INFO]?------------------------------------------------------------------------??

    19.?</span>??

    ?

    clean告訴Maven清理輸出目錄target/compile告訴Maven編譯項目主代碼,從輸出中我們看到Maven首先執行了clean:clean任務,刪除target/目錄,默認情況下Maven構建的所有輸出都在target/目錄中;接著執行resources:resources任務(未定義項目資源,暫且略過);最后執行compiler:compile任務,將項目主代碼編譯至target/classes目錄(編譯好的類為com/juvenxu/mvnbook/helloworld/HelloWorld.Class)。

    上文提到的clean:cleanresources:resources,以及compiler:compile對應了一些Maven插件及插件目標,比如clean:cleanclean插件的clean目標,compiler:compilecompiler插件的compile目標,后文會詳細講述Maven插件及其編寫方法。

    至此,Maven在沒有任何額外的配置的情況下就執行了項目的清理和編譯任務,接下來,我們編寫一些單元測試代碼并讓Maven執行自動化測試。

    1.?[INFO]?Scanning?for?projects...??

    2.?[INFO]?------------------------------------------------------------------------??

    3.?[INFO]?Building?Maven?Hello?World?Project??

    4.?[INFO]????task-segment:?[clean,?test]??

    5.?[INFO]?------------------------------------------------------------------------??

    6.?[INFO]?[clean:clean?{execution:?default-clean}]??

    7.?[INFO]?Deleting?directory?D:\git-juven\mvnbook\code\hello-world\target??

    8.?[INFO]?[resources:resources?{execution:?default-resources}]??

    9.?…??

    10.?Downloading:?http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.pom??

    11.?1K?downloaded??(junit-4.7.pom)??

    12.?[INFO]?[compiler:compile?{execution:?default-compile}]??

    13.?[INFO]?Compiling?1?source?file?to?D:?\code\hello-world\target\classes??

    14.?[INFO]?[resources:testResources?{execution:?default-testResources}]??

    15.?…??

    16.?Downloading:?http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.jar??

    17.?226K?downloaded??(junit-4.7.jar)??

    18.?[INFO]?[compiler:testCompile?{execution:?default-testCompile}]??

    19.?[INFO]?Compiling?1?source?file?to?D:\?code\hello-world\target\test-classes??

    20.?[INFO]?------------------------------------------------------------------------??

    21.?[ERROR]?BUILD?FAILURE??

    22.?[INFO]?------------------------------------------------------------------------??

    23.?[INFO]?Compilation?failure??

    24.?D:\code\hello-world\src\test\java\com\juvenxu\mvnbook\helloworld\HelloWorldTest.java:[8,5]?-source?1.3?中不支持注釋??

    25.?(請使用?-source?5?或更高版本以啟用注釋)??

    26.?????@Test??

    27.?[INFO]?------------------------------------------------------------------------??

    28.?[INFO]?For?more?information,?run?Maven?with?the?-e?switch??

    29.???… ?

    不幸的是構建失敗了,不過我們先耐心分析一下這段輸出(為了本書的簡潔,一些不重要的信息我用省略號略去了)。命令行輸入的是mvn?clean?test,而Maven實際執行的可不止這兩個任務,還有clean:cleanresources:resourcescompiler:compileresources:testResources以及compiler:testCompile。暫時我們需要了解的是,在Maven執行測試(test)之前,它會先自動執行項目主資源處理,主代碼編譯,測試資源處理,測試代碼編譯等工作,這是Maven生命周期的一個特性,本書后續章節會詳細解釋Maven的生命周期。

    從輸出中我們還看到:Maven從中央倉庫下載了junit-4.7.pomjunit-4.7.jar這兩個文件到本地倉庫(~/.m2/repository)中,供所有Maven項目使用。

    構建在執行compiler:testCompile任務的時候失敗了,Maven輸出提示我們需要使用-source?5或更高版本以啟動注釋,也就是前面提到的JUnit?4@Test注解。這是Maven初學者常常會遇到的一個問題。由于歷史原因,Maven的核心插件之一compiler插件默認只支持編譯Java?1.3,因此我們需要配置該插件使其支持Java?5


    總結

      所謂構建就是包括編譯,運行單元測試,生成測試報告(還記得target文件夾嗎?那里存放著測試報告),打包,部署等一系列過程。我們通過Maven可以方便地自動化的完成這些,僅僅是通過一個mvn clean install命令。雖然我最初用它時,以為它僅僅是一個管理項目依賴的工具,類似于NuGet(.NET平臺下的免費、開源的包管理開發工具)。現在看來它的功能還有待我去實踐和發掘。有興趣地可以閱讀一下《Maven實戰》這本書。


    總結

    以上是生活随笔為你收集整理的为什么我们需要Maven的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。