閱讀307 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Maven使用簡易教程

一、Maven介紹
我們在開發項目的過程中,會使用一些開源框架、第三方的工具等等,這些都是以jar包的方式被項目所引用,並且有些jar包還會依賴其他的jar包,我們同樣需要添加到項目中,所有這些相關的jar包都會作為項目的依賴。通常,一個Java EE項目所依賴的jar包會有很多。然而,這還並非是主要問題,在管理這些jar包過程中,jar包的版本往往是最令人頭疼的問題。選擇一個jar包的版本,需要考慮它所依賴的jar包是否支持這個版本,並且還需要確認依賴它的jar包能不能對這個版本兼容。所以,在過去的構建項目過程中,整理出這麼一堆能讓項目正常運行的jar包之後,這個lib目錄就會變為禁區。jar包版本更新了,我們也很少會自找麻煩去觸碰它。至於是不是存在冗餘的jar包?能正常運行就好了嘛。。。。
Maven的出現,解決了開發過程中的這一難題。它可以對項目依賴的jar包進行管理,可以讓你的項目保持基本的依賴,排除冗餘jar包,並且可以讓你非常輕鬆的對依賴的jar包進行版本升級。而這些僅僅是Maven最基本的功能,它可以在這基礎上對項目進行清理、編譯、測試、打包、發布等等構建項目的工作。
 
可以說,Maven是現在Java社區中最強大的項目管理和項目構建工具,而更加值得慶幸的是,這樣一個強大的工具,它的使用也是非常簡單的。
 
現在,JavaEE項目使用的開源軟件都可以通過Maven來獲取,並且,越來越多的公司也開始使用Maven來管理構建項目了。
 
二、Maven下載安裝
1、配置Java運行環境
Maven依賴Java運行環境,因此使用Maven之前需要配置Java的運行環境。下載並安裝JDK,配置JDK的環境變量:
    JAVA_HOME=D:\Dev\Tool\Java\jdk1.6.0_38
    在path中加入%JAVA_HOME%\bin;
2、安裝Maven
 
下載Maven最新版本的二進製zip壓縮包就可以,如:apache-maven-3.0.5-bin.zip
下載完成後,解壓,例如我們把解壓後的文件夾放在D:\Dev\Tool\目錄下。
然後,將Maven的bin目錄添加到path環境變量中,我們這裏就是這個目錄:D:\Dev\Tool\apache-maven-3.0.4\bin
 
在Windows命令提示符下,輸入mvn -v測試一下,如圖:
 
這樣,maven就安裝完成了,就是這麼簡單。接下來我們先來了解一下Maven是如何來管理項目的。
 
三、Maven依賴管理
前麵講了,Maven最核心的就是對依賴jar包的管理,那麼它是通過什麼方式來進行管理的呢?
Maven要求每一個jar包都必須明確定義自己的坐標,Maven就是通過這個坐標來查找管理這些jar包的。
在Maven中,一個jar包的坐標是由它的groupId、artifactId、version這些元素來定義的。例如:
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.3.8</version>
    <packaging>jar</packaging>
groupId:表明其所屬組織或公司及其所屬項目,命名規則為組織或公司域名反轉加項目名稱。
artifactId:項目的模塊名,通常與實際項目名稱一致。模塊的命名通常為項目名前綴加模塊名。
version:當前項目的版本號。
packaging:定義項目的打包方式,可選值有jar、war、pom。默認為jar
注::一個組織或公司都會有很多的項目,而每個項目下都會劃分多個模塊,在開發中我們可以靈活選擇依賴某個模塊。而Maven管理的jar包基本都是模塊性質的項目構建出的jar包。所以,artifactId通常都是模塊名,而不是項目名稱。項目名稱是和組織名稱組合作為groupId來使用的。
 
上麵的配置定義了一個Maven項目的坐標,而如果在項目中依賴這個項目時,同樣是利用它的坐標來指定依賴。例如:
<project>
    ...
    <dependencies>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>2.3.8</version>
        </dependency>
    </dependencies>
    ...
</project>
 
Maven的配置文件中dependencies元素包含了所有依賴的jar包,每一個jar包依賴使用dependency元素定義。
在聲明一個jar包依賴時,除了指定groupId、artifactId、version這三項基本坐標外,還可以使用使用以下元素進行配置:
scope元素:指定依賴的範圍
exclusions元素:排除傳遞性依賴
 
Maven有以下幾種依賴範圍:
compile:編譯依賴範圍(默認值),依賴在編譯、測試、運行期間都有效。
test:測試依賴範圍,隻對測試的classpath有效,在編譯或運行時無法使用指定為test的依賴包。
provided:已提供的依賴範圍,隻對編譯和測試的classpath有效,運行期間不會使用這個依賴。例如servlet-api,在運行時容器已經提供,不需要再重複引入。
runtime:運行時依賴範圍,編譯時無效,隻在測試和運行時使用這個依賴。
system:係統依賴範圍,和provided範圍一致,但是provided是使用容器提供依賴,system是使用係統提供依賴,需要指定依賴文件路徑。
 
傳遞性依賴,是指依賴包對其他包的依賴,比如,我們依賴struts2-core,而strtus2-core需要依賴xwork-core、ognl等,Maven會將這些傳遞性依賴同時引入項目之中。這也是Maven的一大優點,簡化了我們對jar包依賴的管理。而有時我們希望替換某個傳遞性依賴時,就需要使用exclusions排除掉這個傳遞性依賴,然後再添加我們自己要替換的依賴包。
 
例如,如下一個Maven的配置文件,pom.xml:
[html
<?xml version="1.0" encoding="UTF-8"?>  
<project xmlns="https://maven.apache.org/POM/4.0.0"  
    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">  
  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>com.boya.spring</groupId>  
    <artifactId>spring_ioc</artifactId>  
    <packaging>jar</packaging>  
    <version>1.0.0</version>  
  
    <name>${project.artifactId}</name>  
    <description>Spring Ioc Sample</description>  
  
    <dependencies>  
        <!-- spring start -->  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>  
            <version>3.2.0.RELEASE</version>  
            <exclusions>  
                <exclusion>  
                    <groupId>commons-logging</groupId>  
                    <artifactId>commons-logging</artifactId>  
                </exclusion>  
            </exclusions>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-beans</artifactId>  
            <version>3.2.0.RELEASE</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-context</artifactId>  
            <version>3.2.0.RELEASE</version>  
        </dependency>  
  
        <!-- logging start -->  
        <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>slf4j-api</artifactId>  
            <version>1.6.4</version>  
        </dependency>  
        <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>slf4j-log4j12</artifactId>  
            <version>1.6.4</version>  
        </dependency>  
        <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>jcl-over-slf4j</artifactId>  
            <version>1.6.4</version>  
        </dependency>  
        <dependency>  
            <groupId>log4j</groupId>  
            <artifactId>log4j</artifactId>  
            <version>1.2.16</version>  
        </dependency>  
        <dependency>  
            <groupId>log4jdbc</groupId>  
            <artifactId>log4jdbc4</artifactId>  
            <version>1.2</version>  
        </dependency>  
  
        <!--Test start-->  
        <dependency>  
            <groupId>junit</groupId>  
            <artifactId>junit</artifactId>  
            <version>4.10</version>  
            <scope>test</scope>  
        </dependency>  
    </dependencies>  
</project>  
 
四、Maven倉庫
Maven通過項目定義的坐標來管理這些依賴,而這些依賴的物理文件是通過Maven的倉庫來統一管理的。
對於一個依賴坐標,它會按照如下方式反映到Maven的倉庫中。
1、將groupId轉化為路徑:將groupId中的包名分隔符(.)轉換成路徑分隔符(/)。對於上麵的例子就是 org.apache.struts -> org/apache/struts/
2、將artifactId轉化為路徑:在groupId轉化的路徑基礎上連接artifactId。生成路徑為: org/apache/struts/struts2-core/
3、將verion轉化為路徑:在artifactId轉化的路徑基礎上連接version。生成路徑為: org/apache/struts/struts2-core/2.3.8/
4、根據artifactId和version生成依賴包文件名:上例就是 struts2-core-2.3.8
5、根據依賴的打包方式確定文件的擴展名。對於上例它的擴展名就是.jar
 
這樣根據路徑和文件名就找到了這個物理文件在倉庫中的位置:org/apache/struts/struts2-core/2.3.8/struts2-core-2.3.8.jar
 
Maven的倉庫分為本地倉庫和遠程倉庫。
本地倉庫:是Maven在我們本機設置的倉庫目錄,默認目錄為當前用戶目錄下的.m2/repository.
遠程倉庫包括中央倉庫、私服、其他公共倉庫。
中央倉庫是Maven提供的遠程倉庫,地址是:https://repo.maven.apache.org/maven2
私服是我們為了節省帶寬和時間,提升效率,在局域網架設的私有Maven倉庫。
 
 
Maven在根據依賴坐標查找依賴時,首先會從本地倉庫查找該依賴包,當本地倉庫中沒有這個依賴包時,Maven會從中央倉庫查找依賴,並下載到本地倉庫。最後,在我們項目的classpath中引用本地倉庫的依賴包路徑。
例如,當項目隻依賴strtus2-core這個依賴包時,會生成這樣的classpath文件:
[html]  
<?xml version="1.0" encoding="UTF-8"?>  
<classpath>  
  <classpathentry kind="src" path="src/main/java" output="/src/main/webapp/WEB-INF/classes" including="**/*.java"/>  
  <classpathentry kind="src" path="src/main/resources" output="/src/main/webapp/WEB-INF/classes" excluding="**/*.java"/>  
  <classpathentry kind="output" path="src/main/webapp/WEB-INF/classes"/>  
  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>  
  <classpathentry kind="con" path="com.genuitec.eclipse.j2eedt.core.J2EE14_CONTAINER"/>  
  <classpathentry kind="var" path="M2_REPO/org/apache/struts/struts2-core/2.3.8/struts2-core-2.3.8.jar" />  
  <classpathentry kind="var" path="M2_REPO/org/apache/struts/xwork/xwork-core/2.3.8/xwork-core-2.3.8.jar" />  
  <classpathentry kind="var" path="M2_REPO/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar" />  
  <classpathentry kind="var" path="M2_REPO/ognl/ognl/3.0.6/ognl-3.0.6.jar" />  
  <classpathentry kind="var" path="M2_REPO/javassist/javassist/3.11.0.GA/javassist-3.11.0.GA.jar" />  
  <classpathentry kind="var" path="M2_REPO/asm/asm/3.3/asm-3.3.jar"/>  
  <classpathentry kind="var" path="M2_REPO/asm/asm-commons/3.3/asm-commons-3.3.jar"/>  
  <classpathentry kind="var" path="M2_REPO/asm/asm-tree/3.3/asm-tree-3.3.jar"/>  
  <classpathentry kind="var" path="M2_REPO/org/freemarker/freemarker/2.3.19/freemarker-2.3.19.jar" />  
  <classpathentry kind="var" path="M2_REPO/commons-fileupload/commons-fileupload/1.2.2/commons-fileupload-1.2.2.jar" />  
  <classpathentry kind="var" path="M2_REPO/commons-io/commons-io/2.3/commons-io-2.3.jar" />  
</classpath>  
其中,本地倉庫目錄會使用M2_REPO變量表示,因此IDE環境未配置該變量時,需在IDE中添加這個變量的classpath。
 
五、聚合與繼承
一個項目通常存在多個模塊,每個模塊都是作為一個獨立的工程存在。通過Maven配置文件可以把多個模塊聚合在一起進行編譯發布,並且它的聚合非常簡單隻需要使用<modules>元素添加模塊就可以完成聚合。我們參考struts2的pom.xml文件來看一下聚合的配置方式:
[html]  
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">  
    <modelVersion>4.0.0</modelVersion>  
    <parent>  
        <groupId>org.apache.struts</groupId>  
        <artifactId>struts2-parent</artifactId>  
        <version>2.3.8</version>  
    </parent>  
    <groupId>org.apache.struts</groupId>  
    <artifactId>struts2-apps</artifactId>  
    <packaging>pom</packaging>  
    <name>Webapps</name>  
    <modules>  
        <module>blank</module>  
        <module>mailreader</module>  
        <module>portlet</module>  
        <module>showcase</module>  
        <module>rest-showcase</module>  
    </modules>  
....  
</project>  
另外,在這個項目的個各模塊間通常是存在引用關係,並且每個模塊會引用一些相同的依賴,Maven也提供了繼承的機製來管理這些共同的依賴。你可以編寫一個pom.xml文件作為父級pom配置,各個模塊在自己的pom.xml中繼承父級pom文件,就像上麵的示例那樣,使用<parent>元素標識繼承的父級pom文件。
 
父級pom文件的編寫:
1、父級pom文件的packaging必須是pom,它需要作為pom文件發布以便子pom繼承
2、在父級pom可以使用<dependencyManagement>配置依賴管理。在<dependencyManagement>下的依賴聲明不會引入實際依賴,但是可以讓子模塊繼承依賴配置。例如,在子模塊中我們隻標識依賴的groupId和artifactId,它就可以根據父類的依賴管理獲取這個依賴的version及exclussions等配置。
3、在父級pom中可以使用<pluginManagement>配置插件管理。作用和<dependencyManagement>類似,隻不過一個管理依賴一個管理插件。
 
子模塊pom文件的編寫:
1、需要使用<parent>元素標識繼承的父pom
2、可以使用<relativePath>標識父級pom的物理路徑,子模塊會直接從指定的路徑加載父級pom文件,未指定該元素時,子模塊將根據父級pom的坐標從Maven倉庫查找
3、子模塊pom可以繼承父級pom中除artifactId之外的大部分配置,因此子模塊的groupId、version以及依賴的version都可以省略。
 
六、Maven腳本使用
現在大部分IDE都有插件支持Maven,使用插件可以方便的構建Maven項目,如果IDE不支持Maven插件或未安裝Maven插件也可以使用一個簡單的批處理腳本來完成Maven項目的構建。
例如,保存下麵內容,存儲為bat格式的批處理文件
cd %~dp0
call mvn eclipse:clean eclipse:eclipse
 
pause
運行該文件,就會自動根據該目錄下的pom.xml生成該項目的eclipse開發環境配置。
 
在後麵的教程及示例中我都是使用Maven來構建的,pom.xml的示例可以參考我後麵的教程和代碼示例。

最後更新:2017-04-03 08:26:25

  上一篇:go 高性能網絡編程4&#8211;TCP連接的關閉
  下一篇:go [推薦係統]推薦係統實踐Reference