『網際網路架構』軟體架構-環境搭建maven(三)

davidtim發表於2021-09-09

maven所有java開發標準的構建工具,之前才入行的時候聽過ant來進行構建,但是現在基本不存在了 ,maven是一個體繫結構的管理,也是個編譯方式的管理。原始碼: 資料夾Nexus

圖片描述

maven 歷史

Maven最初設計,是以簡化Jakarta Turbine專案的建設。在幾個專案,每個專案包含了不同的Ant構建檔案。 JAR檢查到CVS。 Apache組織開發Maven可以建立多個專案,釋出專案資訊,專案部署,在幾個專案中JAR檔案提供團隊合作和幫助。

maven是什麼?

Maven是基於專案物件模型(POM project object model),可以透過一小段描述資訊(配置)來管理專案的構建,報告和文件的軟體專案管理工具,簡單的說就是用來管理專案所需要的依賴且管理專案構建的工具。Maven現在越來越流行,已經逐步取代Ant。它比Ant單一的批處理功能提供更多實用服務。

maven用之前

在沒有Maven之前,我們開發一個專案,需要自行匯入各種不同的jar包。當依賴包數量多起來,就很難管理了。而且,如果團隊開發時,一個人提交的專案所使用的IDE版本與另一個人的不一致,那麼所提及的專案就可能不能正常地在別人的IDE中編譯、執行。總的來說,大概有以下幾類問題:

  1. jar包太多,需要手動下載、匯入,比較麻煩。

  2. jar包有依賴衝突時,需要自行排查。

  3. 使用ant指令碼構建專案時,需要寫很多重複的任務。

  4. 專案複製給別人時,不僅原始碼,還需要複製大量jar包。

  5. 測試專案時,需要一個個執行測試。

  6. 使用svn或者cvs每次都需要將jar包放入配置庫中,每次下載一個專案都需要下載幾百兆。

maven做什麼?

  1. 依賴管理:透過一個xml檔案,統一管理專案中所以jar包。開發專案時,需要用到的jar包只需在配置檔案中配置好幾個相關資訊,Maven就會自動下載、匯入到專案中,並且如果該jar包有依賴包,也會自動一併下載、匯入。如果專案有jar包依賴衝突,只需透過Maven的 mvn -X compile dependency:tree -Dverbose 指令即可自動排查出衝突的jar包資訊。

  2. 專案構建:這一步類似Ant,可以透過Maven的配置指令碼批處理專案的編譯、測試、打包、部署、釋出等操作.

  3. 資訊管理:管理專案的相關資訊,比如版本資訊、開發者資訊等。

maven的目錄結構

  1. 根目錄必須有src和pom.xml檔案,target目錄。

  2. target目錄可選主要存放註解和一些class檔案。

  3. src下必須有main。

  4. main下有java包,resources資源包,webapp包。

pom的組成

POM 檔案介紹與基本組成
說明:全稱是Project Object Model,通俗點的話說就是要對構建的專案進行建模。組成的基本元素:

元素 可選值 描述
groupId
分組ID
artifactId
模組ID
version
版本
packaging
打包型別:pom、jar、war
modelVersion
對應的超級pom 版本
dependencies
專案依懶包

maven jar包的流程

  1. maven jar先在本地找,查詢本地

  2. 本地找不到去遠端倉庫找

  3. 有的公司有自己的私服,本地找不到先找自己的私服

  4. 私服找不到去遠端倉庫中找,遠端找到後會把jar包丟到私服裡面

圖片描述

遠端倉庫的配置

maven的安裝路徑下,有個lib,lib裡面有個maven-model-build.jar,裡面有個pom檔案。裡面寫明白了,我們的jar包去哪裡找。

圖片描述

圖片描述

圖片描述

圖片描述

maven repository 與映象地址

 這個地址是國際的遠端倉庫,因為國內網路不太穩定,除非科學上網,但是感覺還是沒有國內的倉庫方便。
1.國內一般使用阿里雲倉庫
2.oschina的倉庫

 maven 倉庫用於查詢所需要pom專案

 全球總倉庫1

 全球總倉庫2

 阿里雲映象倉庫

 oschina 映象倉庫

映象配置

修改settings.xml 檔案

<mirrors>
  <mirror>
  <id>alimaven</id>
  <name>aliyun maven</name>
  <url>
  <mirrorOf>central</mirrorOf>
  </mirror><!-- 中央倉庫1 -->
  <mirror>
  <id>repo1</id>
  <mirrorOf>central</mirrorOf>
  <name>Human Readable Name for this Mirror.</name>
  <url>
  </mirror><!-- 中央倉庫2 -->
  <mirror>
  <id>repo2</id>
  <mirrorOf>central</mirrorOf>
  <name>Human Readable Name for this Mirror.</name>
  <url>
  </mirror><!-- 阿里倉庫映象 -->
  <mirror>
  <id>nexus-aliyun</id>
  <mirrorOf>*</mirrorOf>
  <name>Nexus aliyun</name>
  <url>
  </mirror><!-- OSchina倉庫映象 -->
  <mirror>
   <id>CN</id>
   <name>OSChina Central</name>                                                                                                                       
   <url>
   <mirrorOf>central</mirrorOf>
   </mirror></mirrors>

maven的基本命令

mvn 基本命令
mvn clean // 清理
mvn compile // 編譯
mvn test // 測試
mvn package // 打包
mvn install // 打包並上傳到本地倉庫
mvn depeloy // 上傳到遠端倉庫
mvn -Dmaven.test.skip=true // 跳過測試

scope

scope的預設值是compile,那麼scope還能有哪些選項呢?

  1. compile:預設值 他表示被依賴專案需要參與當前專案的編譯,還有後續的測試,執行週期也參與其中,是一個比較強的依賴。打包的時候通常需要包含進去

  2. test:依賴專案僅僅參與測試相關的工作,包括測試程式碼的編譯和執行,不會被打包,例如:junit

  3. runtime:表示被依賴專案無需參與專案的編譯,不過後期的測試和執行週期需要其參與。與compile相比,跳過了編譯而已。例如mysql-JDBC驅動,適用執行和測試階段。

  4. provided:打包的時候可以不用包進去,別的設施會提供。事實上該依賴理論上可以參與編譯,測試,執行等週期。相當於compile,但是打包階段做了exclude操作,例如sevlet,在執行的時候用,其實在打包的時候並不需要打進去,tomcat裡面自帶的有servlet。

  5. system:從參與度來說,和provided相同,不過被依賴項不會從maven倉庫下載,而是從本地檔案系統拿。需要新增systemPath的屬性來定義路徑

maven的專案型別

  • 聚合專案

假設有專案A和專案B,我們想一次性構建兩個專案,而不是到兩個模組的目錄下分別執行mvn命令。maven聚合解決了該問題。
這時候我們要建立另外一個專案ALL,然後透過該模組構建整個專案的所有模組。ALL作為一個maven專案,必須擁有自己的pom檔案。 如果有idea開啟maven的展示的時候對於多專案總會有個root

圖片描述

  • 繼承專案

子專案A,B需要繼承專案ALL中的POM配置,那麼就需要使用到繼承,java專案service模組依賴dao模組,dao模組依賴mapper模組。parent元素中的屬性對應的都是父專案中的內容。在parent元素中還有一個屬性relativePath,maven會透過這個路徑去查詢父專案的pom.xml,如果找不到會從本地倉庫中查詢。relativePath的預設值是../pom.xml,也就是預設父POM在上一層目錄下。

  • 依賴專案

子專案都會繼承父專案的依賴關係,如果子專案不需要父專案的依賴關係,maven提供的dependencyManagement元素能讓子模組繼承到父模組的依賴配置,有能保證子模組的靈活性。dependencyManagement元素下的依賴宣告不會引入實際的依賴,能約束dependencies下的依賴使用。父專案中使用該元素宣告的依賴既不會給父專案引入依賴也不會給子專案引入依賴,但是該配置會被繼承。如果子專案中不宣告經過父專案dependencyManagement修飾的依賴,那麼子專案就不會引入該依賴。

私服的搭建和使用Nexus

學過上邊的內容其實就夠了,但是如果你的定位不是小兵,而是一名技術的經理的話,不僅需要了解和掌握上邊的知識基本的命令,還需要搭建整個私服的maven環境。

  • 歷史Nexus

Nexus是Maven倉庫管理器,也可以叫Maven的私服。Nexus是一個強大的Maven倉庫管理器,它極大地簡化了自己內部倉庫的維護和外部倉庫的訪問。利用Nexus你可以只在一個地方就能夠完全控制訪問和部署在你所維護倉庫中的每個Artifact。Nexus是一套“開箱即用”的系統不需要資料庫,它使用檔案系統加Lucene來組織資料。

   Nexus不是Maven的核心概念,它僅僅是一種衍生出來的特殊的Maven倉庫。對於Maven來說,倉庫只有兩種:本地倉庫和遠端倉庫。
  • Nexus私服的搭建

本次的安裝Nexus,我直接使用docker的方式,去除了很多複雜的配置。
透過原始碼生成1個虛擬機器,準備工作。vagrant已經安裝了 對應的docker。
用docker安裝nexus就是為了避免環境變數,使用者賦權等複雜的操作。對於vagrant的如何安裝不用的系統不一樣可以參看
mac 安裝vgarant :
window安裝

系統型別 IP地址 節點角色 CPU Memory Hostname
Centos7 192.168.66.100 Nexus 2 2G Nexus

(1). 虛擬機器vagrant講述安裝的步驟


圖片描述


圖片描述

(2).機器window/mac開通遠端登入root使用者下

su -# 密碼vagrant#設定 PasswordAuthentication yesvi /etc/ssh/sshd_config
sudo systemctl restart sshd

圖片描述

圖片描述

(3). 安裝nexus

透過shell指令碼的方式執行

mkdir nexuscd nexus
mkdir data
chown -R 200 datapwdll
vi start.sh

圖片描述

圖片描述

start.sh

#!/bin/bashcur_dir=`pwd`
docker stop nexus
docker rm nexus
docker run -d -p 8081:8081 
--name nexus 
-v  ${cur_dir}/data:/sonatype-work 
sonatype/nexus

執行shell指令碼

sh start.sh

圖片描述

訪問獲取地址http://192.168.66.100:8081/nexus
預設的使用者名稱密碼:admin / admin123

圖片描述

  • 倉庫的型別

  1. goup(分組倉庫)

  2. hosted (私有倉庫,我們自己內部生成的jar檔案)

3rd party 就是在公網沒有,其他人給你的jar放這裡的倉庫
Snapshots 本地開發某個模組的快照倉庫
Releases 本地開發某個模組的正式版本倉庫

  1. proxy(公網釋出的jar檔案)

Apache Snapshots apache的快照倉庫
Central 重要倉庫

圖片描述

對於maven的倉庫和映象的概念一定要理解,倉庫是存放mavenjar的地方,映象是我們下載的時候需要下載的地址。阿里雲,碼雲的maven都是映象而非倉庫的概念。

  • 如何本地的專案訪問私服,上傳jar包

maven 私服的setting.xml配置,注入如果是特定的倉庫修改mirrorOf 換成對應的repository id
mirrorOf * 的含義,就是所有的jar包下載都必須走私服,不能走其他的映象和倉庫

<?xml version="1.0" encoding="UTF-8"?><settings xmlns="" 
          xmlns:xsi="" 
          xsi:schemaLocation=" ">

  <pluginGroups></pluginGroups>
  <proxies></proxies>

  <servers>
      <server>
      <id>nexus-releases</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
    <server>
      <id>nexus-snapshots</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
  </servers>

  <mirrors> 
    <mirror> 
      <id>nexus-releases</id> 
      <mirrorOf>*</mirrorOf> 
      <url>http://192.168.66.100:8081/nexus/content/groups/public</url> 
    </mirror>
    <mirror> 
      <id>nexus-snapshots</id> 
      <mirrorOf>*</mirrorOf> 
      <url>http://192.168.66.100:8081/nexus/content/groups/public-snapshots</url> 
    </mirror> 
  </mirrors> 
 
  <profiles>
   <profile>
      <id>nexus</id>
      <repositories>
        <repository>
          <id>nexus-releases</id>
          <url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
        <repository>
          <id>nexus-snapshots</id>
          <url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
         <pluginRepository>
                <id>nexus-releases</id>
                 <url>
                 <releases><enabled>true</enabled></releases>
                 <snapshots><enabled>true</enabled></snapshots>
               </pluginRepository>
               <pluginRepository>
                 <id>nexus-snapshots</id>
                  <url>
                <releases><enabled>true</enabled></releases>
                 <snapshots><enabled>true</enabled></snapshots>
             </pluginRepository>
         </pluginRepositories>
    </profile>
  </profiles>

  <activeProfiles>
      <activeProfile>nexus</activeProfile>
  </activeProfiles>
 </settings>

pom的配置

<distributionManagement>
        <!-- 兩個ID必須與 setting.xml中的<server><id>nexus-releases</id></server>保持一致-->
        <repository>
            <id>nexus-releases</id>
            <name>Nexus Release Repository</name>
            <url>http://192.168.66.100:8081/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>nexus-snapshots</id>
            <name>Nexus Snapshot Repository</name>
            <url>http://192.168.66.100:8081/nexus/content/repositories/snapshots</url>
        </snapshotRepository>
    </distributionManagement>

maven外掛的使用

  • 官網

圖片描述

  • 隨便找一個maven的外掛,看它如何使用


    圖片描述

圖片描述

圖片描述

<project>
  ...  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>3.0.1</version>
        <executions>
          <execution>
            <id>attach-sources</id>
            <phase>verify</phase> <!--什麼時間?生命週期的階段-->
            <goals>
              <goal>jar-no-fork</goal><!--幹什麼事情?目標是什麼-->
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...</project>

maven生命週期

官方介紹 ,生命週期都是按照順序執行的,從上到下。外掛的執行就是生命週期來完成的,某個外掛什麼時間,執行什麼事情,所以使用外掛的時候一定要了解生命週期。

clean lifecycle : 構建前的清理工作
• pre-clean 執行一些需要在clean之前完成的工作
• clean 移除所有上一次構建生成的檔案
• post-clean 執行一些需要在clean之後立刻完成的工作
Default lifecycle: 構建的核心部分,編譯、打包、部署、上傳
• validate<里程碑> 專案及所必須的環境驗證
• initialize 初始化構建狀態,例如設定屬性或建立目錄。
• generate-sources 生成次源包
• process-sources
• generate-resources
• process-resources 複製並處理資原始檔,至目標目錄,準備打包。
• compile<里程碑> 編譯專案的原始碼。
• process-classes
• generate-test-sources
• process-test-sources
• generate-test-resources
• process-test-resources 複製並處理資原始檔,至目標測試目錄。
• test-compile 編譯測試原始碼。
• process-test-classes
• test<里程碑> 使用合適的單元測試框架執行測試。這些測試程式碼不會被打包或部署。
• prepare-package
• package<里程碑> 接受編譯好的程式碼,打包成可釋出的格式,如 JAR 。
• pre-integration-test
• integration-test
• post-integration-test
• verify<里程碑>
• install<里程碑> 將包安裝至本地倉庫,以讓其它專案依賴。
• deploy<里程碑> 將最終的包複製到遠端的倉庫,以讓其它開發人員與專案共享。
site lifecycle:專案報告生成,站點文件生成
• pre-site 執行一些需要在生成站點文件之前完成的工作
• site 生成專案的站點文件
• post-site 執行一些需要在生成站點文件之後完成的工作,並且為部署做準備
• site-deploy 將生成的站點文件部署到特定的伺服器上

圖片描述

PS:百度太多了maven的安裝,也沒必要在這裡說了,重點是maven私服的搭建,還有maven外掛和生命週期,外掛和生命週期的配合才能合理化的使用maven進行構建,透過對maven的理解可以很深入的瞭解。專案高度自動化構建,依賴管理(這是使用Maven最大的好處),倉庫管理。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3349/viewspace-2825871/,如需轉載,請註明出處,否則將追究法律責任。

相關文章