(十三)Maven插件解析運行機制

来源:http://www.cnblogs.com/AlanLee/archive/2016/12/21/6208562.html
-Advertisement-
Play Games

這裡給大家詳細說一下Maven的運行機制,讓大家不僅知其然,更知其所以然。 1.插件保存在哪裡? 與我們所依賴的構件一樣,插件也是基於坐標保存在我們的Maven倉庫當中的。在用到插件的時候會先從本地倉庫查找插件,如果本地倉庫沒有則從遠程倉庫查找插件並下載到本地倉庫。 與普通的依賴構件不同的是,Mav ...


這裡給大家詳細說一下Maven的運行機制,讓大家不僅知其然,更知其所以然。

 

1.插件保存在哪裡?

與我們所依賴的構件一樣,插件也是基於坐標保存在我們的Maven倉庫當中的。在用到插件的時候會先從本地倉庫查找插件,如果本地倉庫沒有則從遠程倉庫查找插件並下載到本地倉庫。

與普通的依賴構件不同的是,Maven會區別對待普通依賴的遠程倉庫與插件的遠程倉庫。前面提到的配置遠程倉庫只會對普通的依賴有效果。當Maven需要的插件在本地倉庫不存在時是不會去我們以前配置的遠程倉庫查找插件的,而是需要有專門的插件遠程倉庫,我們來看看怎麼配置插件遠程倉庫,在pom.xml加入如下內容:

 1 <pluginRepositories>
 2         <pluginRepository>
 3             <id>nexus</id>
 4             <name>nexus</name>
 5             <url>http://192.168.0.70:8081/content/groups/public/</url>
 6             <releases>
 7                 <enabled>true</enabled>
 8             </releases>
 9             <snapshots>
10                 <enabled>true</enabled>
11             </snapshots>
12         </pluginRepository>
13 </pluginRepositories>

大家可以發現,除了pluginRepositories和pluginRepository與以前配置遠程倉庫不同以外,其他的都是一樣的,所代表的含義也是一樣的。Maven的父POM中也是有內置一個插件倉庫的,我現在用的電腦安裝的是Maven 3.0.4版本,我們可以找到這個文件:${M2_HOME}/lib/maven-model-builder-3.0.4.jar,打開該文件,能找到超級父POM:\org\apache\maven\model\pom-4.0.0.xml,它是所有Maven POM的父POM,所有Maven項目都繼承該配置。


我們來看看預設的遠程插件倉庫配置的是啥:

 1 <pluginRepositories>
 2     <pluginRepository>
 3       <id>central</id>
 4       <name>Central Repository</name>
 5       <url>http://repo.maven.apache.org/maven2</url>
 6       <layout>default</layout>
 7       <snapshots>
 8         <enabled>false</enabled>
 9       </snapshots>
10       <releases>
11         <updatePolicy>never</updatePolicy>
12       </releases>
13     </pluginRepository>
14 </pluginRepositories>

預設插件倉庫的地址就是中央倉庫咯,它關閉了對snapshots的支持,防止引入snapshots版本的插件而導致不穩定的構件。一般來說,中央倉庫所包含的插件完全能夠滿足我們的需要,只有在少數情況下才要配置,比如項目的插件無法在中央倉庫找到,或者自己編寫了插件才會配置自己的遠程插件倉庫。

 

2.插件命令運行解析

我們來看這樣一個命令:

mvn compiler:compiler

這個命令會調用maven-compiler-plugin插件並執行compiler目標,大家有木有覺得很神奇?我們在pom.xml中配置插件往往是這樣:

1         <plugin>
2             <groupId>org.apache.maven.plugins</groupId>
3             <artifactId>maven-compiler-plugin</artifactId>
4             <version>3.1</version>
5             <configuration>
6                 <source>1.7</source> <!-- 源代碼使用的開發版本 -->
7                 <target>1.7</target> <!-- 需要生成的目標class文件的編譯版本 -->
8             </configuration>
9         </plugin>    

maven-compiler-plugin插件預設執行的目標為compiler,那麼命令的完整寫法應該是:mvn org.apache.maven.plugins:maven-compiler-plugin:3.1:compiler才對啊,為什麼mvn compiler:compiler也能完美的執行?

 

我們來看看Maven到底幹了些神馬來做到如此牛逼的功能:

 

①插件預設groupId

Maven預設以org.apache.maven.plugins作為groupId,到這裡我們的命令應該是長這樣的:

mvn org.apache.maven.plugins:compiler:compiler

我們也可以配置自己預設的groupId,在Maven的settings.xml中添加如下內容,前面提過最好將settings.xml放在用戶目錄的.m2下:

1 <pluginGroups>
2     <!-- pluginGroup
3      | Specifies a further group identifier to use for plugin lookup.
4     <pluginGroup>com.your.plugins</pluginGroup>
5     -->
6     <pluginGroup>com.your.plugins</pluginGroup>
7 </pluginGroups>

不過說實在的,沒必要動他就別去動他了,我們用Maven只是解決一些剛需的問題,沒必要的設置就儘量不去動他,別把Maven搞得太複雜,雖然Maven的卻有點小複雜,跟大家扯這些只是希望大家能夠對maven理解的更深入那麼一點點,並不是建議大家一定要去使用某些東西,大家在平時的開發中要謹記這一點。

 

②我們來看看Maven插件遠程倉庫的元數據org/apache/maven/plugins/maven-metadata.xml,Maven預設的遠程倉庫是http://repo.maven.apache.org/maven2/,所有插件元數據路徑則是:http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml,我們找到compiler插件的元數據,如圖:

這裡會根據prefix指定的首碼找到對應的artifactId,到這裡我們的命令應該長成了這樣:

mvn org.apache.maven.plugins:maven-compiler-plugin:compiler

 

③我們再根據groupId和artifactId找到maven-compiler-plugin插件單個的元數據,路徑為http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml,如圖:

maven將所有的遠程插件倉庫及本地倉庫元數據歸併後,就能找到release的版本(maven3後為了保證項目構建的穩定性預設使用release版本),到這裡命令就被擴展成為這樣:

mvn org.apache.maven.plugins:maven-compiler-plugin:3.6.0:compiler

如果執行的是mvn compiler:compiler命令,由於maven-compiler-plugin的最新版本已經到了3.6.0,則預設會使用此版本。最後的compiler則是插件要執行的目標咯,看到這裡大家應該明白mvn compiler:compiler命令為什麼能夠得到完美的運行了吧。

 

3.Maven超級POM

最後給大家把超級父POM貼出來,再次強調,如果我們沒有在自己的pom.xml中配置相應的內容,則預設會使用超級父POM配置的內容。我現在用的電腦安裝的是Maven 3.0.4版本,我們可以找到這個文件:${M2_HOME}/lib/maven-model-builder-3.0.4.jar,打開該文件,能找到超級父POM:\org\apache\maven\model\pom-4.0.0.xml,它是所有Maven POM的父POM,所有Maven項目都繼承該配置。

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 
  3 <!--
  4 Licensed to the Apache Software Foundation (ASF) under one
  5 or more contributor license agreements.  See the NOTICE file
  6 distributed with this work for additional information
  7 regarding copyright ownership.  The ASF licenses this file
  8 to you under the Apache License, Version 2.0 (the
  9 "License"); you may not use this file except in compliance
 10 with the License.  You may obtain a copy of the License at
 11 
 12     http://www.apache.org/licenses/LICENSE-2.0
 13 
 14 Unless required by applicable law or agreed to in writing,
 15 software distributed under the License is distributed on an
 16 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17 KIND, either express or implied.  See the License for the
 18 specific language governing permissions and limitations
 19 under the License.
 20 -->
 21 
 22 <!-- START SNIPPET: superpom -->
 23 <project>
 24   <modelVersion>4.0.0</modelVersion>
 25 
 26   <repositories>
 27     <repository>
 28       <id>central</id>
 29       <name>Central Repository</name>
 30       <url>http://repo.maven.apache.org/maven2</url>
 31       <layout>default</layout>
 32       <snapshots>
 33         <enabled>false</enabled>
 34       </snapshots>
 35     </repository>
 36   </repositories>
 37 
 38   <pluginRepositories>
 39     <pluginRepository>
 40       <id>central</id>
 41       <name>Central Repository</name>
 42       <url>http://repo.maven.apache.org/maven2</url>
 43       <layout>default</layout>
 44       <snapshots>
 45         <enabled>false</enabled>
 46       </snapshots>
 47       <releases>
 48         <updatePolicy>never</updatePolicy>
 49       </releases>
 50     </pluginRepository>
 51   </pluginRepositories>
 52 
 53   <build>
 54     <directory>${project.basedir}/target</directory>
 55     <outputDirectory>${project.build.directory}/classes</outputDirectory>
 56     <finalName>${project.artifactId}-${project.version}</finalName>
 57     <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
 58     <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
 59     <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
 60     <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
 61     <resources>
 62       <resource>
 63         <directory>${project.basedir}/src/main/resources</directory>
 64       </resource>
 65     </resources>
 66     <testResources>
 67       <testResource>
 68         <directory>${project.basedir}/src/test/resources</directory>
 69       </testResource>
 70     </testResources>
 71     <pluginManagement>
 72       <!-- NOTE: These plugins will be removed from future versions of the super POM -->
 73       <!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
 74       <plugins>
 75         <plugin>
 76           <artifactId>maven-antrun-plugin</artifactId>
 77           <version>1.3</version>
 78         </plugin>
 79         <plugin>
 80           <artifactId>maven-assembly-plugin</artifactId>
 81           <version>2.2-beta-5</version>
 82         </plugin>
 83         <plugin>
 84           <artifactId>maven-dependency-plugin</artifactId>
 85           <version>2.1</version>
 86         </plugin>
 87         <plugin>
 88           <artifactId>maven-release-plugin</artifactId>
 89           <version>2.0</version>
 90         </plugin>
 91       </plugins>
 92     </pluginManagement>
 93   </build>
 94 
 95   <reporting>
 96     <outputDirectory>${project.build.directory}/site</outputDirectory>
 97   </reporting>
 98 
 99   <profiles>
100     <!-- NOTE: The release profile will be removed from future versions of the super POM -->
101     <profile>
102       <id>release-profile</id>
103 
104       <activation>
105         <property>
106           <name>performRelease</name>
107           <value>true</value>
108         </property>
109       </activation>
110 
111       <build>
112         <plugins>
113           <plugin>
114             <inherited>true</inherited>
115             <artifactId>maven-source-plugin</artifactId>
116             <executions>
117               <execution>
118                 <id>attach-sources</id>
119                 <goals>
120                   <goal>jar</goal>
121                 </goals>
122               </execution>
123             </executions>
124           </plugin>
125           <plugin>
126             <inherited>true</inherited>
127             <artifactId>maven-javadoc-plugin</artifactId>
128             <executions>
129               <execution>
130                 <id>attach-javadocs</id>
131                 <goals>
132                   <goal>jar</goal>
133                 </goals>
134               </execution>
135             </executions>
136           </plugin>
137           <plugin>
138             <inherited>true</inherited>
139             <artifactId>maven-deploy-plugin</artifactId>
140             <configuration>
141               <updateReleaseInfo>true</updateReleaseInfo>
142             </configuration>
143           </plugin>
144         </plugins>
145       </build>
146     </profile>
147   </profiles>
148 
149 </project>
150 <!-- END SNIPPET: superpom -->

很多插件是超級父POM當中並沒有配置的,如果用戶使用某個插件時沒有設定版本,那麼則會根據我上述所說的規則去倉庫中查找可用的版本,然後做出選擇。在Maven2中,插件的版本會被解析至latest。也就是說,當用戶使用某個非核心插件且沒有聲明版本的時候,Maven會將版本解析為所有可用倉庫中的最新版本,latest表示的就是最新版本,而這個版本很有可能是快照版本。

當插件為快照版本時,就會出現潛在的問題。昨天還好好的,可能今天就出錯了,其原因是這個快照版本發生了變化導致的。為了防止這類問題,Maven3調整瞭解析機制,當插件沒有聲明版本的時候,不再解析至latest,而是使用release。這樣就避免了由於快照頻繁更新而導致的不穩定問題。但是這樣就好了嗎?不寫版本號其實是不推薦的做法,例如,我使用的插件發佈了一個新版本,而這個release版本與之前的版本的行為發生了變化,這種變化依然可能導致我們項目的癱瘓。所以使用插件的時候,應該一直顯式的設定版本,這也解釋了Maven為什麼要在超級父POM中為核心插件設定版本咯。

 

結束語:當你感到悲哀痛苦時,最好是去學些什麼東西,學習會使你從悲哀痛苦中走出來,學習會使你永遠立於不敗之地。說實在的,不要太在意眼前所發生的一切,更重要的是培養自己的個人能力,如今待在公司亦或者跳槽,決定你能不能繼續走下去的一定是你的個人能力,作為年輕人,在公司更看重的不應該是薪水的高低,而是公司能給你帶來多大的成長環境。找個好的公司其實不比找個合適的女朋友簡單,作為年輕人我們一定要不斷的提升個人能力,就跟找女朋友似的,往往就是你越有本事就越能夠不將就,你個人能力越強則越有選擇公司的資本。

 

可愛博主:AlanLee

博客地址:http://www.cnblogs.com/AlanLee

本文出自博客園,歡迎大家加入博客園。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 你真的懂異常(Exception)嗎? 目錄 異常介紹 異常的特點 怎樣使用異常 處理異常的 try-catch-finally 捕獲異常的 Catch 塊 釋放資源的 Finally 塊 捕獲異常的 Catch 塊 釋放資源的 Finally 塊 一、異常介紹 我們平時在寫程式時,無意中(或技術不 ...
  • 隨著公司業務的發展,網站的日活數也逐漸增多,以前只需要考慮將所需要的功能實現就行了,當日活越來越大的時候,就需要考慮對伺服器的資源使用消耗情況有一個清楚的認知。 最近老是發現資料庫的連接數如果幾天不重啟伺服器,就經常會發現有很多sleep很久的資料庫連接,對資料庫伺服器的性能有較大的影響。所以需要知 ...
  • 一.簡介 在網頁應用中,你經常需要在處理完表單或其它類型的用戶輸入後,顯示一個通知消息(也叫做“flash message”)給用戶 對於這個功能,Django 提供基於Cookie 和會話的消息,無論是匿名用戶還是認證的用戶。 其消息框架允許你臨時將消息存儲在請求中,併在接下來的請求(通常就是下一 ...
  • 線程可以理解為下載的通道,一個線程就是一個文件的下載通道,多線程也就是同時開啟好幾個下載通道。當伺服器提供下載服務時,使用下載者是共用帶寬的,在優先順序相同的情況下,總伺服器會對總下載線程進行平均分配。不難理解,如果你線程多的話,那下載的越快。 現流行的下載軟體都支持多線程,且支持中途暫停下載,再次開 ...
  • 如果運行後如圖的錯,需要進行如下操作來解決: a:打開cmd,輸入netstat -ano 找到本地地址為8080的最後一項的數字,這個數字就是埠號。 b:再輸入taskkill /t /pid 埠號數字 /f 來關閉此進程。 c:註意每個命令後面不要加 ; 結尾,運行以上命令再重新運行工程即可 ...
  • 本文地址 可以拜讀: 從零開始學 Java 分享提綱: 1.java數據結構 1. java數據結構 1)【概述】 Java工具包提供了強大的數據結構。在Java中的數據結構主要包括以下幾種介面和類: 枚舉(Enumeration) 位集合(BitSet) 向量(Vector) 棧(Stack) 字 ...
  • 1、sdk返回值不是int型 1.1 登錄函數調用 def login(ip, port, username, password, device_info, error_code):"""LLONG CLIENT_Login(char *pchDVRIP, WORD wDVRPort,char *p... ...
  • 其實也沒啥好說的 用樹狀數組可以O(logn)的查詢 套一層整體二分就可以做到O(nlngn) 最後用樹鏈剖分讓序列上樹 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...