maven配置详解

Maven项目之pom.xml文件

(1)什么是pom?

pom作为项目对象模型。通过xml表示maven项目,使用pom.xml来实现。主要描述了项目:包括配置文件;开发者需要遵循的规则,缺陷管理系统,组织和licenses,项目的url,项目的依赖性,以及其他所有的项目相关因素。

2)快速察看:
<project>
  <modelVersion>4.0.0</modelVersion>
<!--maven2.0
必须是这样写,现在是maven2唯一支持的版本-->
  <!--
基础设置-->
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <version>...</version>
  <packaging>...</packaging>

  <name>...</name>

  <url>...</url>
  <dependencies>...</dependencies>
  <parent>...</parent>
  <dependencyManagement>...</dependencyManagement>
  <modules>...</modules>
  <properties>...</properties>

<!--构建设置 -->
  <build>...</build>
  <reporting>...</reporting>

  <!--
更多项目信息 -->
  <name>...</name>
 <description>...</description>
  <url>...</url>
 <inceptionYear>...</inceptionYear>
  <licenses>...</licenses>
 <organization>...</organization>
  <developers>...</developers>
 <contributors>...</contributors>

 

  <!-- 环境设置-->
 <issueManagement>...</issueManagement>
 <ciManagement>...</ciManagement>
 <mailingLists>...</mailingLists> 
  <scm>...</scm>
 <prerequisites>...</prerequisites>
 <repositories>...</repositories>
 <pluginRepositories>...</pluginRepositories>
 <distributionManagement>...</distributionManagement>
  <profiles>...</profiles>
</project>

基本内容:

POM包括了所有的项目信息

groupId:项目或者组织的唯一标志,并且配置时生成路径也是由此生成,如org.myproject.mojo生成的相对路径为:/org/myproject/mojo

artifactId:项目的通用名称

version:项目的版本

packaging:打包机制,如pom,jar,maven-plugin,ejb,war,ear,rar,par

name:用户描述项目的名称,无关紧要的东西,可选

url:应该是只是写明开发团队的网站,无关紧要,可选

classifer:分类

其中groupId,artifactId,version,packaging这四项组成了项目的唯一坐标。一般情况下,前面三项就可以组成项目的唯一坐标了。

 

POM关系:主要为依赖,继承,合成

依赖关系:

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.0</version>
      <type>jar</type>
      <scope>test</scope>
      <optional>true</optional>
    </dependency>

   <dependency>

       <groupId>com.alibaba.china.shared</groupId>

       <artifactId>alibaba.apollo.webx</artifactId>

       <version>2.5.0</version>

       <exclusions>

         <exclusion>

          <artifactId>org.slf4j.slf4j-api</artifactId>

          <groupId>com.alibaba.external</groupId>

         </exclusion>

         ....

       </exclusions>

       ......

</dependencies>

其中groupId, artifactId, version这三个组合标示依赖的具体工程,而且这个依赖工程必需是maven中心包管理范围内的,如果碰上非开源包,maven支持不了这个包,那么则有有三种方法处理:

1.本地安装这个插件installplugin

例如:mvn install:intall-file-Dfile=non-maven-proj.jar -DgroupId=som.group -DartifactId=non-maven-proj-Dversion=1

2.创建自己的repositories并且部署这个包,使用类似上面的deploy:deploy-file命令,

3.设置scopesystem,并且指定系统路径。

dependency里属性介绍:

type:默认为jar类型,常用的类型有:jar,ejb-client,test-jar...,可设置plugins中的extensions值为true后在增加新的类型,

scope:是用来指定当前包的依赖范围,maven的依赖范围

optional:设置指依赖是否可选,默认为false,即子项目默认都继承,为true,则子项目必需显示的引入,与dependencyManagement里定义的依赖类似

exclusions:如果X需要A,A包含B依赖,那么X可以声明不要B依赖,只要在exclusions中声明exclusion.

exclusion:是将B从依赖树中删除,如上配置,alibaba.apollo.webx不想使用com.alibaba.external  ,但是alibaba.apollo.webx是集成了com.alibaba.external,r所以就需要排除掉.

如果一个工程是parent或者aggregation(即mutil-module的)的,那么必须在packing赋值为pom,child工程从parent继承的包括:dependencies,developers,contributors,pluginlists,reports lists,plugin execution with matching ids,plugin configuration

parent的使用方法如下:

<parent> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>my-parent</artifactId> 
    <version>2.0</version> 
    <relativePath>../my-parent</relativePath> 
  </parent>

relativePath是可选的,maven会首先搜索这个地址,在搜索本地远程repositories之前.

dependencyManagement:是用于帮助管理chidrendependencies的。例如如果parent使用dependencyManagement定义了一个dependencyonjunit:junit4.0,那么它的children就可以只引用 groupIdartifactId,version就可以通过parent来设置,这样的好处就是可以集中管理依赖的详情

modules:对于多模块的project,outer-module没有必需考虑inner-moduledependencies,当列出modules的时候,modules的顺序是不重要的,因为maven会自动根据依赖关系来拓扑排序,

modules例子如下

<module>my-project</module>

<module>other-project</module>

properties:是为pom定义一些常量,在pom中的其它地方可以直接引用。

定义方式如下:

<properties>

     <file.encoding>UTF-8</file_encoding>

     <java.source.version>1.5</java_source_version>

     <java.target.version>1.5</java_target_version>

</properties>

使用方式如下

${file.encoding}

还可以使用project.xx引用pom里定义的其它属性:如$(project.version} 

build设置:

defaultGoal:默认的目标,必须跟命令行上的参数相同,如:jar:jar,或者与时期parse相同,例如install

directory:指定buildtarget目标的目录,默认为$(basedir}/target,即项目根目录下的target

finalName:指定去掉后缀的工程名字,例如:默认为${artifactId}-${version}

filters:用于定义指定filter属性的位置,例如filter元素赋值filters/filter1.properties,那么这个文件里面就可以定义name=value对,这个name=value对的值就可以在工程pom中通过${name}引用,默认的filter目录是${basedir}/src/main/fiters/

resources:描述工程中资源的位置 

<resource> 
       <targetPath>META-INF/plexus</targetPath> 
       <filtering>false</filtering> 
       <directory>${basedir}/src/main/plexus</directory> 
        <includes> 
         <include>configuration.xml</include> 
        </includes> 
        <excludes> 
         <exclude>**/*.properties</exclude> 
        </excludes> 
      </resource>

targetPath:指定build资源到哪个目录,默认是basedirectory

filtering:指定是否将filter文件(即上面说的filters里定义的*.property文件)的变量值在这个resource文件有效,例如上面就指定那些变量值在configuration文件无效。

directory:指定属性文件的目录,build的过程需要找到它,并且将其放到targetPath下,默认的directory${basedir}/src/main/resources

includes:指定包含文件的patterns,符合样式并且在directory目录下的文件将会包含进project的资源文件。

excludes:指定不包含在内的patterns,如果incluesexcludes有冲突,那么excludes胜利,那些符合冲突的样式的文件是不会包含进来的。

testResources:这个模块包含测试资源元素,其内容定义与resources类似,不同的一点是默认的测试资源路径是${basedir}/src/test/resources,测试资源是不部署的。

plugins配置:

<plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-jar-plugin</artifactId> 
        <version>2.0</version> 
        <extensions>false</extensions> 
       <inherited>true</inherited> 
        <configuration> 
         <classifier>test</classifier> 
        </configuration> 
       <dependencies>...</dependencies> 
       <executions>...</executions> 
      </plugin>

extensions:trueor false, 决定是否要load这个pluginextensions,默认为true.

inherited:是否让子pom继承,ture orfalse 默认为true.

configuration:通常用于私有不开源的plugin,不能够详细了解plugin的内部工作原理,但使plugin满足的properties

dependencies:pom基础的dependencies的结构和功能都相同,只是plugindependencies用于plugin,pomdenpendencies用于项目本身。在plugindependencies主要用于改变plugin原来的dependencies,例如排除一些用不到的dependency或者修改dependency的版本等,详细请看pomdenpendencies.

executions:plugin也有很多个目标,每个目标具有不同的配置,executions就是设定plugin的目标,

<execution> 
           <id>echodir</id> 
           <goals> 
              <goal>run</goal> 
           </goals> 
           <phase>verify</phase> 
           <inherited>false</inherited> 
           <configuration> 
             <tasks> 
               <echo>Build Dir: ${project.build.directory}</echo> 
             </tasks> 
           </configuration> 
          </execution> 

id:标识符

goals:里面列出一系列的goals元素,例如上面的run goal

phase:声明goals执行的时期,例如:verify

inherited:是否传递execution到子pom里。

configuration:设置execution下列表的goals的设置,而不是plugin所有的goals的设置

 

pluginManagement配置:

pluginManagement的作用类似于denpendencyManagement,只是denpendencyManagement是用于管理项目jar包依赖,pluginManagement是用于管理plugin。与pom build里的plugins区别是,这里的plugin是列出来,然后让子pom来决定是否引用。

例如:

<pluginManagement> 

     <plugins> 
        <plugin> 
         <groupId>org.apache.maven.plugins</groupId> 
         <artifactId>maven-jar-plugin</artifactId> 
         <version>2.2</version> 
          <executions> 
           <execution> 
             <id>pre-process-classes</id> 
             <phase>compile</phase> 
             <goals> 
               <goal>jar</goal> 
             </goals> 
             <configuration> 
               <classifier>pre-process</classifier> 
             </configuration> 
           </execution> 
          </executions> 
        </plugin> 
      </plugins> 
    </pluginManagement> 
pom引用方法: 
pombuild里的plugins引用: 
    <plugins> 

      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-jar-plugin</artifactId> 
      </plugin> 
    </plugins>

build里的directories:

<sourceDirectory>${basedir}/src/main/java</sourceDirectory> 
   <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory> 
   <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory> 
    <outputDirectory>${basedir}/target/classes</outputDirectory> 
   <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>

这几个元素只在parent build element里面定义,他们设置多种路径结构,他们并不在profile里,所以不能通过profile来修改

build 里面的Extensions 
它们是一系列build过程中要使用的产品,他们会包含在runningbulid‘s classpath里面。他们可以开启extensions,也可以通过提供条件来激活plugins。简单来讲,extensions是在build过程被激活的产品 
    <extensions> 

      <extension> 
       <groupId>org.apache.maven.wagon</groupId> 
       <artifactId>wagon-ftp</artifactId> 
        <version>1.0-alpha-3</version> 
      </extension> 
    </extensions> 

reporting设置:

reporting包含site生成阶段的一些元素,某些mavenplugin可以生成reports并且在reporting下配置。例如javadoc,mavensite等,在reporting下配置的reportplugin的方法与build几乎一样,最不同的是buildplugingoalsexecutions下设置,而reportingconfiguresgoalsreporttest

excludeDefaults:是否排除sitegenerator默认产生的reports

outputDirectory,默认的dir变成:${basedir}/target/site

reportsets:设置executiongoals,相当于build里面的executions,不同的是不能够bind areport to another phase,只能够是site

<reporting> 
    <plugins> 
      <plugin> 
        ... 
        <reportSets> 
          <reportSet> 
           <id>sunlink</id> 
           <reports> 
             <report>javadoc</report> 
           </reports> 
           <inherited>true</inherited> 
           <configuration> 
             <links> 
               <link>http://java.sun.com/j2se/1.5.0/docs/api/</link> 
             </links> 
           </configuration> 
          </reportSet> 
        </reportSets> 
      </plugin> 
    </plugins> 
  </reporting> 
reporting里面的厄reportSetsbuild里面的executions的作用都是控制pom的不同粒度去控制build的过程,我们不单要配置plugins,还要配置那些plugins单独的goals

更多项目信息:

name:项目除了artifactId外,可以定义多个名称
description:
项目描述
url:
项目url
inceptionYear:
创始年份

Licenses
<licenses>
  <license>
    <name>Apache 2</name>
    <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
    <distribution>repo</distribution>
    <comments>A business-friendly OSSlicense</comments>
  </license>
</licenses>

列出本工程直接的licenses,而不要列出dependencieslicenses

配置组织信息:
  <organization>
    <name>Codehaus Mojo</name>
    <url>http://mojo.codehaus.org</url>
  </organization>

很多工程都受到某些组织运行,这里设置基本信息

配置开发者信息:

例如:一个开发者可以有多个rolesproperties 
<developers>
    <developer>
      <id>eric</id>
      <name>Eric</name>
      <email>eredmond@codehaus.org</email>
     <url>http://eric.propellors.net</url>
     <organization>Codehaus</organization>
     <organizationUrl>http://mojo.codehaus.org</organizationUrl>
      <roles>
        <role>architect</role>
        <role>developer</role>
      </roles>
      <timezone>-6</timezone>
      <properties>
       <picUrl>http://tinyurl.com/prv4t</picUrl>
      </properties>
    </developer>
  </developers>

环境设置:

issueManagement:bug跟踪管理系统,定义defecttracking system缺陷跟踪系统,比如有(bugzilla,testtrack,clearquest等).

例如:

  <issueManagement> 
    <system>Bugzilla</system> 
    <url>http://127.0.0.1/bugzilla/</url> 
  </issueManagement> 

仓库:

Repositoriespom里面的仓库与setting.xml里的仓库功能是一样的。主要的区别在于,pom里的仓库是个性化的。比如一家大公司里的setting文件是公用的,所有项目都用一个setting文件,但各个子项目却会引用不同的第三方库,所以就需要在pom里设置自己需要的仓库地址。

repositories:要成为maven2repositoryartifact,必须具有pom文件在$BASE_REPO/groupId/artifactId/version/artifactId-version.pom 
BASE_REPO
可以是本地,也可以是远程的。repository元素就是声明那些去查找的repositories 
默认的centralMaven repositoryhttp://repo1.maven.org/maven2/

<repositories> 
    <repository> 
      <releases> 
       <enabled>false</enabled> 
       <updatePolicy>always</updatePolicy> 
       <checksumPolicy>warn</checksumPolicy> 
      </releases> 
      <snapshots> 
       <enabled>true</enabled> 
        <updatePolicy>never</updatePolicy> 
       <checksumPolicy>fail</checksumPolicy> 
      </snapshots> 
      <id>codehausSnapshots</id> 
      <name>CodehausSnapshots</name> 
     <url>http://snapshots.maven.codehaus.org/maven2</url> 
      <layout>default</layout> 
    </repository> 
  </repositories> 

releasesnapshots:是artifact的两种policiespom可以选择那种政策有效。 
enable
:本别指定两种类型是否可用,trueor false 
updatePolicy:
说明更新发生的频率always或者 never 或者 daily(默认的)或者interval:XX是分钟数) 

checksumPolicy:当Maven的部署文件到仓库中,它也部署了相应的校验和文件。您可以选择忽略,失败,或缺少或不正确的校验和警告。

layoutmaven1.xmaven2有不同的layout,所以可以声明为default或者是legacy(遗留方式maven1.x)。

插件仓库:

pluginRepositories:与Repositories具有类似的结构,只是Repositoriesdependencieshome,而这个是plugins home

分发管理:

distributionManagement:管理distributionsupportingfiles 

downloadUrl:是其他项目为了抓取本项目的pom’sartifact而指定的url,就是说告诉pomupload的地址也就是别人可以下载的地址。 
status
:这里的状态不要受到我们的设置,maven会自动设置project的状态,有效的值:none:没有声明状态,pom默认的;converted:本project是管理员从原先的maven版本convertmaven2的;partner:以前叫做synched,意思是与partnerrepository已经进行了同步;deployed:至今为止最经常的状态,意思是制品是从maven2instance部署的,人工在命令行deploy的就会得到这个;verified:本制品已经经过验证,也就是已经定下来了最终版。 
repository
:声明deploy过程中currentproject会如何变成repository,说明部署到repository的信息。 
    <repository> 
     <uniqueVersion>false</uniqueVersion> 
      <id>corp1</id> 
      <name>CorporateRepository</name> 
      <url>scp://repo1/maven2</url> 
      <layout>default</layout> 
    </repository> 
    <snapshotRepository> 
     <uniqueVersion>true</uniqueVersion> 
      <id>propSnap</id> 
      <name>PropellorsSnapshots</name> 
     <url>sftp://propellers.net/maven</url> 
      <layout>legacy</layout> 
    </snapshotRepository> 
id, name:
:唯一性的id,和可读性的name 
uniqueVersion
:指定是否产生一个唯一性的versionnumber还是使用address里的其中version部分。true orfalse 
url
:说明locationtransportprotocol 
layout
default或者legacy

profiles:pom4.0的一个新特性就是具有根据environment来修改设置的能力

它包含可选的activationprofile的触发器)和一系列的changes。例如test过程可能会指向不同的数据库(相对最终的deployment)或者不同的dependencies或者不同的repositories,并且是根据不同的JDK来改变的。那么结构如下: 

  <profiles> 
    <profile> 
      <id>test</id> 
      <activation>...</activation> 
      <build>...</build> 
      <modules>...</modules> 
     <repositories>...</repositories> 
     <pluginRepositories>...</pluginRepositories> 
     <dependencies>...</dependencies> 
      <reporting>...</reporting> 
     <dependencyManagement>...</dependencyManagement> 
     <distributionManagement>...</distributionManagement> 
    </profile> 
  </profiles> 
Activation
 
触发这个profile的条件配置如下例:(只需要其中一个成立就可以激活profile,如果第一个条件满足了,那么后面就不会在进行匹配。 
    <profile> 
      <id>test</id> 
      <activation> 
       <activeByDefault>false</activeByDefault> 
        <jdk>1.5</jdk> 
        <os> 
          <name>WindowsXP</name> 
         <family>Windows</family> 
         <arch>x86</arch> 
         <version>5.1.2600</version> 
        </os> 
        <property> 
         <name>mavenVersion</name> 
         <value>2.0.3</value> 
        </property> 
        <file> 
         <exists>${basedir}/file2.properties</exists> 
         <missing>${basedir}/file1.properties</missing> 
        </file> 
      </activation>  

激活profile的方法有多个:setting文件的activeProfile元素明确指定激活的profileID,在命令行上明确激活Profile-P flag 参数 
查看某个build会激活的profile列表可以用:mvnhelp:active-profiles 

Maven那些事儿

0. 前言

Jason Van Zyl,在 Java 十大风云人物排行榜上或许会看到他。

这兄弟是干嘛的?

他就是 Maven 的创始人,人们都尊称他为“Maven 他爹”。

毋庸置疑,Jason 也是一个秃顶。James Gosling、Rod Johnson、Gavin King,你们可以告诉我为什么吗?

您曾经是否会遇到这些问题:

·        我们要开发一个 Java 项目,为了保证编译通过,我们会到处去寻找 jar 包。当编译通过了,在运行的时候,却发现ClassNotFoundException,我操!还差 jar 包啊?再去找找吧。

·        每个 Java 项目的目录结构都没有一个统一的标准,配置文件到处都是,单元测试代码到底应该放在哪里,没有一个权威的规范。

·        可使用 Ant 做为项目构建工具,它可以自动化地完成编译、测试、打包等任务,确实为我们省了不少事儿,但编写 Ant 的 XML 脚本绝非是一件轻松的事情。

有了 Maven,以上这一切都不再是问题了。

Jason就是 Java 开发规范的“救世主”!他给我们带来了一种全新的项目构建方式,让我们的开发工作更加高效。

不仅如此,Jason 还是一名“野心家”,他不仅希望每个 Java 开发者都能使用他定义的规范,还要我们都从他家里去获取 jar 包(他家就是 Maven 中央仓库),我们只需告诉他,我们想要的 jar 包具体在什么位置即可(这个位置就是 Maven 坐标)。

看来 Jason 要做的是两件事情:

1.   统一开发规范与工具

2.   统一管理 jar

这两件事情他都做到了,而且还做了更多的事情。

工欲善其事,必先利其器。咱们也来玩玩 Maven 这货吧!先得去下载一个。

1. 安装 Maven

Maven 是 Apache 基金会的顶级项目,一般情况下,被 Apache 看中的都不会是烂货。

我们可以从 http://maven.apache.org/ 下载 Maven 开发包,其实就是一个压缩包,下载完毕后,解压一下,配置一下环境变量就可以用了。真是超简单!

假设我们刚刚下载了一个 apache-maven-3.1.1-bin.zip 文件,现在将其解压到D:/SDK 目录下 。我们不妨将解压后的目录重命名为 Maven,这样Maven的根目录就是 D:/SDK/Maven 了。

有两个环境变量可以配置:

·        M2_HOME = D:/SDK/Maven

·        MAVEN_OPTS = -Xms128m -Xmx512m

以上 M2_HOME 是必须要配置的,如果想让 Maven 跑得更快点,可以根据自己的情况来设置 MAVEN_OPTS。

现在我们可以打开 cmd,输入:

mvn -v

我想您一定会看到一些信息,恭喜您,Maven安装成功!

在使用 Maven 之前,很有必要了解一下 Maven 到底是怎样管理 jar 包的,这就是 Maven 仓库要干的活了。

2. 了解 Maven 仓库

使用 Maven 给我们带来的最直接的帮助,就是 jar 包得到了统一管理,那么这些 jar 包存放在哪里呢?它们就在您的 本地仓库 中,位于 C:\Users\用户名\.m2 目录下(当然也可以修改这个默认地址)。

实际上可将本地仓库理解“缓存”,因为项目首先会从本地仓库中获取 jar 包,当无法获取指定 jar 包的时候,本地仓库会从 远程仓库(或 中央仓库) 中下载 jar 包,并放入本地仓库中以备将来使用。这个远程仓库是 Maven 官方提供的,可通过 http://search.maven.org/ 来访问。这样一来,本地仓库会随着项目的积累越来越大。通过下面这张图可以清晰地表达项目、本地仓库、远程仓库之间的关系。

这个结构是否与 Git 的本地仓库与远程仓库有异曲同工之妙呢?

既然 Maven 安装了,那么本地仓库也就有了,下面我们就一起来创建一个 Maven 项目吧。

3. 创建 Maven 项目

我们不妨创建一个 Java Web项目,只需在 cmd 中输入:

mvn archetype:generate

随后 Maven 将下载 Archetype 插件及其所有的依赖插件,这些插件其实都是 jar 包,它们存放在您的 Maven 本地仓库中。

在 cmd 中,您会看到几百个 Archetype(原型),可将它理解为项目模板,您得从中选择一个。

我们的目标是创建 Java Web项目,所以您可以选择 maven-archetype-webapp(可以在 cmd 中进行模糊搜索),随后 Maven 会与您进行一些对话,Maven 想知道以下信息:

·        项目 Archetype Version(原型版本号)是什么?—— 可选择 1.0 版本

·        项目 groupId(组织名) 是什么?—— 可输入 com.smart

·        项目 artifactId(构件名)是什么?—— 可输入 smart-demo

·        项目 version(版本号)是什么?—— 可输入 1.0

·        项目 package(包名)是什么?—— 可输入 com.smart.demo

以上这种方式称为 InteractiveMode(交互模式)

如果您是一位高效人士,或许觉得这样的交互过于繁琐,那么您也可以尝试仅使用一条命名,来完成同样的事情:

mvn archetype:generate -DinteractiveMode=false-DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.smart-DartifactId=smart-demo -Dversion=1.0

以上这种方式成为 Batch Mode(批处理模式)

当然,还有第三种选择,使用 IDE来创建 Maven 项目,您可以使用 Eclipse、NetBeans、IDEA 来创建Maven 项目,操作过程应该是非常简单的。

您也可以使用 IDEA 直接打开一个 Maven 项目,只需要 File -> Open -> 选择 pom.xml,那么下面您就可以在 IDEA 中开发 Maven 项目了,贴一张图片吧:


 

其实这个目录结构还不太完备,我们需要手工添加几个目录上去,最终的目录结构看起来是这样的:

我们手工创建了三个目录:

1.   src/main/java

2.   src/test/java

3.   src/test/resources

为什么自动生成的目录不完备?确实挺无语的,我们就不要去纠结了。不过有必要稍微解释一下这个 Maven 目录规范:

·        main 目录下是项目的主要代码,test 目录下存放测试相关的代码。

·        编译输出后的代码会放在target 目录下(该目录与 src 目录在同一级别下,这里没有显示出来)。

·        java 目录下存放 Java 代码,resources 目录下存放配置文件。

·        webapp 目录下存放 Web 应用相关代码。

·        pom.xml 是 Maven 项目的配置文件。

其中 pom.xml 称为 Project Object Model(项目对象模型),它用于描述整个 Maven 项目,所以也称为 Maven 描述文件。

可见 pom.xml 才是理解 Maven 的关键点,很有必要看看它到底长什么样。

4. 理解 pom.xml

您打开自动生成的 pom.xml,或许会感觉到可读性不太好,有必要做一下格式化,经过整理后是这样的:

<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/maven-v4_0_0.xsd">
 
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.smart</groupId>
    <artifactId>smart-demo</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>
 
    <name>smart-demo Maven Webapp</name>
    <url>http://maven.apache.org</url>
 
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
    <build>
        <finalName>smart-demo</finalName>
    </build>
 
</project>

从上往下简要说明一下:

·        modelVersion:这个是 POM 的版本号,现在都是 4.0.0 的,必须得有,但不需要修改。

·        groupId、artifactId、version:分别表示 Maven 项目的组织名、构件名、版本号,它们三个合起来就是 Maven 坐标,根据这个坐标可以在 Maven 仓库中对应唯一的 Maven 构件

·        packaging:表示该项目的打包方式,war 表示打包为 war 文件,默认为jar,表示打包为 jar 文件。

·        name、url:表示该项目的名称与 URL 地址,意义不大,可以省略。

·        dependencies:定义该项目的依赖关系,其中每一个 dependency 对应一个 Maven 项目,可见 Maven 坐标再次出现,还多了一个 scope,表示作用域(下面会描述)。

·        build:表示与构建相关的配置,这里的 finalName 表示最终构建后的名称 smart-demo.war,这里的 finalName 还可以使用另一种方式来定义(下面会描述)。

如果用树形图来表达 pom.xml,那么会更加清晰:

可见,除了项目的基本信息(Maven坐标、打包方式等)以外,每个 pom.xml 都应该包括:

1.   Lifecycle(生命周期)

2.   Plugins(插件)

3.   Dependencies(依赖)

Lifecycle 是项目构建的生命周期,它包括 9 个 Phase(阶段)。

大家知道,Maven 是一个核心加上多个插件的架构,而这些插件提供了一系列非常重要的功能,这些插件会在许多阶段里发挥重要作用。

阶段

插件

作用

clean

clean

清理自动生成的文件,也就是 target 目录

validate

由 Maven 核心负责

验证 Maven 描述文件是否有效

compile

compiler、resources

编译 Java 源码

test

compiler、surefire、resources

运行测试代码

package

war

项目打包,就是生成构件包,也就是打 war

verify

Maven 核心负责

验证构件包是否有效

install

install

将构件包安装到本地仓库

site

site

生成项目站点,就是一堆静态网页文件,包括 JavaDoc

deploy

deploy

将构件包部署到远程仓库


以上表格中所出现的插件名称实际上是插件的别名(或称为前缀),比如:compiler 实际上是org.apache.maven.plugins:maven-compiler-plugin:2.3.2,这个才是 Maven 插件的完全名称。

每个插件又包括了一些列的 Goal(目标),以 compiler 插件为例,它包括以下目标:

·        compiler:help:用于显示 compiler 插件的使用帮助。

·        compiler:compile:用于编译 main 目录下的 Java 代码。

·        compiler:testCompile:用于编译 test 目录下的 Java 代码。

可见,插件目标才是具体干活的人,一个插件包括了一个多个目标,一个阶段可由零个或多个插件来提供支持。

我们可以在 pom.xml 中定义一些列的项目依赖(构件包),每个构件包都会有一个 Scope(作用域),它表示该构件包在什么时候起作用,包括以下五种:

1.   compile:默认作用域,在编译、测试、运行时有效

2.   test:对于测试时有效

3.   runtime:对于测试、运行时有效

4.   provided:对于编译、测试时有效,但在运行时无效

5.   system:与 provided 类似,但依赖于系统资源

可用一张矩阵表格来表示:

作用域

编译时有效

测试时有效

运行时有效

示例

compile

smart-framework.jar

test

junit.jar

runtime

mysql-connector-java.jar

provided

servlet-api.jar

system

JDK 的 rt.jar


如果您想开发一个 Smart 应用,可参考如下 p om.xml

<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>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <smart.version>1.0</smart.version>
    </properties>
 
    <groupId>com.smart</groupId>
    <artifactId>smart-demo</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>
 
    <dependencies>
        <!-- JUnit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.25</version>
            <scope>runtime</scope>
        </dependency>
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
            <scope>runtime</scope>
        </dependency>
        <!-- Smart -->
        <dependency>
            <groupId>com.smart</groupId>
            <artifactId>smart-framework</artifactId>
            <version>${smart.version}</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <!-- Compile -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <!-- Test -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.15</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <!-- War -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <warName>${project.artifactId}</warName>
                </configuration>
            </plugin>
            <!-- Tomcat -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
            </plugin>
        </plugins>
    </build>
 
</project>

以上 pom.xml 大致解释一下:

·        我们可使用 properties 来定义一些配置属性,例如:project.build.sourceEncoding(项目构建源码编码方式),可设置为 UTF-8,可防止中文乱码。也可定义相关构件包版本号,例如:smart.version,便于日后统一升级。

·        建议使用最新版本的 JUnit,通过 Archetype自动生成的 JUnit 太老了(3.8.1),可改为最新版(4.11)。

·        因为没必要使用 MySQL 客户端的 API,它仅仅在运行时有效,所以我们将 MySQL 构件包的作用域设置为 runtime。

·        因为我们只想在代码中使用 Servlet API,而不想将它所对应的 jar 包放入 WEB-INF 的lib 目录下,所以我们可设置 Servlet 构件包的作用域为 provided。

·        为了保证在 JDK 1.6 运行,我们可配置maven-compiler-plugin 插件,设置输入源码为 1.6,编译输出的字节码也为 1.6。

·        如果想跳过测试,可配置 maven-surefire-plugin 插件,将 skipTests 设置为 true。

·        如果想配置生成的 war 包为 artifactId,可修改 maven-war-plugin 插件,将 warName 修改为 ${project.artifactId},这样就无需再配置 finalName了。

·        如果想通过 Maven 将应用部署到Tomcat 中,可使用 tomcat7-maven-plugin 插件,可使用 mvn tomcat7:run-war 命令来运行 war 包。

5. 使用 Maven 命令

前面我们已经使用了几个 Maven命令,例如:mvn archetype:generate,mvntomcat7:run-war 等。其实,可使用两种不同的方式来执行 Maven 命令:

方式一:mvn<插件>:<目标>[参数]

方式二:mvn<阶段>

现在我们接触到的都是第一种方式,而第二种方式才是我们日常中使用最频繁的,例如:

·        mvn clean:清空输出目录(即 target 目录)

·        mvn compile:编译源代码

·        mvnpackage:生成构件包(一般为 jar 包或 war 包)

·        mvninstall:将构件包安装到本地仓库

·        mvn deploy:将构件包部署到远程仓库

6. 后记

Maven使 Java 开发更加规范化与自动化,其实 Maven 那点事远远不止这些,如果您掌握了以上这些基础知识,再去学习 Maven 的高级特性,我想一定会是一件非常轻松的事情。

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值