文章目录
  1. 1. Maven基本使用:
    1. 1.1. maven坐标
    2. 1.2. Maven依赖
    3. 1.3. Maven仓库管理:
    4. 1.4. Maven生命周期:
      1. 1.4.1. Clean生命周期
      2. 1.4.2. defaut生命周期
      3. 1.4.3. site生命周期
      4. 1.4.4. 命令行与生命周期
      5. 1.4.5. 生命周期与插件绑定
    5. 1.5. Maven的聚合与继承:
    6. 1.6. 使用Nexus创建私服
    7. 1.7. Maven执行单个测试类
    8. 1.8. Maven快速开发web项目
    9. 1.9. Maven的持续集成
    10. 1.10. Maven与自动化部署
    11. 1.11. 版本管理
    12. 1.12. Maven与项目release
    13. 1.13. 利用Maven自动化创建分支:
    14. 1.14. Maven与签名:
  2. 2. Maven灵活的构建:
    1. 2.1. Maven属性
    2. 2.2. 资源过滤
    3. 2.3. Maven Profile
      1. 2.3.1. Profile激活
      2. 2.3.2. profile的种类
    4. 2.4. web资源过滤、
  3. 3. Maven与自动化站点生成
  4. 4. Maven与代码检查及代码分析
  5. 5. 编写Maven插件的一般步骤
  6. 6. 常用archetype介绍
  7. 7. Maven常用插件列表:

Maven基本使用:

mvn help:system 打印出所有Java系统属性和环境变量,下载maven-help-plugin文件

Maven最主要的命令:mvn clean compile,mvn clean test,mvn clean package,mvn clean install.执行test之前会先执行compile的,执行package之前会先执行test,install(把jar包安装到仓库中供所有人使用) 之前会执行package,可以在任何一个Maven项目中执行这些命令。

可以直接运行mvn archetype:generate去生成项目基本骨架。会有很多Archetype供选择,包括著名的Appfuse项目的Archetype,JPA项目的Archetype等。每一个Archetype前面都会对应有一个编号,同时命令行会提示一个默认的编号,其对应的Archetype为maven-archetype-quickstart,直接回车以选择该Archetype,紧接着Maven会提示输入要创建项目的groupId,artifacetId,version以及包名package

maven坐标

groupId:  当前Maven项目隶属的实际项目,可以是域名反向

artifacId:  该元素定义实际项目中的一个Maven项目(模块),推荐的做法是使用实际项目名作为它的前缀

version:  当前版本

packaging:定义Maven项目的打包方式。首先,打包方式通常与所生成构件的文件扩展名对应。jar包和war包会使用不同的命令,当不定义packaging的时候,默认使用jar

classifier:  帮助定义构建输出的一些附属构件。附属构件与主构件对应

dependency  下面的scope用来定义依赖的范围。当为test的时候,该依赖只会被加入到测试代码的测试框架,只有在测试的时候才需要,对于项目主代码,该依赖是不没有任何作用的

Maven依赖

  可运行mvn dependency:list  查看当前项目的已解析依赖
  可以运行mvn dependency:tree  查看当前项目的依赖树
  使用mvn dependency:analyze  工具可以帮助分析当前项目的依赖

<project>
 <dependencies>
  <dependency>
   <groupId>..</groudId>
   <artifactId>..</artifactId>
   <version>..</version>
   <type>..</type><!--依赖的类型,对应于项目坐标定义的packaging,大部分情况下,该元素不必声明,其默认值为jar-->
   <sope>..</scope><!--依赖的范围 1.compile编译依赖范围。如果没有指定就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译,测试,运行三种classpath都有效
                                  2.test 测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,典型例子是Junit
             3.provided 已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是serlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已提供就不需要Maven重复地引入一遍-
             4.runtime 运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动
             5.system系统依赖范围,该依赖与三种classpath关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植性。
             6.import 导入依赖范围,该依赖范围不会对三种classpath产生实际影响->
   <optional>..</optional><!--标记依赖是否可选,可选依赖不会被传递-->

   <exclusions><!--用来排除传递性依赖-->
    <exclusion>
    </exclusion>
   </exclusions>
  </dependency>
 </dependencies>
</project>

Maven仓库管理:

http://repository.sonatype.org/

Nexus是当前最流行的开源Maven仓库管理软件,它提供了关键字搜索,`类名搜索,坐标搜索,校验和搜索等功能。

Maven生命周期:

Maven拥有三套相互独立的生命周期,它们分别是clean,defaultsite。clean生命周期的目的是清理项目,default生命周期的目的是构建项目,而site生命周期的目的是建立项目站点。

Clean生命周期

  1. pre-clean执行一些清理前需要完成的工作

  2. clean清理上一次构建生成的文件

  3. post-clean执行一些清理后需要完成的工作

defaut生命周期

default生命周期定义了真正构建时所需要执行的所有步骤,它是所有生命周期中最核心的部分

  1. validate

  2. initialize

  3. generate-sources

  4. process-sources 处理项目主资源文件。一般来说,是对src/main/resources目录的内容进行变更替换等工作后,复制到项目输出的主classpath目录中

  5. generate-resources

  6. process-resoures

  7. compile 编译项目的主源代码

  8. process-classes

  9. generate-test-sources

  10. process-test-sources 处理项目测试资源文件,一般来说是对src/test/resources目录的内容进行变量替换等工作后,复制到项目输出的测试classpath目录中

  11. generate-test-resoures

  12. process-test-resoures

  13. test-compile 编译项目的中测试代码

  14. process-test-classes

  15. test 使用单元测试框架运行测试,测试代码不会被打包或部署

  16. prepare-package

  17. package 接受编译好的代码,打包成可发布的格式

  18. pre-integration-test

  19. integration-test

  20. post-integration-test

  21. verify

  22. install 将包安装到Maven本地仓库,供本地其他Maven项目使用

  23. deploy 将最终的包复制到远程仓库,供其他开发人员和Maven项目使用

site生命周期

  1. pre-site执行一些在生成项目站点之前需要完成的工作

  2. site 生成项目站点文档

  3. post-site 执行一些在生成项目站点之后需要完成的工作

  4. site-deploy将生成的项目站点发布到服务器上

命令行与生命周期

mvn clean 调用clean生命周期的clean阶段

mvn test 调用defaut生命周期的test阶段

mvn clean install 调用clean生命周期的clean阶段和defaut生命周期的install阶段

mvn clean deploy site-deploy 调用了clean生命周期的clean阶段,default生命周期的deploy阶段,以及site生命周期的site-deploy阶段

生命周期与插件绑定

除了内置绑定外,用户还能够自己选择将某个目标绑定到生命周期的某个阶段上,这种自定义绑定方式能让Maven项目在构建过程中执行更多更富有特色的任务。
一个例子是创建项目的jar包,内置的插件绑定关系中并没有涉及这一任务。

<!--内置绑定源码-->
 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifacetId>maven-source-plugin</artifacetId>
    <version>2.1.2</version>
    <executions>
     <id>attach-soures</id>
     <phase>verify</phase>
     <goals>
     <goal>jar-no-fork</goal>
     </goals>
    </executions>
   </plugin>
  </plugins>
 </build>

Maven的聚合与继承:

Maven的聚合特性能够把项目的各个模块聚合在一起构建,而Maven的继承特性则能帮助抽取各模块相同的依赖和插件等配置,在简化pom的同时,还能促进各个模块配置的一致性。

与聚合模块一样,作为父模块的POM,其打包类型也必须为pom
哪些POM元素可以被继承:

groupId 项目组ID,项目坐标的核心元素
version 项目版本,项目坐标的核心元素
description 项目的描述信息
organization:项目的组织信息
inceptionYear 项目的创始年份
url 项目的URL地址
developers 项目的开发者
contributions项目的贡献者信息
distributionManagement:项目的部署配置
issueManagement:项目的缺陷跟踪系统信息
ciManagement项目的持续集成系统系统信息
scm 项目的版本控制系统信息
maillingLists:项目的邮件列表信息
properties:自定义Maven属性
dependencies:项目的依赖配置
dependencyManagement:项目的依赖管理配置
repositories项目的仓库配置
build 包括项目的源码目录配置,输出目录配置,插件配置,插件管理配置等
reporting:包括项目的报告输出目录,报告插件配置等

Maven提供的dependencyManagement元素既能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖

使用Nexus创建私服

私服不是Maven的核心概念,它仅仅是一种衍生出来的特殊的Maven仓库。通过建立自己的私服可以降低中央仓库负荷,节省外网带宽,加速Maven构建,自己部署构件等,从而高效地使用Maven

Maven执行单个测试类

Maven-surefire-plugin提供了一个test参数让Maven用户能够在命令行指定要运行的测试用例。如只想运行accout-captchaRandomGeneratioTest

$mvn test -Dtest=RandomGeneratorTest

这里test参数的值是测试用例的类名,参数还支持*和,来指定多个用例

Maven快速开发web项目

同任何Maven项目一样,Maven对Web项目的布局也有一个通用的约定,首先要记住的是用户必须为Web项目显式指定打包方式为war.使用jetty-maven-plugin进行web测试,它能够周期性地检查项目内容,发现变更后自动更新到内置 的Jetty web容器中。换句话说,它帮我们省去了打包和部署的步骤。在通常情况下,我们只需要直接在IDE中修改源码,IDE能够执行自动编译,jetty-maven-plugin发现编译后的文件变化后,自动将其更新到Jetty容器。使用它非常简单

<!--使用jetty-maven-plugin-->
   <plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifacetId>jetty-maven-plugin</artifacetId>
    <version>7.16</version>
    <configuration>
     <scanIntervalSeconds>10</scanIntervalSeconds>
     <webAppconfig>
      <contextPath>/test</contextPath><!--表示用户可以通过http://hostname:port/text/访问该应用-->
     </webAppconfig>
    </configuration>
   </plugin>

下一步启动jetty-maven-plugin。在此之前需要对settings.xml做个微小的修改。默认情况下只有org.apache.maven.pluginsorg.codehaus.mojo两个groupId下的插件才支持简化的命令行调用,即可以运行mvn help: system,但mvn jetty: run就不行。因为jetty-maven-plugin的groupId是org.mortbay.jetty。为了能在命令行直接运行mvn jetty: run用户需要配置settings.xml如下

<settings>
    <pluginGroups>
        <pluginGroup>org.mortbay.jetty</pluginGroup>
    <pluginGroups>
</settings>

默认是8080端口,如果希望使用其他端口,可以添加jetty.port参数 mvn jetty:run -Djetty.port=9999

启动Jetty后,用户可以在IDE中修改各类文件,如jsp,html,css,javascript甚至于java类。只要不是修改类名,方法名等较大的操作,jetty-maven-plugin都能扫描到变更并正确地将变化更新到Web容器中。

Maven的持续集成

Maven可以与hudson工具等对项目进行持续化集成,简单地说,持续集成就是快速且高频率地自动构建项目的所有源码,并为项目成员提供丰富的反馈信息。

Maven与自动化部署

Cargo能够帮助用户实现自动化部署,它通过cargo-maven2-plugin提供了Maven集成。它几乎支持所有的Web容器。虽然它与jetty-maven-plugin的功能看起来相似,但它们的目的是不同的,jetty-maven-plugin主要有来帮助日常的快速开发和测试,而cargo-maven2-plugin主要服务于自动化部署。如专门的测试人员只需要一条简单的Maven命令,就可以构建项目并部署到Web容器,然后进行功能测试。

它支持两种本地部署方式,分别是standalone模式和existing模式。

在standalone模式中,它会从web容器的安装目录复制一份配置到用户指定的目录,然后在此基础上部署应用,每次重新构建的时候,这个目录都会被清空,所有配置被重新生成。而在exiting模式中,用户需要指定现有的web容器配置目录,然后它会直接使用这些配置并将应用部署到其对应的位置。

<!--使用cargo自动化部署-->
   <plugin>
    <groupId>org.codehaus.cargo</groupId>
    <artifactId>cargo-maven2-plugin</artifactId>
    <version>1.0</version>
    <configuration>
     <container>
      <containerId>tomcat6x</containerId>
      <home>d:\cmd\apache-tomcat-6.21</home> 
     </container>
     <configuration>
      <type>standalone</type>
      <home>${project.build.directory}/tomecat6x</home>
     </configuration>
    </configuration>
   </plugin>

在setting.xml中加入引插件,在命令行中输入mvn cargo:start就可以启动了。其它类似,如果要部署到远程web容器,就要提供拥有该容器的相应管理员权限。

远程部署:

<!--使用cargo自动化部署到远程web容器-->
   <plugin>
    <groupId>org.codehaus.cargo</groupId>
    <artifactId>cargo-maven2-plugin</artifactId>
    <version>1.0</version>
    <configuration>
     <container>
      <containerId>tomcat6x</containerId>
      <home>remote</home><!--远程部署也必须是remot-->
     </container>
     <configuration>
      <type>runtime</type>

      <properties>
       <cargo.remote.username>admin</cargo.remote.username>
       <cargo.remote.password>admin</cargo.remote.password>
       <cargo.tomcat.manager.url>http://localhost:8080/manager</cargo.tomcat.manager.url>
      </properties>
     </configuration>
    </configuration>
   </plugin>

运行命令mvn cargo:redeploy就可以执行了。如果容器已经部署了当前应用,Cargo会先卸载,然后再重新部署

版本管理

  • 主干(trunk):项目开发代码的主体,是从项目开始直到当前都处于活动的状态。从这里可以获得项目最新的源代码以及几乎所有变更历史

  • 分支(branch):从主干的某个点分离出来的代码拷贝,通常可以在不影响主干的前提下在这里进行重大Bug的修复,或者做一些实验性质的开发。如果分支达到了预期的目的,通常发生在这里的变更会被合并(merge)到主干中。

  • 标签(tag)用来标识主干或者分支的某个点的状态,以代表项目的某个稳定状态。这通常就是版本发布时的状态。

Maven与项目release

Maven Release Plugin可以帮助我们发布项目版本

它主要有三个目标:

  1. release:prepare依次执行以下操作

    • 检查项目是否有未提交的代码
    • 检查项目是否有快照版本依赖
    • 根据用户的输入将快照版本升级为发布版
    • 将POM中的SCM信息更新为标签地址
    • 基于修改后的POM执行Maven构建
    • 提交POM变更
    • 基于用户输入为代码打标签
    • 将代码从发布版本升级为新的快照版
    • 提交POM变更
  2. releas:rollback 回退release:prepare所执行的操作,将POM回退至release:prepare之前的状态,并提交。需要注意的是,该步骤不会删除release:prepare生成的标签,因此用户需要手动删除

  3. release:perform 执行版本发布。签出release:prepare生成的标签中的源代码,并在此基础上执行mvn deploy命令打包并部署构件至仓库。

要为项目发布版本,首先需要为其添加正确的版本控制系统信息,因为Maven Release Plugin需要知道版本控制系统的主干,标签等地址信息后才能执行相关的操作。

<scm>
    <connection>scm:svn:http://....app/trunk</connection>
    <developerConnection>scm:svn:https://..../app/trunk</developerConnection>
    <url>http://.../account/trunk</url>
</scm>

上述代码中,connectin表示一个只读的scm地址,而developerConnection元素表示可写的scm地址,url则表示可以浏览器中访问的scm地址。为了能让Maven识别,connection和developerConnection必须以scm开头,冒号之后的部分表示版本控制工具类型。接下来才是实际的scm地址。

该配置只告诉Maven当前代码的位置(主干),而版本发布还要涉及标签操作。因此还要配置Maven Release Plugin告诉其标签的基础目录

<plugin>
    <groupId>org.apache.maven.plugins</plugin>
    <artifacetId>maven-release-plugin</artifacetId>
    <version>2.0</version>
    <configuration>
        <tagBase>https://localhost/app/tags</tagBase>
    </configuration>
</plugin>

利用Maven自动化创建分支:

在正式版本1.1.0发布的同时,还可以创建一个分支用来修复将来这个版本可能遇到的重大bug。这个过程可以手工完成。如使用svn的copy操作将主干代码复制到一个名为1.1.x的分支中,然后修改分支中的pom文件,升级其版本为1.1.1-snapshot

使用Maven Release Pluginbranch目标,它能够帮我们自动化这些操作:

  • 检查本地有无未提交的代码
  • 为分支更改POM的版本,
  • 将POM中的SCM信息更新为分支地址
  • 提交以上更新
  • 将主干的代码复制到分支中
  • 修改本地代码使其回退到分之前的版本(用户可以指定新的版本)
  • 提交本地更改

当然,为了让它为我们工作,和版本发布一样,必须在在pom中提供正确的scm信息,此外,由于分支操作会涉及版本控制系统里的分支地址,因此还要为它配置分支基础目录

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifacetId>maven-release-plugin</artifacetId>
    <version>2.0</version>
    <configuration>
        <tagBase>https://localhost/app/tags/</tagBase>
        <branchBase>https://localhost/app/branches/</branchBase>
    </configuration>
</plugin>

现在运行命令:

mvn release:branch -DbranchName = 1.1.x \ -DuddateBranchVersions = true -DupdateWorkingCopyVersions = false

-DbranchName = 1.1.x 用来配置所有创建分支的名称。

-DupdateBranchVersions = true表示为分支使用新的版本。

-DupdateWorkingCopyVersion = false表示不更新本地代码(即主干)的版本。

运行上述命令后,Maven会提示输入项目分支的版本

Maven与签名:

手动地对Maven构件进行签名并将这些签名部署到Maven仓库是一件耗时的体力活。而使用Maven GPG Plugin只需要提供几行简单的配置,它就能够帮我们自动完成签名这一工作。

<!--使用GPG给构件加签名-->
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifacetId>maven-gpg-plugin</artifacetId>
    <version>1.0</version>
    <executions>
     <execution>
      <id>sign-artifacts</id>
      <phase>verify</phase>
      <goals>
       <goal>sign</goal>
      </goals>
     </execution>
    </executions>
   </plugin>

然后使用一般mvn命令签名并发布项目构件:

mvn clean deploy -Dgpg.passphrase = yourpassphrase

如果不提供-Dgpg.passphrase参数,运行时就会要求输入密码

Maven灵活的构建:

Maven为了支持灵活的构建,内置了三大特性,即属性,Profile和资源过滤

Maven属性

maven有6类属性

  1. 内置属性: 主要有两个内置属性${basedir}表示项目的根目录,即包含pom.xml文件的目录。${version}表示项目版本
  2. POM属性 用户可以使用该类属性引用POM文件中对应元素的值。如 ${project.artifactId}对应<project><artifactId>元素的值。

    • ${project.build.sourceDirectory}项目主源码目录 默认src/main/java
    • ${project.build.testSourceDirectory}
    • ${project.build.directory} 默认target/
    • ${project.outputDirectory}项目主代码编译输出目录 默认为target/classes/
    • ${project.build.finalName}项目打包输出文件的名称,默认为${project.artifactId}-${project.version}
      这些属性都对应了一个POM元素,它们中的一些属性默认值都是在超级POM中定义的
  3. 自定义属性:用户可以POM的元素下自定义Maven属性如:

      

       <my.prop>hello</my.prop>
    

      
    然后在POM的其他地方使用${my.prop}的时候会被替换成hello

  4. Settings属性:与POM属性同理,用户使用以settings开关的属性引用settings.xml文件中XmL元素的值。如常用 的${setttings.localRespository}指向用户本地仓库的地址。

  5. Java系统属性 所有Java系统属性都可以使用Maven属性引用 。如${user.home}指向了用户目录。用户可以使用mvn help:system查看所有的Java系统属性

  6. 环境变量 :所有环境变量都可以使用以env.开头的Maven属性引用。如${env.JAVA_HOME}指代了JAVA_HOM环境变量的值。用户可以使用mvn help:system查看所有环境变量

正确使用这些Maven的属性可以帮助我们简化POM的配置和维护工作。

资源过滤

为了应对环境的变化,首先需要使用Maven属性将这些将会发生变化的部分提取出来。如数据库配置中,连接数据库使用的驱动类,URL,用户名和密码都可能发生变化,因此用maven属性取代它们:
  
database.jdbc.driverClass=${db.driver}
database.jdbc.connectionURL=${db.url}
database.jdbc.username=${db.username}
database.jdbc.password=${db.password}
既然使用了maven属性,就应该在某个地方定义它们,这里使用一个额外的profile将其包裹:

<profiles>
 <profile>
  <id>dev</id>
  <properties>
   <db.driver>com.mysql.jdbc.Driver</db.driver>
   <db.url>jdbc:mysql://localhost:3306/test</db.url>
   <db.username>dev</db.username>
   <db.password>dev-pwd</db.password>
  </properties>
 </profile>
</profiles>

这里Maven属性定义与直接在POM的properties元素下定义并无二致,这里使用一个id为dev的profile,其目的是将开发环境下的配置与其他环境区别开来。

有了属性定义,配置文件中也使用了这些属性。这还不行,Maven属性默认只有在POM中才会被解析,也就是说,${db.username}放到POM中会就test,但是如果放到src/main/resources/目录下的文件中,构建的时候它将仍然还是${db.username},因此,需要让Maven解析资源文件中的Maven属性。

资源文件的处理其实是maven-resource-plugin做的事情,它默认的行为只是将项目主资源文件复制到主代码编译输出目录中,将测试资源文件复制到测试代码编译输出目录中。不过只要通过一些简单的POM配置,该插件就能够解析资源文件中的Maven属性,即开启资源过滤。

Maven默认的主资源目录和测试资源目录的定义是在超级POM中,要为资源目录过滤,只要在此基础上添加一行filtering配置即可,

<resources>
    <resource>
        <directory>${project.basedir}/src/main/resoureces</directory>
<filtering>true</filtering>
    </resource>
</resources>

类似地可以为测试资源目录开启过滤。
到目前为止一切基本就绪了,我们将数据库配置的变化部分提取成了Maven属性,在POM的profile中定义了这些属性的值,并且为资源目录开启了属性过渡。最后,只需要在命令行激活profile,Maven就能够在构建项目的时候使用profile中属性值替换数据库配置文件中的属性引用。运行命令如下:

mvn clean install -Pdev

-P参数表示在命令行激活一个profile。这里激活了id为dev的profile.构建完成后,输出目录中的数据库配置就是开发环境的配置了。

Maven Profile

从前面内容我们可以看到,不同环境的构建很可能是不同的,典型的情况就是数据库配置。除此之外,有些环境可能需要配置插件使用本地文件,或者使用特殊版本的依赖,或者需要一个特殊的构件名称。为了能让构建在各个环境下方便地移植,Maven引入了profile概念。

profile能够在构建的时候修改POM的一个子集,或者添加额外的配置元素。用户可以使用很多方式激活profile,以实现构建在不同环境下的移植。

继续以数据库为例,如下配置引入了一个针对开发环境的profile,类似还可以加入测试环境和产品环境profile

<profiles>
 <profile>
  <id>dev</id>
  <properties>
   <db.driver>com.mysql.jdbc.Driver</db.driver>
   <db.url>jdbc:mysql://localhost:3306/dev</db.url>
   <db.username>dev</db.username>
   <db.password>dev-pwd</db.password>
  </properties>
 </profile>
 <profile>
  <id>test</id>
  <properties>
   <db.driver>com.mysql.jdbc.Driver</db.driver>
   <db.url>jdbc:mysql://localhost:3306/test</db.url>
   <db.username>test</db.username>
   <db.password>test-pwd</db.password>
  </properties>
 </profile>
</profiles>

同样的属性在两个profile中的值是不一样的,dev profile是开发环境数据库的配置,而test profile提供的是测试环境数据库的配置。现在开发人员可以使用mvn命令的时候在后面加上-Pdev激活dev profile,而测试人员可以使用-Ptest激活test Profile

Profile激活

为了方便用户,Maven支持多种激活Profile方式:

  1. 命令行激活
    用户可以使用mvn命令行参数-P加上profile的id来激活profile,多个id之间可以逗号分隔。如下激活了dev -x和dev -y两个profile

    mvn clean install -Pdev -x,dev -y
  2. settings文件显示激活
    如果用户希望某个profile默认一直处于激活状态,就可以配置settings.xml文件的activeProfiles元素,表示其配置的profile对于所有项目都处于激活状态。

    <settings>
        <activeProfiles>
            <activeProfile>dev -x</activeProfile>
        </activeProfiles>
    </settings>
    
  3. 系统属性激活
    用户可能配置当某系统属性存在的时候,自动激活profile

    <profiles>
        <profile>
            <activation>
                <property>
                    <name>test</name>
                </property>
            </activation>
        </profile>
    </profiles>
    

    可以进一步配置当某系统属性test存在,且值等于x时激活profile

    <profiles>
        <profile>
            <activation>
                <property>
                    <name>test</name>
                    <value>x</value>
                </property>
            </activation>
        </profile>
    </profiles>
    

    不要忘记,用户可以在命令行声明系统属性如:

    mvn clean install -Dtest=x

    因此这其实是一种从命令行激活profile的方法,而且多个profile完全可以使用同一个系统属性来激活

  4. 操作系统属性激活
    profile还可以自动根据操作系统环境激活,如果构建在不同的操作系统有差异,用户完全可以将这些差异写进profile,然后配置它们自动基于操作系统环境激活。

    <profiles>
        <profile>
            <activation>
                <os>
                    <name>Windows XP</name>
                    < family>Windows</family>
                    <arch>x86</arch>
                    <version>5.1.2600</version>
                </os>
            </activation>
        </profile>
    </profiles>
    

    这里family会值包括Windows,UNIX和Mac等,其它几项,name,arch,versin,用户可以通过查看环境中和系统属性os.name.os.arch.os.version获得

  5. 文件存在与否激活
    Maven能够根据项目中某个文件存在与否决定是否激活profile

    <profiles>
        <profile>
            <activation>
                <file>
                    <missing>x.properties</missing>
                    <exists>y.properties</exists>
                </file>
            </activation>
        </profile>
    </profiles>
    
  6. 默认激活

    用户可以在定义profile的时候指定其默认激活

    <profiles>
        <profile>
            <id>dev</id>
            <activation>
                <activeByDefalut>true</activeByDefault>
            </activation>
        </profile>
    </profiles>
    

    使用activeByDefault元素用户可以指定profile自动激活,需要注意的是,如果POM中有任何一个profile通过以上其他任意一种方式激活了,所有的默认激活配置都会失效。
    mvn提供了一个目标帮助用户了解当前激活的profile:

    mvn help:active-profiles

    mvn还有另外一个目标用来列出当前所有的profile

    mvn help:all-profiles

profile的种类

根据具体需要,可以在以下位置声明profile,

  • pom.xml 很显然pom.xml中声明的profile只对当前项目有效
  • 用户setting.xml,用户目录下.ml/settings.xml中的profile对本机上该用户所有的Maven项目有效
  • 全局settings.xml .Maven安装目录下conf/settings.xml中的profile对本机上所有的Maven项目有效
  • profiles.xml 还可以在项目根目录下使用一个额外的profiles.xml文件来声明profile,不过该特性已经在Maven3中被移除,建议用户将这类profile移到settings.xml中

web资源过滤、

在web项目中,资源文件同样位于src/main/resources/目录下,它们经处理后会位于war包的WEB_INF/classes目录下,这也是Jave代码编译打包后的目录。也就是说,这类资源文件在打包过后位于应用程序的classpath中。web项目中还有另外一类资源文件,默认它们的源码文件位于src/main/webapps/目录,经打包后位于war包根目录。如一个web项目的css源码文件在src/main/webapp/css/目录,项目打包后在war包的css/目录下找到对应的css文件。这一类资源文件称为web资源文件,它们在打包后不位于应用程序的classpath中。与一般的资源文件一样,web资源文件默认不会被过滤,开启一般资源文件的过滤也不会影响到web资源文件。

不过有的时候,我们可能希望在构建项目的时候,为不同的客户使用不一样的资源文件。这时可以在web资源文件中使用Maven属性。然后使用profile分别定义这些maven属性的值。最后需要配置maven-war-plugin对src/main/webapp/这一web资源目录开启过滤

<!--开启web资源过滤-->
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1</version>
    <configuration>
     <webResources>
      <filtering>true</filtering>
      <directory>src/main/webapp</directory>
      <includes>
       <include>**/*.css</include>
       <include>**/*.js</includes>
      </includes>
     </webResources>
    </configuration>
   </plugin>

Maven与自动化站点生成

Maven不仅仅是一个自动化构建工具和一个依赖管理工具,它还能够帮助聚合项目信息,促进团队间的交流。POM可以包含各种项目信息,如项目描述,版本控制系统地址,缺陷跟踪系统地址,许可证信息,开发者信息等。用户可以让Maven自动生成一个web站点,以web的形式发布这些信息。此外,Maven社区提供了大量插件,能让用户生成各种各样的项目审查报告,包括测试覆盖率,静态代码分析,代码变更等。使用maven-site-plugin插件

Maven与代码检查及代码分析

checkstyle代码检查插件,PMD是一款强大的源代码分析工具,它能够寻找代码中的问题,包括潜在的bug,无用代码,可优化代码,重复代码以及过于复杂的表达式。http://pmd.sourceforge.net/
要让Maven在站点生成PMD报告,只需要配置maven-pmd-plugin

Maven用户可以直接从命令行获得Effective POM(所有父pom及超级pom),mvn help:effective -pom

m2eclipse能够自动下载并使用依赖的源码包。用户在项目上右击,选择Maven,再选择Download Sources让m2eclipse为当前项目的依赖下载源码包

编写Maven插件的一般步骤

创建一个maven-plugin项目,插件本身也是Maven项目,特殊的地方在于它的packaging必须是maven-plugin,用户可以使用maven-archetype-plugin快速创建一个Maven插件项目

为插件编写目标。每个插件都必须以包含一个或多个目标。Maven称之为Mojo(与pojo相对应)。编写插件的时候必须提供一个或多个继承自AbstractMojo的类

为目标提供配置点,大部分Maven插件及其目标都是可以配置的,因此在编写Mojo的时候需要注意提供可配置的参数

编写代码实现目标行为:根据实际需要实现Mojo

错误处理及日志,当Mojo发生异常时,根据情况控制Maven的运行状态。在代码中编写必要的日志便为用户提供足够的信息

测试插件:编写自动化的测试代码测试行为,然后再实际运行插件以验证其行为

创建一个Mojo所我必要的三项是:继承AbstractMojo,实现execute()方法,提供@goal标注

常用archetype介绍

到目前为止,Maven仓库中已经包含了249个archetype(http://repol.maven.org/maven2/archetype-catalog.xml)

此外还有大量的没有发布到中央仓库中,
比较常见的是:

maven-archetype-quicksart 最常见的java项目基本骨架

maven-archetype-webapp 最简单的Maven war项目的模板
AppFuse Archetype AppFuse是一个集成了很多开源工具的项目,它由Matt Raible开发,旨在帮助 Jave编程人员快速高效地创建项目。AppFuse本身使用Maven构建,它的核心其实就是一个项目的骨架,是包含持久层,业务和展现层的一个基本结构。在AppFuse2.x中,已经集成了大量流行的开源工具,如Spring,Struts2,JPA,JSF,Tapestry等

AppFuse 为用户提供了大量Archetype,以方便用户快速创建各类型的项目,它们都使用同样的groupId org.appfuse.针对各种展现层分别为:

appfuse-*-jsf:基于JSF展现层框架的Archetype
appfuse-*-spring:基于Spring MVC展现框架的Archetype
appfuse-*-struts:基于struts2展现层框架的Archetype
appfuse-*-tapestry:基于Tapestry展现框架的Archetype

每一种展现层框架都有3个Archetype,分别为light,basic和modular,其中,light类型的Archetype只包含最简单的骨架,basic类型的Archetype则包含了一些用户管理及安全方面的特性。modular类型的Archetype会生成多模块的项目,其中的core模块包含了持久层及业务层的代码,而Web模块则是展现层的代码。

更多AppFuse 的信息可以访问官方入门手册:http://appfuse.org/display/apf/appfuse+quickstart

我们也可以自己动手编写一个archetype

Maven常用插件列表:

maven-clean-plugin 清理项目

maven-compile-plugin 编译项目

maven-deply-plugin 部署项目`

maven-install-plugin 安装项目

maven-resource-plugin 处理资源文件

maven-site-plugin 生成站点

maven-surefire-plugin 执行测试

maven-jar-plugin 构建JAR项目

maven-war-plugin 构建WAR项目

maven-shade-plugin 构建包含依赖的JAR包

maven-changelog-plugin 生成版本控制变更报告

maven-checkstyle-plugin 生成CheckStyle报告

maven-javadoc-plugin 生成JavaDoc文档

maven-jxr-plugin 生成源码交叉引用文档

maven-pmd-plugin 生成PMD报告

maven-project-info-reports-plugin 生成项目信息报告

maven-surefire-report-plugin 生成单元测试报告

maven-antrun-plugin 调用Ant任务

maven-archetype-plugin 基于Archetype 生成项目骨架

maven-assembly-plugin 构建自定义格式的分发包

maven-dependency-plugin 依赖分析及控制

maven-enforcer-plugin 定义规则并强制要求项目遵守

maven-pgp-plugin 为项目构件生成pgp签名

maven-help-plugin 获取项目及Maven环境的信息

maven-invoker-plugin 自动运行Maven项目构建并验证

maven-release-plugin 自动化项目版本发布

maven-scm-plugin 集成版本控制系统

maven-source-plugin 生成源码包

maven-eclipse-plugin 生成Eclipse项目环境配置

build-helper-maven-plugin 包含各种支持构建生命周期的目标

exec-maven-plugin 运行系统程序或者Java程序

jboss-maven-plugin 启动,停止Jboss部署项目

properties-maven-plugin 从properties文件读写Maven属性

sql-maven-plugin 运行SQL脚本

tomcat-maven-plugin 启动,停止Tomcat,部署项目

version-maven-plugin 自动化批量更新POM版本

cargo-maven-plugin 启动、停止、配置各类web容器自动化部署web项目

jetty-maven-plugin 集成Jetty容器,实现快速开发测试

maven-gae-plugin 集成Google App Engine

maven-license-plugin 自动化添加许可证证明至源码文件

maven-android-plugin 构建Android项目
可以去Apaceh,Codehaus,Googlecode上找到完整的插件列表。

文章目录
  1. 1. Maven基本使用:
    1. 1.1. maven坐标
    2. 1.2. Maven依赖
    3. 1.3. Maven仓库管理:
    4. 1.4. Maven生命周期:
      1. 1.4.1. Clean生命周期
      2. 1.4.2. defaut生命周期
      3. 1.4.3. site生命周期
      4. 1.4.4. 命令行与生命周期
      5. 1.4.5. 生命周期与插件绑定
    5. 1.5. Maven的聚合与继承:
    6. 1.6. 使用Nexus创建私服
    7. 1.7. Maven执行单个测试类
    8. 1.8. Maven快速开发web项目
    9. 1.9. Maven的持续集成
    10. 1.10. Maven与自动化部署
    11. 1.11. 版本管理
    12. 1.12. Maven与项目release
    13. 1.13. 利用Maven自动化创建分支:
    14. 1.14. Maven与签名:
  2. 2. Maven灵活的构建:
    1. 2.1. Maven属性
    2. 2.2. 资源过滤
    3. 2.3. Maven Profile
      1. 2.3.1. Profile激活
      2. 2.3.2. profile的种类
    4. 2.4. web资源过滤、
  3. 3. Maven与自动化站点生成
  4. 4. Maven与代码检查及代码分析
  5. 5. 编写Maven插件的一般步骤
  6. 6. 常用archetype介绍
  7. 7. Maven常用插件列表: