一文帶你搞定 Maven

作者:程序員迪迦
https://juejin.cn/post/7218069978045726776

依賴

依賴是我們在使用 Maven 構建項目時最常使用的功能,通過依賴標籤,我們可以直接從 Maven 倉庫中引入對應的 Jar 包,無需手動再將 Jar 添加到目錄下了,可謂是十分方便,不過我們除了使用,還需要考慮多模塊下依賴之間的關係。

依賴配置

這個大家應該都很熟悉了,通過標籤引入 Maven 依賴

<dependencies> 
 <!-- servlet包 -->
     <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
     </dependency>
</dependencies>

引入依賴之後,刷新一下 Maven 依賴就可以引入相關的 Jar 包了。

依賴傳遞

依賴具有傳遞性,當我們引入了一個依賴的時候,就會自動引入該依賴引入的所有依賴,依次往下引入所有依賴。 比如我們引入了 Druid 數據庫連接池的 SpringBoot-Starter,那麼就會自動引入一些依賴如圖,我們僅僅引入了 druid-spring-boot-starter 依賴,就自動引入了該依賴依賴的依賴。總而言之就是套娃就完事了。 我們將這三個依賴稱爲間接引入的依賴,而我們在標籤中引入的依賴稱爲直接依賴,那麼如果這兩個重複了並且版本不一樣的話會怎麼辦呢,最後引入的到底是哪個版本呢,還是說都會引入呢? 如果重複了,遵從以下規則簡單來說,就是越在外層的優先級越高,如果同級的就按照配置順序,配置順序靠前的覆蓋配置順序靠後的。

可選依賴

可選依賴指對外隱藏當前所依賴的資源

<dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.12</version>
 <optional>true</optional>
</dependency>

配置了該選項之後,間接依賴就失效了。

排除依賴

排除依賴指主動斷開間接依賴的資源

<dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.12</version>
 <exclusions>
  <exclusion>
   <groupId>org.hamcrest</groupId>
   <artifactId>hamcrest-core</artifactId>
  </exclusion>
 </exclusions>
</dependency>

配置了該選項之後,間接依賴也會失效。 排除依賴和可選依賴的區別: 可選依賴是依賴提供者設置的,比如我們引入了 Durid,那麼該選項由 Durid 開發者設置 排除依賴由依賴引入者設置,比如我們引入了 Durid,那麼我們可以設置該選項

依賴範圍

依賴的 jar 默認情況可以在任何地方使用,可以通過 scope 標籤來改變依賴的作用範圍。主代碼指的是 main 文件夾下的代碼,測試代碼指的是 test 文件夾下的代碼(就那個綠色的玩意),打包指的是 maven package 指令執行時是否將 Jar 包打包。 其實如果我們偷懶的話,全部都默認也不是不可能,不過爲了我們程序代碼的可讀性與簡潔性,還是按照規範來比較好。

生命週期與插件

項目構建生命週期

Maven 項目構建生命週期描述的是一次構建過程經歷了多少個事件,我們可以把生命週期當成一個人的年齡。 Maven 將生命週期劃分爲三個大階段,類似於人類的青年,中年,暮年

第一個和第三個週期比較簡單,我們重點介紹一下 default 階段 先上一張勸退圖以上就是 defalut 階段完整的生命週期,其中標紅的地方,是幾個比較重要的週期,在 Idea 的 Maven 工具中也能體現出來當我們在 Idea 中點擊這幾個生命週期時,Maven 會自動將之前所有的生命週期都執行到,就類似於如果我 18 歲了,那麼我肯定經歷過 8 歲。

插件

插件就是 Idea 中 Maven 工具的 Plugins 部分通過 pom 文件中的標籤引入新的插件

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
</build>

那麼什麼是插件呢?

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-source-plugin</artifactId>
      <version>2.2.1</version>
      <executions>
        <execution>
          <goals>
            <goal>jar</goal>
          </goals>
          <phase>generate-test-resources</phase>
        </execution>
      </executions>
    </plugin>
  </plugins>

上述自定義插件的作用指的是在 generate-test-resources 生命週期執行打 jar 包的操作。

其實簡單的說,生命週期就是一個人的年齡階段,而插件就是每個人在每個年齡需要做的事情 總結:Maven 將一個項目構建的過程分爲一長串連續的生命週期,在對應的生命週期會通過插件完成對應的事件,通過使用 Maven 的生命週期,我們可以獲得我們需要的功能,可能是打 jar 包,可能是安裝到本地倉庫,可能是部署到私服。

模塊聚合

當使用 Maven 進行多模塊開發的時候,有可能出現 A 模塊依賴 B 模塊,B 模塊依賴 C 模塊,那麼我們如果想對 A 模塊打包,那麼就要先打包 C 模塊,再打包 B 模塊,最後打包 A 模塊才能成功,否則會報錯,並且,如果 C 模塊更新了,我們也要手動更新所有依賴 C 模塊的模塊,這樣是及不方便的,Maven 爲了更好的進行多模塊開發,提供了模塊聚合的功能。 作用:聚合用於快速構建 Maven 工程,一次性構建多個項目 / 模塊

<!--聚合的所有模塊-->
<modules>
        <module>ruoyi-admin</module>
        <module>ruoyi-framework</module>
        <module>ruoyi-system</module>
        <module>ruoyi-quartz</module>
        <module>ruoyi-generator</module>
        <module>ruoyi-common</module>
</modules>
<!--打包類型定義爲pom-->
<packaging>pom</packaging>

模塊繼承

還是在多模塊項目開發中,多個子模塊可能會引入相同的依賴,但是他們有可能會各自使用不同的版本,版本問題,有可能會導致最後構建的項目出問題,所以我們需要一種機制,來約定子模塊的相關配置,於是就有了模塊繼承 作用:通過繼承可以實現在子工程中沿用父工程中的配置 實現步驟:還是以 ruoyi 爲例

  1. 在子工程中聲明其父工程座標與對應的位置
 <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.8.1</version>
 </parent>
  1. 在父工程中定義依賴管理
<dependencyManagement>
        <dependencies>
            <!-- SpringBoot的依賴配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.5.8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 阿里數據庫連接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- SpringBoot集成mybatis框架 -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis-spring-boot.version}</version>
            </dependency>
            <!-- pagehelper 分頁插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.boot.version}</version>
            </dependency>
    </dependencies>
</dependencyManagement>
  1. 定義完成之後,子工程相關的依賴就無需定義版本號,會直接使用父工程的版本號
<dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>

繼承除了依賴版本號之外,還會繼承一些資源,如下圖

屬性

在 Maven 中,對於有些依賴可能需要保證相同的版本,比如 Spring 相關依賴,那麼我們就需要一個機制來保證這些依賴的版本都相同,我們可以使用 Maven 中的屬性,類似編程語言的全局變量。 Maven 中有很多屬性:

  1. 自定義屬性

  2. 內置屬性

  3. Setting 屬性

  4. Java 系統屬性

  5. 環境變量屬性

此處我們重點講解一下

自定義屬性

作用:將一些字符串定義爲變量,方便統一維護 使用步驟:還是以 ruoyi 爲例

  1. 定義自定義屬性
<properties>
        <ruoyi.version>3.8.1</ruoyi.version>
</properties>
  1. 調用:${xxx.yyy}
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>${ruoyi.version}</version>

內置屬性

作用:使用 Maven 內置屬性,快速配置一些文件

${basedir}
${version}

Setting 屬性

作用:使用 Maven 配置文件 setting.xml 中的標籤屬性,用於動態配置

${setting.localRepository}

Java 系統屬性

作用:讀取 Java 系統屬性 調用格式

${user.name}

系統屬性查詢方式

mvn help:system

環境變量屬性

作用:使用 Maven 環境變量

${env.JAVA_HOME}

版本管理

對於我們的項目來說,如果我們將其放到一些 Maven 倉庫中,那麼就需要對其進行版本控制,我們可以看一下一些開源項目的 Maven 官網上的版本。pom 文件配置

<version>1.0.0.RELEASE</version>

工程版本號約定工程版本

環境配置

一個項目,開發環境、測試環境、生產環境的配置文件必然不同,那麼 Maven 就需要進行多環境配置管理 Maven 多環境對應 Idea 中 Maven 工具的 Profiles 配置文件:通過配置文件配置,一個 profile 代表一個可選項 然後我們在 application.yml 配置文件中設置即可,之後通過設置 maven 的 profiles,就可以動態調整環境了。

私服

Maven 私服指的是企業自己搭建的 Maven 倉庫,通過 Maven 私服,第三方組織可以把自己組織內部的 Maven 依賴安裝到私服上,提供給組織內部使用,搭建完私服之後,通過配置 Maven,我們不止可以從中央倉庫中獲取 Maven 依賴,還可以從私服中獲取 Maven 依賴。 下圖是獲取資源的過程,中央倉庫的資源會從中央倉庫獲取,其他資源會從私服倉庫獲取

私服搭建

通過 Nexus 搭建私服 Nexus 是 Sonatype 公司的一款 Maven 私服產品 下載地址:Download (sonatype.com)

私服倉庫介紹

安裝好之後我們來看一下私服默認的倉庫列表可以將這些倉庫分爲三大類

創建私服倉庫 點擊 create repository 選擇 maven2(hosted)填入倉庫名稱創建完之後在倉庫列表可見,將新建的倉庫加入 maven-public 倉庫組,之後通過該倉庫組的 url 訪問點擊 maven-public 倉庫組

本地倉庫訪問私服配置

配置本地倉庫訪問私服的權限(setting.xml 文件),如果你想從這個倉庫中獲取或者部署資源,那麼就需要 server 配置來驗證權限,此處可以是不同的賬號密碼,不同的用戶對於倉庫的權限也不同。 配置 Servers

<servers>
 <server>
  <id>ticknet-release</id>
  <username>admin</username>
  <password>admin</password>
 </server>
 <server>
  <id>ticknet-snapshots</id>
  <username>admin</username>
  <password>admin</password>
 </server>
</servers>

配置 setting.xml 的 Profiles

    <profiles>
        <profile>
            <id>artifactory</id>
            <repositories>
                <repository>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                    <id>repo</id>
                    <name>repo</name>
                    <url>xxxx</url>
                </repository>
                <repository>
                    <snapshots/>
                    <id>snapshots</id>
                    <name>snapshots-only</name>
                    <url>xxxx</url>
                </repository>
            </repositories>
        </profile>
    </profiles>

此處的 URL 通過這個 copy 按鈕獲取。 配置激活 profiles

 <activeProfiles>
        <activeProfile>artifactory</activeProfile>
 </activeProfiles>

之後就可以從私服獲取資源了

上傳資源到私服

配置項目 pom 文件

<distributionManagement>
 <repository>
  <id>ticknet-release</id>
  <url>http://localhost:8081/repository/ticknet-release/</url>
 </repository>
 <snapshotRepository>
  <id>ticknet-snapshots</id>
  <url>http://localhost:8081/repository/ticknet-release/</url>
  </snapshotRepository>
</distributionManagement>

配置完執行生命週期的 deploy 即可。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/oQ4VEEnAYJFtOuqpWk18lw