【Maven】Maven 基礎教程(二):Maven 的使用

Maven 基礎教程》系列,包含以下 2 篇文章:

  • Maven 基礎教程(一):基礎介紹、開發環境配置
  • Maven 基礎教程(二):Maven 的使用

😊 如果您覺得這篇文章有用 ?? 的話,請給博主一個一鍵三連 🚀🚀🚀 吧 (點贊 🧡、關注 💛、收藏 💚)!!!您的支持 💖💖💖 將激勵 🔥 博主輸出更多優質內容!!!

Maven 基礎教程(二):Maven 的使用

  • 3.Maven 的使用
    • 3.1 核心概念:坐標
    • 3.2 pom.xml
    • 3.3 依賴
    • 3.4 依賴的傳遞
    • 3.5 依賴的排除
    • 3.6 繼承
      • 3.6.1 概念
      • 3.6.2 作用
      • 3.6.3 一個例子
    • 3.7 聚合
      • 3.7.1 Maven 中的聚合
      • 3.7.2 繼承和聚合的對應關系
      • 3.7.3 聚合的配置
      • 3.7.4 依賴循環問題

3.Maven 的使用

3.1 核心概念:坐標

數學中的坐標使用 x x x y y y z z z 三個 向量 作為空間的坐標系,可以在 空間 中唯一的定位到一個
在這里插入圖片描述
Maven 中的坐標使用三個 向量Maven的倉庫 中唯一的定位到一個 jar 包

  • groupId:公司或組織的 id,即公司或組織域名的 倒序,通常也會加上項目名稱。例如:com.javatv.maven
  • artifactId:一個項目或者是項目中的一個模塊的 id,即模塊的名稱,將來作為 Maven 工程的工程名。例如:auth
  • version:版本號。例如:1.0.0

坐標和倉庫中 jar 包的存儲路徑之間的對應關系,如下:

<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>

上面坐標對應的 jar 包在 Maven 本地倉庫中的位置:

Maven本地倉庫根目錄\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar

3.2 pom.xml

  • POMProject Object Model項目對象模型。和 POM 類似的是 DOMDocument Object Model),文檔對象模型。它們都是模型化思想的具體體現。
  • POM 表示將工程抽象為一個模型,再用程序中的對象來描述這個模型。這樣我們就可以用程序來管理項目了。我們在開發過程中,最基本的做法就是將現實生活中的事物抽象為模型,然后封裝模型相關的數據作為一個對象,這樣就可以在程序中計算與現實事物相關的數據。
  • POM 理念集中體現在 Maven 工程根目錄下 pom.xml 這個配置文件中。所以這個 pom.xml 配置文件就是 Maven 工程的 核心配置文件。其實學習 Maven 就是學這個文件怎么配置,各個配置有什么用。
<!-- 當前Maven工程的坐標 -->
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<!-- 當前Maven工程的打包方式,可選值有下面三種:-->
<!-- jar:表示這個工程是一個Java工程  -->
<!-- war:表示這個工程是一個Web工程 -->
<!-- pom:表示這個工程是“管理其他工程”的工程 -->
<packaging>jar</packaging><properties><!-- 工程構建過程中讀取源碼時使用的字符集 --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties><!-- 當前工程所依賴的jar包 -->
<dependencies><!-- 使用dependency配置一個具體的依賴 --><dependency><!-- 在dependency標簽內使用具體的坐標依賴我們需要的一個jar包 --><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><!-- scope標簽配置依賴的范圍 --><scope>test</scope></dependency>
</dependencies>

3.3 依賴

上面說到我們使用 Maven 最主要的就是使用它的依賴管理功能,引入依賴存在一個范圍,Maven 的依賴范圍包括:compileprovidedruntimetestsystem

  • compile:表示編譯范圍,指 A 在編譯時依賴 B,該范圍為默認依賴范圍。編譯范圍的依賴會用在編譯,測試,運行,由于運行時需要,所以編譯范圍的依賴會被打包。
  • providedprovied 依賴只有當 jdk 或者一個容器已提供該依賴之后才使用。provided 依賴在編譯和測試時需要,在運行時不需要。例如:Servlet API 被 Tomcat 容器提供了。
  • runtimeruntime 依賴在運行和測試系統時需要,但在編譯時不需要。例如:JDBC 的驅動包。由于運行時需要,所以 runtime 范圍的依賴會被打包。
  • testtest 范圍依賴在編譯和運行時都不需要,只在測試編譯和測試運行時需要。例如:Junit。由于運行時不需要,所以 test 范圍依賴不會被打包。
  • systemsystem 范圍依賴與 provided 類似,但是必須顯示的提供一個對于本地系統中 jar 文件的路徑。一般不推薦使用。
依賴范圍編譯測試運行時是否會被打入 jar
compile????
provided????
runtime????
test????
system????

而在實際開發中,我們常用的就是 compiletestprovided

3.4 依賴的傳遞

A 依賴 B,B 依賴 C,那么在 A 沒有配置對 C 的依賴的情況下,A 里面能不能直接使用 C?在以上的前提下,C 是否能夠傳遞到 A,取決于 B 依賴 C 時使用的依賴范圍。B 依賴 C 時使用 compile 范圍:可以傳遞;B 依賴 C 時使用 testprovided 范圍:不能傳遞。所以需要這樣的 jar 包時,就必須在需要的地方明確配置依賴才可以。

3.5 依賴的排除

當 A 依賴 B,B 依賴 C,而且 C 可以傳遞到 A 的時候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往這種情況都是為了避免 jar 包之間的沖突。
在這里插入圖片描述
所以配置依賴的排除其實就是阻止某些 jar 包的傳遞。因為這樣的 jar 包傳遞過來會和其他 jar 包沖突。

一般通過使用 excludes 標簽配置依賴的排除:

<dependency><groupId>net.javatv.maven</groupId><artifactId>auth</artifactId><version>1.0.0</version><scope>compile</scope><!-- 使用excludes標簽配置依賴的排除  --><exclusions><!-- 在exclude標簽中配置一個具體的排除 --><exclusion><!-- 指定要排除的依賴的坐標(不需要寫version) --><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency>

3.6 繼承

3.6.1 概念

Maven 工程之間,A 工程繼承 B 工程

  • B 工程:父工程
  • A 工程:子工程

本質上是 A 工程的 pom.xml 中的配置繼承了 B 工程中 pom.xml 的配置。

3.6.2 作用

在父工程中統一管理項目中的依賴信息,具體來說是管理依賴信息的版本。

它的背景是:

  • 對一個比較大型的項目進行了模塊拆分。
  • 一個 project 下面,創建了很多個 module
  • 每一個 module 都需要配置自己的依賴信息。

它背后的需求是:

  • 在每一個 module 中各自維護各自的依賴信息很容易發生出入,不易統一管理。
  • 使用同一個框架內的不同 jar 包,它們應該是同一個版本,所以整個項目中使用的框架版本需要統一。
  • 使用框架時所需要的 jar 包組合(或者說依賴信息組合)需要經過長期摸索和反復調試,最終確定一個可用組合。這個耗費很大精力總結出來的方案不應該在新的項目中重新摸索。
  • 通過在父工程中為整個項目維護依賴信息的組合既保證了整個項目使用規范、準確的 jar 包;又能夠將以往的經驗沉淀下來,節約時間和精力。

3.6.3 一個例子

1?? 一般在模塊化開發中一般都會創建一個父工程,如下:

在這里插入圖片描述
在這里插入圖片描述
父工程創建好之后,要修改它的打包方式:

<!-- 當前工程作為父工程,它要去管理子工程,所以打包方式必須是 pom -->
<packaging>pom</packaging>

只有打包方式為 pom 的 Maven 工程能夠管理其他 Maven 工程。打包方式為 pom 的 Maven 工程中不寫業務代碼,它是專門管理其他 Maven 工程的工程,所以可以將生成的 src 目錄刪除。

2?? 創建模塊工程

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
然后可以在父工程的 pom 文件中看到:

在這里插入圖片描述
而子工程的 pom 如下:

在這里插入圖片描述
3?? 在父工程中配置依賴的統一管理

使用 dependencyManagement 標簽配置對依賴的管理,如下:

<?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>net.javatv.maven</groupId><artifactId>maven-demo-parent</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>demo-module</module></modules><dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.3.19</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.3.19</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.19</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.19</version></dependency></dependencies></dependencyManagement></project>

而實際上被管理的依賴并沒有真正被引入到工程。

4?? 子工程中引用那些被父工程管理的依賴

關鍵點:省略版本號

子工程引用父工程中的依賴信息時,可以把版本號去掉。把版本號去掉就表示子工程中這個依賴的版本由父工程決定,具體來說是由父工程的 dependencyManagement 來決定。

子工程 pom 如下:

<?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"><!-- 使用parent標簽指定當前工程的父工程 --><parent><artifactId>maven-demo-parent</artifactId><groupId>net.javatv.maven</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><!-- 子工程的坐標 --><!-- 如果子工程坐標中的groupId和version與父工程一致,那么可以省略 --><artifactId>demo-module</artifactId><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId></dependency></dependencies></project>

此時,被管理的依賴才被引入到工程。
在這里插入圖片描述
5?? 修改父工程依賴信息的版本

這個修改可以是降級,也可以是升級,但一般來說都是升級。

在這里插入圖片描述
6?? 父工程中聲明自定義屬性

對同一個框架的一組 jar 包最好使用相同的版本,為了方便升級框架,可以將 jar 包的版本信息統一提取出來,統一聲明版本號:

<!-- 通過自定義屬性,統一指定Spring的版本 -->
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!-- 自定義標簽,維護Spring版本數據 --><spring.version>5.3.19</spring.version>
</properties>

在需要的地方使用 ${} 的形式來引用自定義的屬性名,真正實現一處修改,處處生效。

<?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>net.javatv.maven</groupId><artifactId>maven-demo-parent</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>demo-module</module></modules><!-- 通過自定義屬性,統一指定Spring的版本 --><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!-- 自定義標簽,維護Spring版本數據 --><spring.version>5.3.19</spring.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency></dependencies></dependencyManagement></project>

編寫一套符合要求、開發各種功能都能正常工作的依賴組合并不容易。如果公司里已經有人總結了成熟的組合方案,那么再開發新項目時,如果不使用原有的積累,而是重新摸索,會浪費大量的時間。為了提高效率,我們可以使用工程繼承的機制,讓成熟的依賴組合方案能夠保留下來。如下:
在這里插入圖片描述
如上圖所示,公司級的父工程中管理的就是成熟的依賴組合方案,各個新項目、子系統各取所需即可。

3.7 聚合

聚合,指分散的聚集到一起,即部分組成整體。

3.7.1 Maven 中的聚合

使用一個總工程將各個模塊工程匯集起來,作為一個整體對應完整的項目,實際就是 module 標簽。

  • 項目:整體
  • 模塊:部分

3.7.2 繼承和聚合的對應關系

繼承 關系角度來看:

  • 父工程
  • 子工程

聚合 關系角度來看:

  • 總工程
  • 模塊工程

3.7.3 聚合的配置

在總工程中配置 modules 即可:

<modules><module>demo-module</module>
</modules>

3.7.4 依賴循環問題

如果 A 工程依賴 B 工程,B 工程依賴 C 工程,C 工程又反過來依賴 A 工程,那么在執行構建操作時會報下面的錯誤:

DANGER[ERROR] [ERROR] The projects in the reactor contain a cyclic reference:

這個錯誤的含義是:循環引用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/710826.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/710826.shtml
英文地址,請注明出處:http://en.pswp.cn/news/710826.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt中關于信號與槽函數的思考

信號與槽函數的思考 以pushbutton控件為例&#xff0c;在主界面上放置一個pushbutton控件&#xff0c;點擊右鍵選擇關聯槽函數&#xff0c;關聯一個click函數&#xff0c;如下圖所示&#xff1a; 在該函數中&#xff0c;實現了一個點擊pushbutton按鈕后&#xff0c;彈出一個窗…

nginx使用詳解--反向代理

什么是反向代理&#xff1f; 正向代理&#xff1a; 一般的訪問流程是客戶端直接向目標服務器發送請求并獲取內容&#xff0c;使用正向代理后&#xff0c;客戶端改為向代理服務器發送請求&#xff0c;并指定目標服務器&#xff08;原始服務器&#xff09;&#xff0c;然后由代理…

在極狐GitLab 配置 SSL/https

本文作者 徐曉偉 說明 極狐GitLab https 使用的是 nginx 實現的本文使用的域名是IP 192.168.80.14&#xff08;原因&#xff1a;如果使用域名&#xff0c;必須擁有這個域名的所有權&#xff0c;并增加解析才可以&#xff0c;要不然在 Docker 容器中&#xff0c;無法使用域名檢…

go并發模式之----使用時順序模式

常見模式之二&#xff1a;使用時順序模式 定義 顧名思義&#xff0c;起初goroutine不管是怎么個先后順序&#xff0c;等到要使用的時候&#xff0c;需要按照一定的順序來&#xff0c;也被稱為未來使用模式 使用場景 每個goroutine函數都比較獨立&#xff0c;不可通過參數循環…

DOM 獲取父子節點

DOM 是以樹狀結構排列的&#xff0c;所以父子關系是相對的&#xff0c;當li為我們的目標節點的時候&#xff0c;ul為其父節點&#xff0c;其他li為它的兄弟節點&#xff0c;li里面包含的標簽為子節點&#xff0c;以此類推。 那我們如何找父節點&#xff1f; 元素.parentNode&am…

libigl 網格質量矩陣

文章目錄 一、簡介二、應用三、實現效果參考資料一、簡介 在 libigl 中,igl::massmatrix 是一個用于計算給定三角網格的質量矩陣的函數。質量矩陣在有限元分析和其他模擬技術中非常有用,它通常用于描述網格中各個節點的質量或者用于計算模擬過程中的慣性效應。 igl::massmatr…

分布式系統如何做數據對賬?

前言 在分布式系統中&#xff0c;雖然我們會使用各種分布式事務的方案&#xff0c;來保證各個系統之間的一致性。但是&#xff0c;很多時候往往事與愿違。 尤其是現在很多公司都采用最終一致性的方案&#xff0c;而所謂最終一致性&#xff0c;無論是本地消息表、事務消息、還…

藍橋杯:數組分割(Java)

目錄 問題描述輸入格式輸出格式代碼實現 問題描述 小藍有一個長度為N的數組A[A0,A1,… AN-1]。現在小藍想要從A對應的數組下標所構成的集合Ⅰ0,1,2,…,N -1中找出一個子集R1&#xff0c;那么R1在Ⅰ中的補集為R2。記S1∈∑Ar&#xff0c;S2∈∑Ar&#xff0c;我們要求S1和S2均為…

node 之 npm

1.什么是包 node.js中的第三方模塊又叫做包 就像電腦和計算機指的是相同的東西&#xff0c;第三方模塊和包指的是同一個概念&#xff0c;只不過叫法不同 2.包的來源 不同于 Node.js 中的內置模塊與自定義模塊&#xff0c;包是由第三方個人或團隊開發出來的&#xff0c;免費供所…

【計算機網絡——應用層】http協議

文章目錄 1. http協議1.1 http協議簡介1.2 url組成1.3 urlencode與urldecode 2. http協議的格式2.1 http協議的格式2.2 一些細節問題 3. http的方法、狀態碼和常見響應報頭3.1 http請求方法3.2 http狀態碼3.3 http常見的響應報頭屬性 4. 一個非常簡單的http協議服務端5. http長…

【X806開發板試用】文章一 ubuntu開發環境搭建

一、環境配置 官方鏈接&#xff1a; 環境配置 1.安裝必要的庫和軟件 sudo apt-get install build-essential gcc g make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-b…

pix2pix-zero

pix2pix-zero&#xff1a;零樣本圖像到圖像轉換 論文介紹 Zero-shot Image-to-Image Translation 關注微信公眾號: DeepGoAI 項目地址&#xff1a;https://github.com/pix2pixzero/pix2pix-zero 論文地址&#xff1a;https://arxiv.org/abs/2302.03027 本文介紹了一種名為…

Golang 函數中 defer 和 return 的調用順序

先來看一段代碼&#xff1a; package mainimport "fmt"func f() (ret int) {defer func() {ret}()return 1 } func main() {fmt.Println(f()) }上面這段代碼的輸出是2&#xff0c;不是1 原因在于&#xff1a; 1&#xff09;ret 是在執行 return 1 語句后發生的 2&…

基于SpringBoot多模塊項目引入其他模塊時@Autowired無法注入

基于SpringBoot多模塊項目引入其他模塊時Autowired無法注入 一、問題描述1、解決方案 一、問題描述 啟動Spring Boot項目時報 Could not autowire. No beans of ‘xxxxxxxx’ type found. 沒有找到bean的實例&#xff0c;即spring沒有實例化對象&#xff0c;也就無法根據配置文…

【LeetCode-中等】209.長度最小的子數組-雙指針/滑動窗口

力扣題目鏈接 1. 暴力解法 這道題的暴力解法是兩層嵌套for循環&#xff0c;第一層循環從 i 0 開始遍歷至數組末尾&#xff0c;第二層循環從 j i 開始遍歷至找到總和大于等于 target 的連續子數組&#xff0c;并將該連續子數組的長度與之前找到的子數組長度相比較&#xff0…

傳輸層兩大戰將TCP、UDP的定位

傳輸層 定義一些傳輸數據的協議和端口&#xff0c;傳輸協議同時進行流量控制&#xff0c;根據接收方的數據吞入熟讀&#xff0c;規定適當的發送速率&#xff0c;解決傳輸效率及能力問題 什么是TCP TCP/IP即傳輸控制/網絡協議&#xff0c;是面向連接的協議&#xff0c;發送數…

什么是IP公網?

IP公網是指互聯網上可以公開訪問的IP地址。它是經過互聯網服務提供商&#xff08;ISP&#xff09;向用戶提供的公共網絡IP地址。與之相對的是內網IP地址&#xff0c;內網IP地址一般是由路由器或交換機分配給連接在局域網中的設備使用。 IP公網的作用非常廣泛&#xff0c;可以應…

C#解析JSON

https://blog.csdn.net/weixin_43046974/article/details/131449900 C#解析JSON 1. JSON定義2. JSON一般構成及解析方法3. 解析舉例子 1. JSON對象解析&#xff0c;只包含一層對象{}2. 嵌套JSON對象解析&#xff0c;包含多層對象{}3. JSON數組解析1&#xff08;數組循環遍歷&…

Web APIs知識點講解(階段二)

DOM-事件基礎 一.事件 1.事件 目標&#xff1a;能夠給 DOM元素添加事件監聽 事件:事件是在編程時系統內發生的動作或者發生的事情&#xff0c;比如用戶在網頁上單擊一個按鈕 事件監聽:就是讓程序檢測是否有事件產生&#xff0c;一旦有事件觸發&#xff0c;就立即調用一個函…

http工具類

public class HttpRequstUtil {/*** http請求方法** param message 查詢條件* param url 查詢地址* param token 身份驗證token* param socketTimeout socket 響應時間* param connectTimeout 超時時間* return 返回字符串*/Deprecatedpublic stat…