Maven是一個Java平臺下項目管理及自動構建工具,抽象出了Java平臺下的軟件工程構建的標準生命週期,並提供了提供了各個生命週期下的自動化工具。git
Maven對生命週期的抽象是流程順序化的,也就是說你要進行到某個週期的某個階段,那麼這個階段以前的所有階段都會被執行.apache
清理週期的目的在於去除掉上次構建生成的資源,好比的.class等等,保證構建最後使用的輸出資源是當前工做空間內的處理輸出資源;包含的主要流程:clean安全
默認週期包含了的主要流程:校驗(validate),編譯(compile),測試(test),打包(package),驗證(verify),安裝到本地倉庫(install),發佈到遠程倉庫(deploy)。服務器
也叫站點生成周期,主要包括兩個流程:第一輩子成工程的文檔,第二部署到服務器上去;網絡
Maven規定了構建週期的每一個階段順序執行及某個階段應該幹什麼的標準,也就是完成了對構建流程的抽象並制定了流程的順序標準,那麼這些標準的實現者是誰呢?插件(plugin),插件具體的完成每一個流程每一個階段的具體的工做。ssh
一個插件能夠有多種功能,每種功能稱之爲一個目標(goal);好比compile插件能夠支持編譯功能代碼(goal-compile)和 編譯測試代碼(goal-testCompile);maven
好比下面的編譯插件提供了compile和testCompile兩個功能,並分別綁定到了default聲明週期的<phase>compile</phase>以及<phase>test-compile</phase>;這就是告訴Maven工具在執行到<phase>compile</phase>和<phase>test-compile</phase>階段時,要去調用maven-compiler-plugin的compile或者testCompile功能。ide
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <executions> <execution> <id>default-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </execution> <execution> <id>default-testCompile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </execution> </executions> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin>
mvn test
:意思是告訴mvn執行到<phasese>test</phasese>,那麼在以前的全部階段及每一個階段綁定的每個goal都會被執行;工具
mvn compiler:compile
:意思是告訴mvn 值執行這個compiler插件的compile功能,注意這樣只會執行這個插件的這個功能,其餘插件的功能不不會執行; 這裏補充一些插件名解析的規則,對於一個插件的名字K,maven會把這個插件名解析成maven-K-plugin(maven本身提供的默認插件)及K-maven-plugin(第三方自定義插件),並從當前工程有效pom.xml的去尋找artifactId(請參看下面的Jar的座標)爲maven-K-plugin或者K-maven-plugin的插件,K就是插件的別名,學習
Maven爲不一樣的類型的工程的每一個階段提供了默認的插件來實現約定的功能。 (工程的類型由pom文件的<packaging></packaging> 指定,通常爲jar、war、pom==多 module的狀況下)
基本上在每個工程中都不可避免的會加入多個jar做爲lib,而這些lib的中jar的版本兼容性是一個使人至關頭痛的問題:A.jar依賴C.jar,B.jar也依賴C.jar,可是依賴的分別是C的不一樣版本。
一個兩個還好能夠上三者官網上看一下解決下衝突,若是不少這樣的狀況,是否是很想死?甚至若是你不是很熟悉每一個Jar的話,有衝突你甚至都發現不了。
最好出現一個約定Jar版本管理系統,自動的解決或者提示衝突在哪裏。Maven提供這樣一個系統(包含一個內置的中央倉庫和Jar的座標系)來解決這個問題:
每一個Jar必須聲明本身的x(groupId:組織Id)y(artifactId:工程Id)z(version:工程版本)三個座標,使用的依賴也必須明確的聲明其xyz座標,這樣Maven就能夠彙總查看整個系統具體使用哪一個Jar的哪一個版本,若是出現了同Jar不一樣版本(同XY不一樣Z)的狀況就報告衝突。
這個之後再補充,我通常在衝突的dependency裏面直接exclusion掉,而後從新指定一個較高級的版本。
也就是保存所有的Jar的服務器,maven本身提供了一箇中央倉庫,但通常企業開發中都會本身搭建nexus私服。
也就是下面setting.xml裏面指定的本地路徑。
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <!--指定你本地倉庫的位置--> <localRepository>E:\JarLib</localRepository> <!-- 是否啓用交互模式:默認true;交互模式是指當maven須要你的輸入時會讀取你在console的輸入的數據 <interactiveMode>true</interactiveMode> --> <!-- offline 是否在離線模式運行?默認false <offline>false</offline> --> <!-- 插件組的Id:plugin 的groupId 內置了 "org.apache.maven.plugins" and "org.codehaus.mojo" ,不須要使用自定插件的人員無需修改 --> <pluginGroups> <!-- <pluginGroup>com.your.plugins</pluginGroup> --> </pluginGroups> <!-- 網絡代理:默認使用第一個,實際上基本不須要;好比你要去某個特定的倉庫下載Jar而這個倉庫又不在公網須要經過代理去下載,這裏配置代理的安全密碼驗證的東西 --> <proxies> <!-- <proxy> <id>optional</id> <active>true</active> <protocol>http</protocol> <username>proxyuser</username> <password>proxypass</password> <host>proxy.host.net</host> <port>80</port> <nonProxyHosts>local.net|some.host.com</nonProxyHosts> </proxy> --> </proxies> <!-- 訪問某些服務的票據帳戶密碼或者sshkey等,注意這些Id應該和倉庫的Id同樣,實際上Maven也只會訪問這些服務器 --> <servers> <server> <id>nexus-private-repo</id> <username>admin</username> <password>adminpass</password> </server> </servers> <!-- 遠程倉庫的鏡像,若是從某個倉庫下載Jar下不下來的時候,好比網絡太垃圾,若是存在這個倉庫的鏡像maven則會轉到這個鏡像來下載。 --> <mirrors> <!-- 注意mirrodId 必須unique <mirror> <id>mirrorId</id> <mirrorOf>repositoryId</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://my.repository.com/repo/path</url> </mirror> --> </mirrors> <!-- 配置項組,在知足某些條件時激活,配置組中定義的配置會增長到Pom.xml中,這些配置項會被Pom中定義的各個插件使用。通常的都會配置各個工程通用的項目配置及保密的配置等等 --> <profiles> <profile> <id>nexus-private-repo</id> <repositories> <!--好比這個倉庫的位置--> <repository> <id>nexus-private-repo</id> <name>nexus-private-repo</name> <url>http://127.0.0.1:8090/repository/maven-snapshots</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> </profiles> <!-- 激活的profile,會被全部的工程繼承使用, --> <activeProfiles> <activeProfile>nexus-private-repo</activeProfile> </activeProfiles> </settings>
<?xml version="1.0" encoding="GBK"?> <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> <!--多module開發時指定的具體的父POM,父POM的配置大部分都會被繼承--> <parent> <groupId>com.aruforce</groupId> <artifactId>mvn-test</artifactId> <version>1.0.0-RELEASE</version> </parent> <!--下面設定本身的座標系--> <groupId>com.aruforce</groupId><!----> <artifactId>common</artifactId> <version>1.0.1-SNAPSHOT</version> <!--設定本身的工程類型--> <packaging>Jar</packaging> <!--一些配置項目,可使用${tag}獲取值,注意父POM的中的定義項目不會被繼承下來--> <properties> <jdk.version>1.8</jdk.version> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <!--jar deploy的遠程倉庫位置--> <distributionManagement> <repository> <id>nexus-private-repo</id> <name>Fruit Releases</name> <url>http://127.0.0.1:8090/repository/maven-releases</url> </repository> <snapshotRepository> <id>nexus-private-repo</id> <name>Fruit Snapshots</name> <url>http://127.0.0.1:8090/repository/maven-snapshots</url> </snapshotRepository> </distributionManagement> <!--共用的依賴管理,若是在下面的以來配置中修改其中的配置的話(主要是版本),就是管理中指定的版本--> <dependencyManagement> <dependencies> <!--junit 插件--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <!--插件的有效級別:System,provide,test,compile,runtime等等,涉及到插件的依賴傳遞,默認值是compile compile:編譯範圍依賴在全部的classpath中可用,同時它們也會被打包。 provided:provided 依賴只有在當JDK 或者一個容器已提供該依賴以後才使用.已提供範圍的依賴在編譯classpath(不是運行時)可用。它們不是傳遞性的,也不會被打包。 runtime:runtime 依賴在運行和測試系統的時候須要,但在編譯的時候不須要。好比,你可能在編譯的時候只須要JDBC API JAR,而只有在運行的時候才須要JDBC驅動實現。 test:test範圍依賴 在通常的編譯和運行時都不須要,它們只有在測試編譯和測試運行階段可用。 system:system範圍依賴與provided 相似,可是你必須顯式的提供一個對於本地系統中JAR 文件的路徑。不要使用它。 optional:可選的,classpath有沒有都行。 --> <scope>test</scope> </dependency> </dependencies> <dependency> <groupId>com.aruforce</groupId> <artifactId>dependA</artifactId> <version>1.0.0-RELEASE</version> <scope>compile</scope><!--覆蓋上面的配置--> <exclusions> <exclusion> <groupId>com.aruforce</groupId> <artifactId>ABdependC</artifactId><!--依賴1.2.0版本--> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.aruforce</groupId> <artifactId>dependB</artifactId> <version>1.0.0-RELEASE</version> <scope>compile</scope><!--覆蓋上面的配置--> <exclusions> <exclusion> <groupId>com.aruforce</groupId> <artifactId>ABdependC</artifactId><!--依賴1.0.0版本--> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.aruforce</groupId> <artifactId>ABdependC</artifactId> <version>1.2.0-RELEASE</version><!---暫且先試下1.2.0版本若是版本不行就換其餘的,都不行git fork modify deploy到nexus 從新引入--> <scope>compile</scope> </dependency> </dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope><!--覆蓋上面的配置--> </dependency> </dependencies> <!--聲明週期的相關配置--> <build> <!--構建過程的通用配置項目--> <resources> <resource> <filtering>${pfile}</filtering> <directory>src/main/resources</directory> </resource> </resources> <testResources> <testResource> <filtering>false</filtering> <directory>src/test/resources</directory> </testResource> </testResources> <finalName>${artifactId}-${version}</finalName> <filters> <filter>${profile}</filter> </filters> <plugins> <plugin> <!--關於插件的配置項,能夠去插件的官方網站查看使用說明,實際上不多幾乎沒有,長配置的只有編譯插件,及reources插件(主要是根據filrters裏面的配置在打包前處理源配置文件生成不一樣環境須要的配置)--> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.3</version> </plugin> </plugins> </build> <!--不一樣配置項 mvn excutable -P profileId 這個profile裏面的配置會生效--> <profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <pfile>dev.properties</pfile> </properties> </profile> <profile> <id>test</id> <activation> <activeByDefault>false</activeByDefault> </activation> <properties> <pfile>test.properties</pfile> </properties> </profile> </profiles> </project>
那些安裝配置啊什麼的不值得寫;高級點的須要本身寫插件的部分還沒遇到;插件的配置項目不太應該寫在這裏並且也說明怎麼去查找;依賴的版本版本衝突排解方法也夠簡單粗暴。至於使用說明,讀完也基本上有感受,本身試着擺弄幾個類型的工程吧 jar->war->多module。。。基本上也就這個學習使用流程吧。。。剩下的私服搭建 通常就是nexus了。。。這個工具的安裝配置。。看看Tutorial什麼也就能夠了。。。
開始學習使用maven的時候弄不清楚概念確實很亂很蛋疼。。。總想放棄溜了。。。學完後發現maven這些也是解決特定問題。。。知道問題在哪。。知道運做邏輯後。。看着那些配置項也就明白什麼意思了。。。