maven 的基本使用終結版

預期讀者

對 maven 有一定基礎的同學,想對 maven 有系統瞭解的同學

文章思路

本文先會說下 maven 的幾個基本概念:依賴,倉庫,生命週期和插件、
然後是maven 的聚合和繼承、
然後再說 settings 文件和 pom 文件的相關配置、
最後再列出常用插件及使用 maven 遇到的一些問題及解決辦法

第一部分-依賴

傳遞依賴

A–>B–>C 當前項目爲A,A依賴於B,B依賴於C,那麼 A 依賴於 C

依賴範圍

如果 A-> B ,B 依賴於 junit 包,但 B 的 junit 包配置的 <scope>test</scope>,則 junit 不會被 A 依賴。

常用的依賴範圍有

  • compile (默認)

表示被依賴項目需要參與當前項目的編譯,還有後續的測試,運行週期也參與其中,是一個比較強的依賴。打包的時候通常需要包含進去

  • test

不會有傳遞依賴,也不會打包,依賴項目僅僅參與測試相關的工作,包括測試代碼的編譯和執行,例如:junit

  • provided

參與編譯,測試,運行,但打包的時候不會打進去,如 servlet-api

  • runtime

表示被依賴項目無需參與項目的編譯,不過後期的測試和運行週期需要其參與。與compile相比,跳過了編譯而已。例如JDBC驅動,適用運行和測試階段

  • system

從參與度來說,和provided相同,不過被依賴項不會從maven倉庫下載,而是從本地文件系統拿。需要添加systemPath的屬性來定義路徑

依賴仲裁

最短路徑原則

A->B->C->common1.1.jar
A->common1.0.jar

那麼A最終會依賴common1.0.jar

加載先後原則

A->B
A->C
B->common1.0.jar
C->common1.1.jar

A同時依賴B和C,那麼B和C誰先加載,就依賴誰的common.jar

排除依賴傳遞

一般用於去除一些無用的依賴,或使用最新的依賴包;如 spring 和 hibernate 都會使用 slf4j ,可以自行決定是用 spring 依賴的,還是用 hibernate 依賴的,或者兩者都不用,使用最新的。

比如spring-core排除commons-loggoing

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>${spring.version}</version>
  <exclusions>
    <exclusion>
      <artifactId>commons-logging</artifactId>
      <groupId>commons-logging</groupId>
    </exclusion>
  </exclusions>
</dependency>

第二部分-倉庫

maven 的倉庫分爲本地倉庫、私服、和遠程倉庫,倉庫中放置的是 jar 包和 插件。

查找方式:本地->私服->遠程

私服對於個人開發是不需要的,但對於團隊開發是必須的;因爲項目肯定會分爲各個模塊,每個人開發的模塊需要部署到私服上去,對方纔能訪問到。

pom 中配置倉庫(個人用或開源項目)

<repositories>
    <!--配置阿里雲的倉庫,用於下載常用 jar 包-->
    <repository>
          <id>public</id>
        <name>aliyun nexus</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <releases><enabled>true</enabled></releases>
    </repository>
    <!--配置公司倉庫,用於下載其它模塊包-->
    <repository>
          <id>company</id>
        <name>company nexus</name>
        <url>http://company/nexus/content/groups/public/</url>
        <releases><enabled>true</enabled></releases>
        <snapshots><enabled>true</enabled></snapshots>    <!--這個默認是 false 需要自己打開 -->
    </repository>
</repository>

<!--配置插件倉庫-->
<pluginRepositories>
    <pluginRepository>
        <id>public</id>
        <name>aliyun nexus</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <releases><enabled>true</enabled></releases>
        <snapshots><enabled>false</enabled></snapshots>
    </pluginRepository>
</pluginRepositories>

將倉庫配置到 settings 文件中(公司用項目)

<profiles>
    <profile>
        <id>repo</id>
         <repositories>
           <repository>
             <id>public</id>
             <name>aliyun nexus</name>
             <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
             <releases><enabled>true</enabled></releases>
           </repository>
         </repositories>
   </profile>
   
    <profile>
      <id>env-dev</id>

      <activation>
        <property>
          <name>target-env</name>
          <value>dev</value>
        </property>
      </activation>

      <properties>
        <tomcatPath>/path/to/tomcat/instance</tomcatPath>
      </properties>
    </profile>
</profiles>

<!--激活屬性配置,可以激活多個-->
<activeProfiles>
    <activeProfile>repo</activeProfile>
    <activeProfile>env-dev</activeProfile>
</activeProfiles>

將開發的模塊佈置到私服

在 pom 中配置發佈的地址,在 settings 中配置發佈的用戶名和密碼。
pom 配置發佈地址

<distributionManagement>
   <repository>
       <id>server-rel-id</id>    <!--這個 id 需要和 servers 中的 id 一致-->
       <name>release-publish</name>
       <url>http://company/public</url>
   </repository>
   <snapshotRepository>
       <id>server-rel-id-snapshot</id>
       <name>release-publish</name>
       <url>http://company/public</url>
   </snapshotRepository>
</distributionManagement>

settings 中配置用戶名密碼

<servers>
    <server>
      <id>server-rel-id</id>
      <username>repouser</username>
      <password>repopwd</password>
    </server>
    <server>
      <id>server-rel-id-snapshot</id>
      <username>repouser</username>
      <password>repopwd</password>
    </server>
</servers>

常用倉庫

  • 阿里雲倉庫
<repository>
      <id>public</id>
    <name>aliyun nexus</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <releases><enabled>true</enabled></releases>
</repository>

第三部分-生命週期和插件

maven 的生命週期是抽象的,具體的實現由插件完成。

Maven定義了三套生命週期:clean、default、site,每個生命週期都包含了一些階段(phase)插件的目標 綁定到生命週期的階段來完成任務。三套生命週期相互獨立,但各個生命週期中的phase卻是有順序的,且後面的 phase 依賴於前面的 phase。執行某個phase時,其前面的phase會依順序執行,但不會觸發另外兩套生命週期中的任何phase。
比如執行package,前面的test、comiple等會運行。
在這裏插入圖片描述

clean生命週期

  • pre-clean :執行清理前的工作;
  • clean :清理上一次構建生成的所有文件(target);
  • post-clean :執行清理後的工作

default生命週期

default生命週期是最核心的,它包含了構建項目時真正需要執行的所有步驟。

  • process-resources :複製和處理資源文件到target目錄,準備打包;
  • compile :編譯項目的源代碼;
  • test-compile :編譯測試源代碼;
  • test :運行測試代碼;
  • package :打包成jar或者war或者其他格式的分發包;
  • install :將打好的包安裝到本地倉庫,供其他項目使用;
  • deploy :將打好的包安裝到遠程倉庫,供其他項目使用;

site生命週期

  • pre-site
  • site :生成項目的站點文檔;
  • post-site
  • site-deploy :發佈生成的站點文檔

插件的目標

一個插件通常可以完成多個任務,每一個任務就叫做插件的一個目標。如執行mvn install命令時,調用的插件和執行的插件目標如下:

在這裏插入圖片描述

將插件綁定到生命週期

Maven的生命週期是抽象的,實際需要插件來完成任務,這一過程是通過將插件的目標(goal)綁定到生命週期的具體階段(phase)來完成的。如:將maven-compiler-plugin插件的compile目標綁定到default生命週期的compile階段,完成項目的源代碼編譯:

在這裏插入圖片描述

舉個例子,使用源碼生成插件,並綁定到 package 階段

<plutins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-source-plugin</artifactId>
           <version>2.1.2</version>
           <executions>
               <execution>
                   <phase>package</phase>
                   <goals><goal>jar-no-fork</goal></goals>
               </execution>
           </executions>
    </plugin>
</plugins>

第四部分-maven 的聚合和繼承

聚合是爲了解決模塊的依賴關係,並且方便統一打包和測試。

對於每一個模塊來說,都來寫一遍屬性配置,依賴配置,插件配置,倉庫配置未免太麻煩 ,而且不好管理;所以一般都會有一個父項目來配置好這麼東西,子項目不需要關心jar 版本,插件配置等信息。

一般把聚合和繼承這兩個統一放到一個 pom 文件中,做爲父項目存在,這兩個需要的打包方式爲 pom 。

<!--打包方式需要配置爲 pom -->
<packaging>pom</packaging>

<!-- 聚合的模塊列表,不需要關心順序,maven 會自動根據依賴關係順序-->
<modules>
    <module>modul1</module>
    <module>modul2</module>
</modules>

<!--配置子項目可能需要用到的 jar 包-->
<dependencyManagement>
    <dependencies>
    </dependencies>
</dependencyManagement>

<!--配置子項目可能需要用到的 插件-->
<pluginManagement>
     <plugins>
    </plugins>
</pluginManagement>

最後一部分-常用插件和項目中遇到的一些問題

第三方包的安裝

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>

jdk 版本的問題

因爲 maven 用的 jdk 一般版本都比較老,所以造成老是提示 jdk 版本不對的問題,這樣解決。

<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>
    </configuration>
</plugin>

打包時跳過測試

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
        <skipTests>true</skipTests>
    </configuration>
</plugin>

mybatis mapper 文件沒有編譯問題

把 mapper xml 文件放到同 mapper 同一級的時候 ,經常用找不到 xml 文件的問題,這樣解決,放到 build 子節點下

<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
    </resource>
</resources>

servlet3 不需要 web.xml 問題

<properties>
     <failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

常用插件

  • 打包帶上源碼,這個其實還挺好用的
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-source-plugin</artifactId>
    <version>2.1.2</version>
    <executions>
       <execution>
            <phase>package</phase>
            <goals><goal>jar-no-fork</goal></goals>
        </execution>
    </executions>
</plugin>
  • 把java工程打包成爲一個可執行的jar包
<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>3.0.0</version>
  <configuration>
    <archive>
      <manifest>
        <mainClass>com.learn.MyApp</mainClass>
      </manifest>
    </archive>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
</plugin>
  • tomcat 插件
<plugin>
  <groupId>org.apache.tomcat.maven</groupId>
  <artifactId>tomcat7-maven-plugin</artifactId>
  <version>2.2</version>
  <configuration>
      <port>8080</port>
      <path>/</path>
  </configuration>
</plugin>
  • jetty 插件
<plugin>
      <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.2.11.v20150529</version>
    <configuration>
        <httpConnector>
            <port>8081</port>
        </httpConnector>
        <webAppSourceDirectory>src/main/webapp</webAppSourceDirectory>
        <scanIntervalSeconds>10</scanIntervalSeconds>
        <webApp>
            <contextPath>/sanritools</contextPath>
        </webApp>
    </configuration>
</plugin>

一點小推廣

Excel 通用導入導出,支持 Excel 公式
https://blog.csdn.net/sanri1993/article/details/100601578

使用模板代碼 ,從數據庫生成代碼 ,及一些項目中經常可以用到的小工具
https://blog.csdn.net/sanri1993/article/details/98664034

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章