1、插件
Maven本質(zhì)上是一個(gè)插件框架,它的核心并不執(zhí)行任何具體的構(gòu)建任務(wù),所有這些任務(wù)都交給插件來完成,像編譯是通過maven-compile-plugin實(shí)現(xiàn)的、測(cè)試是通過maven-surefire-plugin實(shí)現(xiàn)的,maven也內(nèi)置了很多插件,所以我們?cè)陧?xiàng)目進(jìn)行編譯、測(cè)試、打包的過程是沒有感覺到。
進(jìn)一步說,每個(gè)任務(wù)對(duì)應(yīng)了一個(gè)插件目標(biāo)(goal),每個(gè)插件會(huì)有一個(gè)或者多個(gè)目標(biāo),例如maven-compiler-plugin的compile目標(biāo)用來編譯位于src/main/java/目錄下的主源碼,testCompile目標(biāo)用來編譯位于src/test/java/目錄下的測(cè)試源碼。
認(rèn)識(shí)上述Maven插件的基本概念有助于理解Maven的工作機(jī)制,不過要想更高效率地使用Maven,了解一些常用的插件還是很有必要的,這可以幫助你避免一不小心重新發(fā)明輪子。多年來Maven社區(qū)積累了大量的經(jīng)驗(yàn),并隨之形成了一個(gè)成熟的插件生態(tài)圈。Maven官方有兩個(gè)插件列表:
- 第一個(gè)列表的GroupId為org.apache.maven.plugins,這里的插件最為成熟,具體地址為:http://maven.apache.org/plugins/index.html
- 第二個(gè)列表的GroupId為org.codehaus.mojo,這里的插件沒有那么核心,但也有不少十分有用,其地址為:http://mojo.codehaus.org/plugins.html。
下面列舉了一些常用的核心插件,每個(gè)插件的如何配置,官方網(wǎng)站都有詳細(xì)的介紹。
一個(gè)插件通常提供了一組目標(biāo),可使用以下語法來執(zhí)行:
mvn [plugin-name]:[goal-name]
例如,一個(gè)Java項(xiàng)目使用了編譯器插件,通過運(yùn)行以下命令編譯
mvn compiler:compile
Maven提供以下兩種類型的插件:
構(gòu)建插件:在生成過程中執(zhí)行,并應(yīng)在pom.xml中的
<build/>元素進(jìn)行配置報(bào)告插件:在網(wǎng)站生成期間執(zhí)行的,應(yīng)該在pom.xml中的
<reporting/>元素進(jìn)行配置
這里僅列舉幾個(gè)常用的插件,每個(gè)插件的如何進(jìn)行個(gè)性化配置在官網(wǎng)都有詳細(xì)的介紹。
<plugins>
<plugin>
<!-- 編譯插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<!-- 發(fā)布插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<!-- 打包插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
</plugin>
<plugin>
<!-- 安裝插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
</plugin>
<plugin>
<!-- 單元測(cè)試插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<!-- 源碼插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1</version>
<!-- 發(fā)布時(shí)自動(dòng)將源碼同時(shí)發(fā)布的配置 -->
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
除了這些核心插件之外,還有很多優(yōu)秀的第三方插件,可以幫助我們快捷、方便的構(gòu)架項(xiàng)目。當(dāng)使用到某些功能或者特性的時(shí)候多加搜索,往往得到讓你驚喜的效果。
例如,項(xiàng)目中使用了Mybatis,就有一款神奇的maven插件,運(yùn)行一個(gè)命令,就可以根據(jù)數(shù)據(jù)庫的表,自動(dòng)生成Mybatis的mapper配置文件以及DAO層接口模板。
在pom.xml中添加plugin:
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/mybatis-generator/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
</plugin>
定義generatorConfig.xml配置文件:
<generatorConfiguration>
<classPathEntry location="/Users/winner/mysql/mysql-connector-java-5.1.36.jar"/>
<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 去掉自動(dòng)生成的注解 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3344/db?characterEncoding=utf8" userId="id" password="password"></jdbcConnection>
<!-- 默認(rèn)false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer true,把JDBC DECIMAL 和
NUMERIC 類型解析為java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 生成映射類-->
<javaModelGenerator targetPackage="com.clf.model" targetProject="/Users/winner/Documents/workspace/project/src/main/java/">
<!-- enableSubPackages:是否讓schema作為包的后綴 -->
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成xml文件-->
<sqlMapGenerator targetPackage="com.clf.mapper" targetProject="/Users/winner/Documents/workspace/project/src/main/resources/">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</sqlMapGenerator>
<!-- 生成mapper interface-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.clf.mapper" targetProject="/Users/winner/Documents/workspace/project/src/main/java/">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaClientGenerator>
<table tableName="table_name" domainObjectName="object_name" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
然后定位到pom.xml所在的路徑下面,運(yùn)行:
mvn mybatis-generator:generate
所有的文件就會(huì)自動(dòng)生成,怎一個(gè)爽字了得。
2、命令
2.1 常用命令
從某種意義上來說,軟件是幫助不懂程序的人來操作計(jì)算機(jī)的,圖形化界面尤其如此。在上個(gè)世紀(jì),比爾蓋茨之所以成為世界首富,微軟之所以IT界的巨鱷,就是因?yàn)閃indows開圖形化操作之先河,并搶先占領(lǐng)了全球市場,笑傲江湖數(shù)十年,至今依然寶刀未老。
誠然,現(xiàn)在幾乎每種軟件都有圖形化界面,用鼠標(biāo)點(diǎn)擊幾下就可以完成操作。Maven也不例外,在各類IDE中都有成熟的插件來簡化操作。
但是作為開發(fā)人員,應(yīng)該時(shí)刻保持著一種職業(yè)神圣感,我們擁有上帝之手,借助程序來操縱著計(jì)算機(jī)世界的一切。我們與計(jì)算機(jī)交流的正途是通過命令,而不是圖形化界面。東漢末年分三國,為什么?很大一部分因素就是因?yàn)榛鹿偌瘓F(tuán)隔斷了皇權(quán)與士大夫之間的直接聯(lián)系!圖形化界面是人機(jī)交互的第三者,阻止著我們與計(jì)算機(jī)的親密接觸,長此以往,必生間隙。吾輩不可不慎也哉!
總而言之,圖形化界面不是不能用,因?yàn)樗_實(shí)有好處,可以提高開發(fā)效率,規(guī)避操作失誤。我的觀點(diǎn)是,用它,但是不要依賴它。
作為開發(fā)利器的maven,為我們提供了十分豐富的命令,了解maven的命令行操作并熟練運(yùn)用常見的maven命令還是十分必要的。無論多先進(jìn)多炫的圖形化界面,底層都得靠maven命令來驅(qū)動(dòng)。知其然,知其所以然,方能百戰(zhàn)不殆。
在講解插件的那一篇文章中已經(jīng)說過,maven的所有任務(wù)都是通過插件來完成的,它本身只是一個(gè)空空如也的框架,不具備執(zhí)行具體任務(wù)的能力。
maven的命令格式如下:
mvn [plugin-name]:[goal-name]
該命令的意思是:執(zhí)行“plugin-name”插件的“goal-name”目標(biāo)(或者稱為動(dòng)作)。
用戶可以通過兩種方式調(diào)用Maven插件目標(biāo)。
第一種方式是將插件目標(biāo)與生命周期階段(lifecycle phase)綁定,這樣用戶在命令行只是輸入生命周期階段而已,例如Maven默認(rèn)將maven-compiler-plugin的compile目標(biāo)與compile生命周期階段綁定,因此命令mvn compile實(shí)際上是先定位到compile這一生命周期階段,然后再根據(jù)綁定關(guān)系調(diào)用maven-compiler-plugin的compile目標(biāo)。
第二種方式是直接在命令行指定要執(zhí)行的插件目標(biāo),例如mvn archetype:generate 就表示調(diào)用maven-archetype-plugin的generate目標(biāo),這種帶冒號(hào)的調(diào)用方式與生命周期無關(guān)。
常用的maven命令如下:
| 命令 | 動(dòng)作 |
|---|---|
| mvn –version | 顯示版本信息 |
| mvn clean | 清理項(xiàng)目生產(chǎn)的臨時(shí)文件,一般是模塊下的target目錄 |
| mvn compile | 編譯源代碼,一般編譯模塊下的src/main/java目錄 |
| mvn package | 項(xiàng)目打包工具,會(huì)在模塊下的target目錄生成jar或war等文件 |
| mvn test | 測(cè)試命令,或執(zhí)行src/test/java/下junit的測(cè)試用例. |
| mvn install | 將打包的jar/war文件復(fù)制到你的本地倉庫中,供其他模塊使用 |
| mvn deploy | 將打包的文件發(fā)布到遠(yuǎn)程參考,提供其他人員進(jìn)行下載依賴 |
| mvn site | 生成項(xiàng)目相關(guān)信息的網(wǎng)站 |
| mvn eclipse:eclipse | 將項(xiàng)目轉(zhuǎn)化為Eclipse項(xiàng)目 |
| mvn dependency:tree | 打印出項(xiàng)目的整個(gè)依賴樹 |
| mvn archetype:generate | 創(chuàng)建Maven的普通java項(xiàng)目 |
| mvn tomcat:run | 在tomcat容器中運(yùn)行web應(yīng)用 |
| mvn jetty:run | 調(diào)用 Jetty 插件的 Run 目標(biāo)在 Jetty Servlet 容器中啟動(dòng) web 應(yīng)用 |
注意:運(yùn)行maven命令的時(shí)候,首先需要定位到maven項(xiàng)目的目錄,也就是項(xiàng)目的pom.xml文件所在的目錄。否則,必以通過參數(shù)來指定項(xiàng)目的目錄。
2.2 命令參數(shù)
上面列舉的只是比較通用的命令,其實(shí)很多命令都可以攜帶參數(shù)以執(zhí)行更精準(zhǔn)的任務(wù)。
Maven命令可攜帶的參數(shù)類型如下:
-
-D:傳入屬性參數(shù)
比如命令:
mvn package -Dmaven.test.skip=true
以-D開頭,將maven.test.skip的值設(shè)為true,就是告訴maven打包的時(shí)候跳過單元測(cè)試。同理,mvn deploy-Dmaven.test.skip=true代表部署項(xiàng)目并跳過單元測(cè)試。
-
-P: 使用指定的Profile配置
比如項(xiàng)目開發(fā)需要有多個(gè)環(huán)境,一般為開發(fā),測(cè)試,預(yù)發(fā),正式4個(gè)環(huán)境,在pom.xml中的配置如下:
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>qa</id>
<properties>
<env>qa</env>
</properties>
</profile>
<profile>
<id>pre</id>
<properties>
<env>pre</env>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<env>prod</env>
</properties>
</profile>
</profiles>
<build>
<filters>
<filter>config/${env}.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
profiles定義了各個(gè)環(huán)境的變量id,filters中定義了變量配置文件的地址,其中地址中的環(huán)境變量就是上面profile中定義的值,resources中是定義哪些目錄下的文件會(huì)被配置文件中定義的變量替換。
通過maven可以實(shí)現(xiàn)按不同環(huán)境進(jìn)行打包部署,命令為:
mvn package -P dev
其中“dev“為環(huán)境的變量id,代表使用Id為“dev”的profile。
此外,常用的命令參數(shù)還有:
-
-e:顯示maven運(yùn)行出錯(cuò)的信息 -
-o:離線執(zhí)行命令,即不去遠(yuǎn)程倉庫更新包 -
-X:顯示maven允許的debug信息 -
-U: 強(qiáng)制去遠(yuǎn)程更新snapshot的插件或依賴,默認(rèn)每天只更新一次
2.3 實(shí)例
下面結(jié)合幾個(gè)實(shí)例來看看maven命令的使用方法。
2.3.1 archetype:create & archetype:generate
“archetype”是“原型”的意思,maven可以根據(jù)各種原型來快速創(chuàng)建一個(gè)maven項(xiàng)目。
archetype:create是maven 3.0.5之前創(chuàng)建項(xiàng)目的命令,例如創(chuàng)建一個(gè)普通的Java項(xiàng)目:
mvn archetype:create -DgroupId=packageName -DartifactId=projectName Dversion=1.0.0-SNAPSHOT
后面的三個(gè)參數(shù)用于指定項(xiàng)目的groupId、artifactId以及version。
創(chuàng)建Maven的Web項(xiàng)目:
mvn archetype:create -DgroupId=packageName -DartifactId=projectName -DarchetypeArtifactId=maven-archetype-webapp
archetypeArtifactId參數(shù)用于指定使用哪個(gè)maven原型,這里使用的是maven-archetype-webapp,maven會(huì)按照web應(yīng)用的目錄結(jié)構(gòu)生成項(xiàng)目。
需要注意的是,在maven 3.0.5之后,archetype:create命令不在使用,取而代之的是archetype:generate命令。
該命令會(huì)以交互的模式創(chuàng)建maven項(xiàng)目,不需要像archetype:create那樣在后面跟一堆參數(shù),很容易出錯(cuò)。
但是,在命令行直接運(yùn)行archetype:generate,往往會(huì)出現(xiàn)下面的結(jié)果:

程序卡在了“Generating project in Interactive mode”這一步,加入“-X”參數(shù)顯示詳細(xì)信息:
mvn -X archetype:generate
運(yùn)行結(jié)果如下:

可見,最終是卡到這一行,maven默認(rèn)會(huì)從遠(yuǎn)程服務(wù)器上獲取catalog,archetypeCatalog 表示插件使用的archetype元數(shù)據(jù),默認(rèn)值為remote,local,即中央倉庫archetype元數(shù)據(jù) (http://repo1.maven.org/maven2/archetype-catalog.xml)加上插件內(nèi)置元數(shù)據(jù),由于中央倉庫的archetype太多(幾千個(gè))而造成程序的阻滯。實(shí)際上我們使用不了那么多的原型,加入-DarchetypeCatalog=internal參數(shù)就可以避免這種情況,只使用內(nèi)置的原型就夠了:
mvn archetype:generate -DarchetypeCatalog=internal
然后maven會(huì)告訴你,archetype沒有指定,默認(rèn)使用maven-archetype-quickstart,或者你從下面的列表中選擇一個(gè)可用的原型:

列表中可用的內(nèi)置原型共有10個(gè),我們選擇使用maven-archetype-quickstart原型(相當(dāng)于一個(gè)“Hello World”模板)來創(chuàng)建項(xiàng)目,輸入對(duì)應(yīng)的序號(hào)“7”即可。
然后會(huì)依次提醒你輸入groupId、artifactId、version(默認(rèn)1.0-SNAPSHOT以及創(chuàng)建的第一個(gè)包名。

2.3.2 eclipse:eclipse
正式的開發(fā)環(huán)境中,代碼一般是通過cvs、svn或者git來管理,我們從服務(wù)器下載下來源代碼,然后執(zhí)行mvn eclipse:eclipse生成ecllipse項(xiàng)目文件,然后導(dǎo)入到eclipse就行了。
2.3.3 tomcat:run
用了maven后,可以不需要用eclipse里的tomcat來運(yùn)行web項(xiàng)目(實(shí)際工作中經(jīng)常會(huì)發(fā)現(xiàn)用它會(huì)出現(xiàn)不同步更新的情況),只需在對(duì)應(yīng)目錄里運(yùn)行 mvn tomat:run命令,然后就可在瀏覽器里運(yùn)行查看了。
首先來看一下maven tomcat插件的配置:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/dubbo-admin</path>
<uriEncoding>UTF-8</uriEncoding>
<finalName>dubbo-admin</finalName>
<server>tomcat7</server>
</configuration>
</plugin>
然后配置jsp,servlet依賴等:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>jsptags</groupId>
<artifactId>pager-taglib</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
然后按照下面的方式運(yùn)行:

還可以加入以下參數(shù):
- 跳過測(cè)試:
-Dmaven.test.skip(=true) - 指定端口:
-Dmaven.tomcat.port=9090 - 忽略測(cè)試失?。?code>-Dmaven.test.failure.ignore=true
當(dāng)然,如果你的其它關(guān)聯(lián)項(xiàng)目有過更新的話,一定要在項(xiàng)目根目錄下運(yùn)行mvn clean install來執(zhí)行更新,再運(yùn)行mvn tomcat:run使改動(dòng)生效。
2.3.4 help:describe
maven有各種插件,插件又有各種目標(biāo)。我們不可能記得每個(gè)插件命令。maven提供了查詢各類插件參數(shù)的命令:mvn help:describe。
例如:mvn help:describe -Dplugin=help
代表查詢help插件的命令規(guī)范,然后maven就會(huì)告訴你該命令有幾個(gè)goal,各種參數(shù)的的意義以及配置方法:

下面的命令則代表插敘該插件的詳細(xì)命令參數(shù):
mvn help:describe -Dplugin=help -Dfull

maven會(huì)告訴你該命令有什么參數(shù),怎么使用