来自极客学院html
Apache Maven 是一套软件工程管理和整合工具。基于工程对象模型(POM)的概念,经过一个中央信息管理模块,Maven 可以管理项目的构建、报告和文档。前端
Maven 是一个项目管理和整合工具。Maven 为开发者提供了一套完整的构建生命周期框架。开发团队几乎不用花多少时间就可以自动完成工程的基础构建配置,由于 Maven 使用了一个标准的目录结构和一个默认的构建生命周期。java
在有多个开发团队环境的状况下,Maven 可以在很短的时间内使得每项工做都按照标准进行。由于大部分的工程配置操做都很是简单而且可复用,在建立报告、检查、构建和测试自动配置时,Maven 可让开发者的工做变得更简单。web
Maven 可以帮助开发者完成如下工做:spring
总的来讲,Maven 简化了工程的构建过程,并对其标准化。它无缝衔接了编译、发布、文档生成、团队合做和其余任务。Maven 提升了重用性,负责了大部分构建相关的任务。数据库
Maven 最初是在 Jakarta Turbine 项目中为了简化构建过程而设计的。项目中有几个子工程,每一个工程包含稍有不一样的 ANT 文件。JAR 文件使用 CVS 管理。apache
Apache 小组随后开发了 Maven,可以同时构建多个工程、发布工程信息、部署工程、在几个工程中共享 JAR 文件,而且协助团队合做。windows
Maven 的主要目的是为开发者提供api
Maven 工程结构和内容被定义在一个 xml 文件中 - pom.xml,是 Project Object Model (POM) 的简称,此文件是整个 Maven 系统的基础组件。详细内容请参考 Maven POM 部分。服务器
Maven 使用约定而不是配置,意味着开发者不须要再本身建立构建过程。
开发者不须要再关心每个配置细节。Maven 为工程提供了合理的默认行为。当建立 Maven 工程时,Maven 会建立默认的工程结构。开发者只须要合理的放置文件,而在 pom.xml 中再也不须要定义任何配置。
举例说明,下面的表格展现了工程源码文件、资源文件的默认配置,和其余一些配置。假定 ${basedir}
表示工程目录:
配置项
|
默认值
|
---|---|
source code | ${basedir}/src/main/java |
resources | ${basedir}/src/main/resources |
Tests | ${basedir}/src/test |
Complied byte code | ${basedir}/target |
distributable JAR | ${basedir}/target/classes |
为了构建工程,Maven 为开发者提供了选项来配置生命周期目标和工程依赖(依赖于 Maven 的插件扩展功能和默认的约定)。大部分的工程管理和构建相关的任务是由 Maven 插件完成的。
开发人员不须要了解每一个插件是如何工做的,就可以构建任何给定的 Maven 工程。详细内容请参考 Maven 插件部分。
POM 表明工程对象模型。它是使用 Maven 工做时的基本组建,是一个 xml 文件。它被放在工程根目录下,文件命名为 pom.xml。
POM 包含了关于工程和各类配置细节的信息,Maven 使用这些信息构建工程。
POM 也包含了目标和插件。当执行一个任务或者目标时,Maven 会查找当前目录下的 POM,从其中读取所须要的配置信息,而后执行目标。可以在 POM 中设置的一些配置以下:
在建立 POM 以前,咱们首先肯定工程组(groupId),及其名称(artifactId)和版本,在仓库中这些属性是工程的惟一标识。
<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> <groupId>com.companyname.project-group</groupId> <artifactId>project</artifactId> <version>1.0</version> </project>
须要说明的是每一个工程应该只有一个 POM 文件。
节点
|
描述
|
---|---|
groupId | 这是工程组的标识。它在一个组织或者项目中一般是惟一的。例如,一个银行组织 com.company.bank 拥有全部的和银行相关的项目。 |
artifactId | 这是工程的标识。它一般是工程的名称。例如,消费者银行。groupId 和 artifactId 一块儿定义了 artifact 在仓库中的位置。 |
version | 这是工程的版本号。在 artifact 的仓库中,它用来区分不一样的版本。例如: com.company.bank:consumer-banking:1.0 com.company.bank:consumer-banking:1.1. |
全部的 POM 都继承自一个父 POM(不管是否显式定义了这个父 POM)。父 POM 也被称做 Super POM,它包含了一些能够被继承的默认设置。
Maven 使用 effective pom(Super pom 加上工程本身的配置)来执行相关的目标,它帮助开发者在 pom.xml 中作尽量少的配置,固然这些配置能够被方便的重写。
查看 Super POM 默认配置的一个简单方法是执行如下命令:mvn help:effective-pom
在你的电脑上的任意目录下建立一个 pom.xml 文件,使用上面提到的示例 pom 中的内容。
在下面的例子中,咱们在 C:\MVN\project
目录中建立了一个 pom.xml 文件。
如今打开命令控制台,到 pom.xml 所在的目录下执行如下 mvn 命令。
C:\MVN\project>mvn help:effective-pom
Maven 将会开始处理并显示 effective-pom。
[INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'help'. [INFO] ------------------------------------------------------------------------ [INFO] Building Unnamed - com.companyname.project-group:project-name:jar:1.0 [INFO] task-segment: [help:effective-pom] (aggregator-style) [INFO] ------------------------------------------------------------------------ [INFO] [help:effective-pom {execution: default-cli}] [INFO] ..... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: < 1 second [INFO] Finished at: Thu Jul 05 11:41:51 IST 2012 [INFO] Final Memory: 6M/15M [INFO] ------------------------------------------------------------------------
Effective POM 的结果就像在控制台中显示的同样,通过继承、插值以后,使配置生效。
<?xml version="1.0" encoding="UTF-8"?> <!-- ================================================================= --> <!-- --> <!-- Generated by Maven Help Plugin on 2012-07-05T11:41:51 --> <!-- See: http://maven.apache.org/plugins/maven-help-plugin/ --> <!-- --> <!-- ================================================================= --> <!-- ================================================================= --> <!-- --> <!-- Effective POM for project --> <!-- 'com.companyname.project-group:project-name:jar:1.0' --> <!-- --> <!-- ================================================================= --> <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 h ttp://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.project-group</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <sourceDirectory>C:\MVN\project\src\main\java</sourceDirectory> <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory> <testSourceDirectory>C:\MVN\project\src\test\java</testSourceDirectory> <outputDirectory>C:\MVN\project\target\classes</outputDirectory> <testOutputDirectory>C:\MVN\project\target\test-classes</testOutputDirectory> <resources> <resource> <mergeId>resource-0</mergeId> <directory>C:\MVN\project\src\main\resources</directory> </resource> </resources> <testResources> <testResource> <mergeId>resource-1</mergeId> <directory>C:\MVN\project\src\test\resources</directory> </testResource> </testResources> <directory>C:\MVN\project\target</directory> <finalName>project-1.0</finalName> <pluginManagement> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.3</version> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-2</version> </plugin> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> </plugin> <plugin> <artifactId>maven-dependency-plugin</artifactId> <version>2.0</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.4</version> </plugin> <plugin> <artifactId>maven-ear-plugin</artifactId> <version>2.3.1</version> </plugin> <plugin> <artifactId>maven-ejb-plugin</artifactId> <version>2.1</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <artifactId>maven-javadoc-plugin</artifactId> <version>2.5</version> </plugin> <plugin> <artifactId>maven-plugin-plugin</artifactId> <version>2.4.3</version> </plugin> <plugin> <artifactId>maven-rar-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <artifactId>maven-release-plugin</artifactId> <version>2.0-beta-8</version> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.3</version> </plugin> <plugin> <artifactId>maven-site-plugin</artifactId> <version>2.0-beta-7</version> </plugin> <plugin> <artifactId>maven-source-plugin</artifactId> <version>2.0.4</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.4.3</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.1-alpha-2</version> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <artifactId>maven-help-plugin</artifactId> <version>2.1.1</version> </plugin> </plugins> </build> <repositories> <repository> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>Maven Repository Switchboard</name> <url>http://repo1.maven.org/maven2</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <releases> <updatePolicy>never</updatePolicy> </releases> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>Maven Plugin Repository</name> <url>http://repo1.maven.org/maven2</url> </pluginRepository> </pluginRepositories> <reporting> <outputDirectory>C:\MVN\project\target/site</outputDirectory> </reporting> </project>
在上面的 pom.xml 中,你能够看到 Maven 在执行目标时须要用到的默认工程源码目录结构、输出目录、须要的插件、仓库和报表目录。
Maven 的 pom.xml 文件也不须要手工编写。
Maven 提供了大量的原型插件来建立工程,包括工程结构和 pom.xml。
详细内容请参考 Maven - 插件 和 Maven - 建立工程 部分的内容。
构建生命周期是一组阶段的序列(sequence of phases),每一个阶段定义了目标被执行的顺序。这里的阶段是生命周期的一部分。
举例说明,一个典型的 Maven 构建生命周期是由如下几个阶段的序列组成的:
阶段
|
处理
|
描述
|
---|---|---|
prepare-resources | 资源拷贝 | 本阶段能够自定义须要拷贝的资源 |
compile | 编译 | 本阶段完成源代码编译 |
package | 打包 | 本阶段根据 pom.xml 中描述的打包配置建立 JAR / WAR 包 |
install | 安装 | 本阶段在本地 / 远程仓库中安装工程包 |
当须要在某个特定阶段以前或以后执行目标时,可使用 pre 和 post 来定义这个目标。
当 Maven 开始构建工程,会按照所定义的阶段序列的顺序执行每一个阶段注册的目标。Maven 有如下三个标准的生命周期:
目标表示一个特定的、对构建和管理工程有帮助的任务。它可能绑定了 0 个或多个构建阶段。没有绑定任何构建阶段的目标能够在构建生命周期以外被直接调用执行。
执行的顺序依赖于目标和构建阶段被调用的顺序。例如,考虑下面的命令。clean 和 package 参数是构建阶段,而 dependency:copy-dependencies 是一个目标。
mvn clean dependency:copy-dependencies package
这里的 clean 阶段将会被首先执行,而后 dependency:copy-dependencies 目标会被执行,最终 package 阶段被执行。
当咱们执行 mvn post-clean 命令时,Maven 调用 clean 生命周期,它包含如下阶段。
Maven 的 clean 目标(clean:clean)绑定到了 clean 生命周期的 clean 阶段。它的 clean:clean 目标经过删除构建目录删除了构建输出。因此当 mvn clean 命令执行时,Maven 删除了构建目录。
咱们能够经过在上面的 clean 生命周期的任何阶段定义目标来修改这部分的操做行为。
在下面的例子中,咱们将 maven-antrun-plugin:run 目标添加到 pre-clean、clean 和 post-clean 阶段中。这样咱们能够在 clean 生命周期的各个阶段显示文本信息。
咱们已经在 C:\MVN\project
目录下建立了一个 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.pre-clean</id> <phase>pre-clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>pre-clean phase</echo> </tasks> </configuration> </execution> <execution> <id>id.clean</id> <phase>clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>clean phase</echo> </tasks> </configuration> </execution> <execution> <id>id.post-clean</id> <phase>post-clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>post-clean phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行下面的 mvn 命令。
C:\MVN\project>mvn post-clean
Maven 将会开始处理并显示 clean 生命周期的全部阶段。
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------ [INFO] Building Unnamed - com.companyname.projectgroup:project:jar:1.0 [INFO] task-segment: [post-clean] [INFO] ------------------------------------------------------------------ [INFO] [antrun:run {execution: id.pre-clean}] [INFO] Executing tasks [echo] pre-clean phase [INFO] Executed tasks [INFO] [clean:clean {execution: default-clean}] [INFO] [antrun:run {execution: id.clean}] [INFO] Executing tasks [echo] clean phase [INFO] Executed tasks [INFO] [antrun:run {execution: id.post-clean}] [INFO] Executing tasks [echo] post-clean phase [INFO] Executed tasks [INFO] ------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------ [INFO] Total time: < 1 second [INFO] Finished at: Sat Jul 07 13:38:59 IST 2012 [INFO] Final Memory: 4M/44M [INFO] ------------------------------------------------------------------
你能够尝试修改 mvn clean 命令,来显示 pre-clean 和 clean,而在 post-clean 阶段不执行任何操做。
这是 Maven 的主要生命周期,被用于构建应用。包括下面的 23 个阶段。
生命周期阶段
|
描述
|
---|---|
validate | 检查工程配置是否正确,完成构建过程的全部必要信息是否可以获取到。 |
initialize | 初始化构建状态,例如设置属性。 |
generate-sources | 生成编译阶段须要包含的任何源码文件。 |
process-sources | 处理源代码,例如,过滤任何值(filter any value)。 |
generate-resources | 生成工程包中须要包含的资源文件。 |
process-resources | 拷贝和处理资源文件到目的目录中,为打包阶段作准备。 |
compile | 编译工程源码。 |
process-classes | 处理编译生成的文件,例如 Java Class 字节码的增强和优化。 |
generate-test-sources | 生成编译阶段须要包含的任何测试源代码。 |
process-test-sources | 处理测试源代码,例如,过滤任何值(filter any values)。 |
test-compile | 编译测试源代码到测试目的目录。 |
process-test-classes | 处理测试代码文件编译后生成的文件。 |
test | 使用适当的单元测试框架(例如JUnit)运行测试。 |
prepare-package | 在真正打包以前,为准备打包执行任何须要的操做。 |
package | 获取编译后的代码,并按照可发布的格式进行打包,例如 JAR、WAR 或者 EAR 文件。 |
pre-integration-test | 在集成测试执行以前,执行所需的操做。例如,设置所需的环境变量。 |
integration-test | 处理和部署必须的工程包到集成测试可以运行的环境中。 |
post-integration-test | 在集成测试被执行后执行必要的操做。例如,清理环境。 |
verify | 运行检查操做来验证工程包是有效的,并知足质量要求。 |
install | 安装工程包到本地仓库中,该仓库能够做为本地其余工程的依赖。 |
deploy | 拷贝最终的工程包到远程仓库中,以共享给其余开发人员和工程。 |
有一些与 Maven 生命周期相关的重要概念须要说明:
当一个阶段经过 Maven 命令调用时,例如 mvn compile,只有该阶段以前以及包括该阶段在内的全部阶段会被执行。
不一样的 maven 目标将根据打包的类型(JAR / WAR / EAR),被绑定到不一样的 Maven 生命周期阶段。
在下面的例子中,咱们将 maven-antrun-plugin:run 目标添加到 Build 生命周期的一部分阶段中。这样咱们能够显示生命周期的文本信息。
咱们已经更新了 C:\MVN\project 目录下的 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.validate</id> <phase>validate</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>validate phase</echo> </tasks> </configuration> </execution> <execution> <id>id.compile</id> <phase>compile</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>compile phase</echo> </tasks> </configuration> </execution> <execution> <id>id.test</id> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>test phase</echo> </tasks> </configuration> </execution> <execution> <id>id.package</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>package phase</echo> </tasks> </configuration> </execution> <execution> <id>id.deploy</id> <phase>deploy</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>deploy phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行如下 mvn 命令。
C:\MVN\project>mvn compile
Maven 将会开始处理并显示直到编译阶段的构建生命周期的各个阶段。
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------ [INFO] Building Unnamed - com.companyname.projectgroup:project:jar:1.0 [INFO] task-segment: [compile] [INFO] ------------------------------------------------------------------ [INFO] [antrun:run {execution: id.validate}] [INFO] Executing tasks [echo] validate phase [INFO] Executed tasks [INFO] [resources:resources {execution: default-resources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MVN\project\src\main\resources [INFO] [compiler:compile {execution: default-compile}] [INFO] Nothing to compile - all classes are up to date [INFO] [antrun:run {execution: id.compile}] [INFO] Executing tasks [echo] compile phase [INFO] Executed tasks [INFO] ------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------ [INFO] Total time: 2 seconds [INFO] Finished at: Sat Jul 07 20:18:25 IST 2012 [INFO] Final Memory: 7M/64M [INFO] ------------------------------------------------------------------
Maven Site 插件通常用来建立新的报告文档、部署站点等。
阶段:
在下面的例子中,咱们将 maven-antrun-plugin:run 目标添加到 Site 生命周期的全部阶段中。这样咱们能够显示生命周期的全部文本信息。
咱们已经更新了 C:\MVN\project 目录下的 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.pre-site</id> <phase>pre-site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>pre-site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.site</id> <phase>site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.post-site</id> <phase>post-site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>post-site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.site-deploy</id> <phase>site-deploy</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>site-deploy phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行如下 mvn 命令。
C:\MVN\project>mvn site
Maven 将会开始处理并显示直到 site 阶段的 site 生命周期的各个阶段。
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------ [INFO] Building Unnamed - com.companyname.projectgroup:project:jar:1.0 [INFO] task-segment: [site] [INFO] ------------------------------------------------------------------ [INFO] [antrun:run {execution: id.pre-site}] [INFO] Executing tasks [echo] pre-site phase [INFO] Executed tasks [INFO] [site:site {execution: default-site}] [INFO] Generating "About" report. [INFO] Generating "Issue Tracking" report. [INFO] Generating "Project Team" report. [INFO] Generating "Dependencies" report. [INFO] Generating "Project Plugins" report. [INFO] Generating "Continuous Integration" report. [INFO] Generating "Source Repository" report. [INFO] Generating "Project License" report. [INFO] Generating "Mailing Lists" report. [INFO] Generating "Plugin Management" report. [INFO] Generating "Project Summary" report. [INFO] [antrun:run {execution: id.site}] [INFO] Executing tasks [echo] site phase [INFO] Executed tasks [INFO] ------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------ [INFO] Total time: 3 seconds [INFO] Finished at: Sat Jul 07 15:25:10 IST 2012 [INFO] Final Memory: 24M/149M [INFO] ------------------------------------------------------------------```
构建配置文件是一组配置的集合,用来设置或者覆盖 Maven 构建的默认配置。使用构建配置文件,能够为不一样的环境定制构建过程,例如 Producation 和 Development 环境。
Profile 在 pom.xml 中使用 activeProfiles / profiles 元素指定,而且能够用不少方式触发。Profile 在构建时修改 POM,而且为变量设置不一样的目标环境(例如,在开发、测试和产品环境中的数据库服务器路径)。
Profile 主要有三种类型。
类型
|
在哪里定义
|
---|---|
Per Project | 定义在工程 POM 文件 pom.xml 中 |
Per User | 定义在 Maven 设置 xml 文件中 (%USER_HOME%/.m2/settings.xml) |
Global | 定义在 Maven 全局配置 xml 文件中 (%M2_HOME%/conf/settings.xml) |
Maven 的 Profile 可以经过几种不一样的方式激活。
咱们假定你的工程目录像下面这样:
如今,在 src/main/resources 目录下有三个环境配置文件:
文件名称
|
描述
|
---|---|
env.properties | 没有配置文件时的默认配置 |
env.test.properties | 使用测试配置文件时的测试配置 |
env.prod.properties | 使用产品配置文件时的产品配置 |
在接下来的例子中,咱们将 attach maven-antrun-plugin:run 目标添加到测试阶段中。这样能够咱们在不一样的 Profile 中输出文本信息。咱们将使用 pom.xml 来定义不一样的 Profile,并在命令控制台中使用 maven 命令激活 Profile。
假定,咱们在 C:\MVN\project 目录下建立了如下的 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <profiles> <profile> <id>test</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>Using env.test.properties</echo> <copy file="src/main/resources/env.test.propertiestofile ="${project.build.outputDirectory}/env.properties"/> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行如下 mvn 命令。使用 -P 选项指定 Profile 的名称。
C:\MVN\project>mvn test -Ptest
Maven 将开始处理并显示 test Profile 的结果。
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------ [INFO] Building Unnamed - com.companyname.projectgroup:project:jar:1.0 [INFO] task-segment: [test] [INFO] ------------------------------------------------------------------ [INFO] [resources:resources {execution: default-resources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 3 resources [INFO] [compiler:compile {execution: default-compile}] [INFO] Nothing to compile - all classes are up to date [INFO] [resources:testResources {execution: default-testResources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MVN\project\src\test\resources [INFO] [compiler:testCompile {execution: default-testCompile}] [INFO] Nothing to compile - all classes are up to date [INFO] [surefire:test {execution: default-test}] [INFO] Surefire report directory: C:\MVN\project\target\surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- There are no tests to run. Results : Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 [INFO] [antrun:run {execution: default}] [INFO] Executing tasks [echo] Using env.test.properties [INFO] Executed tasks [INFO] ------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------ [INFO] Total time: 1 second [INFO] Finished at: Sun Jul 08 14:55:41 IST 2012 [INFO] Final Memory: 8M/64M [INFO] ------------------------------------------------------------------
如今咱们练习一下,你能够按照下面的步骤作:
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行下面的 mvn 命令。使用 -P 选项指定 Profile 的名称。
C:\MVN\project>mvn test -Pnormal C:\MVN\project>mvn test -Pprod
检查构建的输出看看有什么不一样。
打开 Maven 的 settings.xml 文件,该文件能够在 %USER_HOME%/.m2 目录下找到,%USER_HOME% 表示用户主目录。若是 settings.xml 文件不存在则须要建立一个。
像在下面例子中展现的同样,使用 activeProfiles 节点添加 test 配置做为激活的 Profile。
<settings 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/settings-1.0.0.xsd"> <mirrors> <mirror> <id>maven.dev.snaponglobal.com</id> <name>Internal Artifactory Maven repository</name> <url>http://repo1.maven.org/maven2/</url> <mirrorOf>*</mirrorOf> </mirror> </mirrors> <activeProfiles> <activeProfile>test</activeProfile> </activeProfiles> </settings>
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行下面的 mvn 命令。不要使用 -P 选项指定 Profile 的名称。Maven 将显示被激活的 test Profile 的结果。
C:\MVN\project>mvn test
如今从 maven 的 settings.xml 中删除激活的 Profile,并更新 pom.xml 中的 test Profile。将下面的内容添加到 profile 元素的 activation 元素中。
当系统属性 “env” 被设置为 “test” 时,test 配置将会被触发。建立一个环境变量 “env” 并设置它的值为 “test”。
<profile> <id>test</id> <activation> <property> <name>env</name> <value>test</value> </property> </activation> </profile>
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行下面的 mvn 命令。
C:\MVN\project>mvn test
activation 元素包含下面的操做系统信息。当系统为 windows XP 时,test Profile 将会被触发。
<profile> <id>test</id> <activation> <os> <name>Windows XP</name> <family>Windows</family> <arch>x86</arch> <version>5.1.2600</version> </os> </activation> </profile>
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行下面的 mvn 命令。不要使用 -P 选项指定 Profile 的名称。Maven 将显示被激活的 test Profile 的结果。
C:\MVN\project>mvn test
如今使用 activation 元素包含下面的操做系统信息。当 target/generated-sources/axistools/wsdl2java/com/companyname/group 缺失时,test Profile 将会被触发。
<profile> <id>test</id> <activation> <file> <missing>target/generated-sources/axistools/wsdl2java/ com/companyname/group</missing> </file> </activation> </profile>
如今打开命令控制台,跳转到 pom.xml 所在目录,并执行下面的 mvn 命令。不要使用 -P 选项指定 Profile 的名称。Maven 将显示被激活的 test Profile 的结果。
C:\MVN\project>mvn test
在 Maven 的术语中,仓库是一个位置(place),例如目录,能够存储全部的工程 jar 文件、library jar 文件、插件或任何其余的工程指定的文件。
Maven 仓库有三种类型:
Maven 本地仓库是机器上的一个文件夹。它在你第一次运行任何 maven 命令的时候建立。
Maven 本地仓库保存你的工程的全部依赖(library jar、plugin jar 等)。当你运行一次 Maven 构建,Maven 会自动下载全部依赖的 jar 文件到本地仓库中。它避免了每次构建时都引用存放在远程机器上的依赖文件。
Maven 本地仓库默认被建立在 %USER_HOME% 目录下。要修改默认位置,在 %M2_HOME%\conf 目录中的 Maven 的 settings.xml 文件中定义另外一个路径。
<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>C:/MyLocalRepository</localRepository> </settings>
当你运行 Maven 命令,Maven 将下载依赖的文件到你指定的路径中。
Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量经常使用的库。
中央仓库的关键概念:
要浏览中央仓库的内容,maven 社区提供了一个 URL: http://search.maven.org/#browse。使用这个仓库,开发人员能够搜索全部能够获取的代码库。
若是 Maven 在中央仓库中也找不到依赖的库文件,它会中止构建过程并输出错误信息到控制台。为避免这种状况,Maven 提供了远程仓库的概念,它是开发人员本身定制仓库,包含了所须要的代码库或者其余工程中用到的 jar 文件。
举例说明,使用下面的 POM.xml,Maven 将从远程仓库中下载该 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>com.companyname.common-lib</groupId> <artifactId>common-lib</artifactId> <version>1.0.0</version> </dependency> <dependencies> <repositories> <repository> <id>companyname.lib1</id> <url>http://download.companyname.org/maven2/lib1</url> </repository> <repository> <id>companyname.lib2</id> <url>http://download.companyname.org/maven2/lib2</url> </repository> </repositories> </project>
当咱们执行 Maven 构建命令时,Maven 开始按照如下顺序查找依赖的库:
Maven 其实是一个依赖插件执行的框架,每一个任务其实是由插件完成。Maven 插件一般被用来:
插件一般提供了一个目标的集合,而且可使用下面的语法执行:
mvn [plugin-name]:[goal-name]
例如,一个 Java 工程可使用 maven-compiler-plugin 的 compile-goal 编译,使用如下命令:
mvn compiler:compile
Maven 提供了下面两种类型的插件:
类型
|
描述
|
---|---|
Build plugins | 在构建时执行,并在 pom.xml 的 元素中配置。 |
Reporting plugins | 在网站生成过程当中执行,并在 pom.xml 的 元素中配置。 |
下面是一些经常使用插件的列表:
插件
|
描述
|
---|---|
clean | 构建以后清理目标文件。删除目标目录。 |
compiler | 编译 Java 源文件。 |
surefile | 运行 JUnit 单元测试。建立测试报告。 |
jar | 从当前工程中构建 JAR 文件。 |
war | 从当前工程中构建 WAR 文件。 |
javadoc | 为工程生成 Javadoc。 |
antrun | 从构建过程的任意一个阶段中运行一个 ant 任务的集合。 |
咱们已经在咱们的例子中大量使用了 maven-antrun-plugin 来输出数据到控制台上。请查看 Maven - 构建配置文件 章节。让咱们用一种更好的方式理解这部份内容,在 C:\MVN\project 目录下建立一个 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.clean</id> <phase>clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>clean phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
接下来,打开命令终端跳转到 pom.xml 所在的目录,并执行下面的 mvn 命令。
C:\MVN\project>mvn clean
Maven 将开始处理并显示 clean 生命周期的 clean 阶段。
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------ [INFO] Building Unnamed - com.companyname.projectgroup:project:jar:1.0 [INFO] task-segment: [post-clean] [INFO] ------------------------------------------------------------------ [INFO] [clean:clean {execution: default-clean}] [INFO] [antrun:run {execution: id.clean}] [INFO] Executing tasks [echo] clean phase [INFO] Executed tasks [INFO] ------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------ [INFO] Total time: < 1 second [INFO] Finished at: Sat Jul 07 13:38:59 IST 2012 [INFO] Final Memory: 4M/44M [INFO] ------------------------------------------------------------------
上面的例子展现了如下关键概念:
Maven 使用原型(archetype)插件建立工程。要建立一个简单的 Java 应用,咱们将使用 maven-archetype-quickstart 插件。在下面的例子中,咱们将在 C:\MVN 文件夹下建立一个基于 maven 的 java 应用工程。
咱们打开命令控制台,跳转到 C:\MVN 目录,并执行下面的 mvn 命令。
C:\MVN>mvn archetype:generate -DgroupId=com.companyname.bank -DartifactId=consumerBanking -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Maven 将开始处理,并将建立完成的 java 应用工程结构。
INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'archetype'. [INFO] ------------------------------------------------------------------- [INFO] Building Maven Default Project [INFO] task-segment: [archetype:generate] (aggregator-style) [INFO] ------------------------------------------------------------------- [INFO] Preparing archetype:generate [INFO] No goals needed for project - skipping [INFO] [archetype:generate {execution: default-cli}] [INFO] Generating project in Batch mode [INFO] ------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0 [INFO] ------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.companyname.bank [INFO] Parameter: packageName, Value: com.companyname.bank [INFO] Parameter: package, Value: com.companyname.bank [INFO] Parameter: artifactId, Value: consumerBanking [INFO] Parameter: basedir, Value: C:\MVN [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: C:\MVN\consumerBanking [INFO] ------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------ [INFO] Total time: 14 seconds [INFO] Finished at: Tue Jul 10 15:38:58 IST 2012 [INFO] Final Memory: 21M/124M [INFO] ------------------------------------------------------------------
如今跳转到 C:/MVN 目录。有将看到一个名为 consumerBanking 的 java 应用工程(就像在 artifactId 中设定的同样)。Maven 使用一套标准的目录结构,就像这样:
使用上面的例子,咱们能够知道下面几个关键概念:
文件夹结构
|
描述
|
---|---|
consumerBanking | 包含 src 文件夹和 pom.xml |
src/main/java contains | java 代码文件在包结构下(com/companyName/bank)。 |
src/main/test contains | 测试代码文件在包结构下(com/companyName/bank)。 |
src/main/resources | 包含了 图片 / 属性 文件(在上面的例子中,咱们须要手动建立这个结构)。 |
Maven 也建立了一个简单的 Java 源文件和 Java 测试文件。打开 C:\MVN\consumerBanking\src\main\java\com\companyname\bank 文件夹,能够看到 App.java 文件。
package com.companyname.bank; /** * Hello world! * */ public class App { public static void main( String[] args ) { System.out.println( "Hello World!" ); } }
打开 C:\MVN\consumerBanking\src\test\java\com\companyname\bank 文件夹,能够看到 AppTest.java。
package com.companyname.bank; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Unit test for simple App. */ public class AppTest extends TestCase { /** * Create the test case * * @param testName name of the test case */ public AppTest( String testName ) { super( testName ); } /** * @return the suite of tests being tested */ public static Test suite() { return new TestSuite( AppTest.class ); } /** * Rigourous Test :-) */ public void testApp() { assertTrue( true ); } }
开发人员须要将他们的文件按照上面表格中提到的结构放置好,接下来 Maven 将会搞定全部构建相关的复杂任务。
在下个章节中,咱们将讨论如何使用 maven 构建和测试工程:Maven - 构建 & 测试工程。
咱们在建立工程章节中学到的是如何使用 Maven 建立 Java 应用。如今咱们将看到如何构建和测试这个应用。
跳转到 C:/MVN 目录下,既你的 java 应用目录下。打开 consumerBanking 文件夹。你将看到 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> </dependency> </dependencies> </project>
能够看到,Maven 已经添加了 JUnit 做为测试框架。默认 Maven 添加了一个源码文件 App.java 和一个测试文件AppTest.java 到上个章节中咱们提到的默认目录结构中。
打开命令控制台,跳转到 C:\MVN\consumerBanking 目录下,并执行如下 mvn 命令。
C:\MVN\consumerBanking>mvn clean package
Maven 将开始构建工程。
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------- [INFO] Building consumerBanking [INFO] task-segment: [clean, package] [INFO] ------------------------------------------------------------------- [INFO] [clean:clean {execution: default-clean}] [INFO] Deleting directory C:\MVN\consumerBanking\target [INFO] [resources:resources {execution: default-resources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MVN\consumerBanking\src\main\ resources [INFO] [compiler:compile {execution: default-compile}] [INFO] Compiling 1 source file to C:\MVN\consumerBanking\target\classes [INFO] [resources:testResources {execution: default-testResources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MVN\consumerBanking\src\test\ resources [INFO] [compiler:testCompile {execution: default-testCompile}] [INFO] Compiling 1 source file to C:\MVN\consumerBanking\target\test-classes [INFO] [surefire:test {execution: default-test}] [INFO] Surefire report directory: C:\MVN\consumerBanking\target\ surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.companyname.bank.AppTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.027 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [jar:jar {execution: default-jar}] [INFO] Building jar: C:\MVN\consumerBanking\target\ consumerBanking-1.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2 seconds [INFO] Finished at: Tue Jul 10 16:52:18 IST 2012 [INFO] Final Memory: 16M/89M [INFO] ------------------------------------------------------------------------
你已经构建了你的工程并建立了最终的 jar 文件,下面是要学习的关键概念:
如今打开命令控制台,跳转到 C:\MVN\consumerBanking\target\classes 目录,并执行下面的 java 命令。
C:\MVN\consumerBanking\target\classes>java com.companyname.bank.App
你能够看到结果:
Hello World!
咱们看看如何添加其余的 Java 文件到工程中。打开 C:\MVN\consumerBanking\src\main\java\com\companyname\bank 文件夹,在其中建立 Util 类 Util.java。
package com.companyname.bank; public class Util { public static void printMessage(String message){ System.out.println(message); } }
更新 App 类来使用 Util 类。
package com.companyname.bank; /** * Hello world! * */ public class App { public static void main( String[] args ) { Util.printMessage("Hello World!"); } }
如今打开命令控制台,跳转到 C:\MVN\consumerBanking 目录下,并执行下面的 mvn 命令。
C:\MVN\consumerBanking>mvn clean compile
在 Maven 构建成功以后,跳转到 C:\MVN\consumerBanking\target\classes 目录下,并执行下面的 java 命令。
C:\MVN\consumerBanking\target\classes>java -cp com.companyname.bank.App
你能够看到结果:
Hello World!
如今,如你所知道的,Maven的依赖管理使用的是 Maven - 仓库 的概念。可是若是在远程仓库和中央仓库中,依赖不能被知足,如何解决呢? Maven 使用外部依赖的概念来解决这个问题。
例如,让咱们对在 Maven - 建立工程 部分建立的项目作如下修改:
如今,咱们的工程结构应该像下图同样:
如今你有了本身的工程库(library),一般状况下它会包含一些任何仓库没法使用,而且 maven 也没法下载的 jar 文件。若是你的代码正在使用这个库,那么 Maven 的构建过程将会失败,由于在编译阶段它不能下载或者引用这个库。
为了处理这种状况,让咱们用如下方式,将这个外部依赖添加到 maven 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.companyname.bank</groupId> <artifactId>consumerBanking</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>consumerBanking</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>ldapjdk</groupId> <artifactId>ldapjdk</artifactId> <scope>system</scope> <version>1.0</version> <systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath> </dependency> </dependencies> </project>
上例中, <dependencies>
的第二个 <dependency>
元素 , 阐明了外部依赖的关键概念。
但愿如今你懂得了有关外部依赖的知识,你将可以在你的 Maven 工程中指定外部依赖。
本教程将教你如何建立应用程序的文档。那么让咱们开始吧,在 C:/ MVN 目录下,建立你的 javaconsumerBanking 应用程序。打开 consumerBanking 文件夹并执行如下 mvn 命令。
C:\MVN>mvn site
Maven 将开始构建工程。
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------- [INFO] Building consumerBanking [INFO]task-segment: [site] [INFO] ------------------------------------------------------------------- [INFO] [site:site {execution: default-site}] [INFO] artifact org.apache.maven.skins:maven-default-skin: checking for updates from central [INFO] Generating "About" report. [INFO] Generating "Issue Tracking" report. [INFO] Generating "Project Team" report. [INFO] Generating "Dependencies" report. [INFO] Generating "Continuous Integration" report. [INFO] Generating "Source Repository" report. [INFO] Generating "Project License" report. [INFO] Generating "Mailing Lists" report. [INFO] Generating "Plugin Management" report. [INFO] Generating "Project Summary" report. [INFO] ------------------------------------------------------------------- [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------- [INFO] Total time: 16 seconds [INFO] Finished at: Wed Jul 11 18:11:18 IST 2012 [INFO] Final Memory: 23M/148M [INFO] -------------------------------------------------------------------
打开 C:\MVN\consumerBanking\target\site 文件夹。点击 index.html 就能够看到文档了。
Maven 使用称做 Doxia 的文件处理引擎建立文档,它将多个源格式的文件转换为一个共通的文档模型。要编写工程文档,你可使用如下可以被 Doxia 解析的几种经常使用格式来编写。
格式名称
|
描述
|
引用
|
---|---|---|
XDoc | Maven 1.x 版本的文档格式 | http://jakarta.apache.org/site/jakarta-site2.html |
FML | FAQ 文档格式 | http://maven.apache.org/doxia/references/fml-format.html |
XHTML | 可扩展 HTML 格式 | http://en.wikipedia.org/wiki/XHTML |
Maven 使用原型(Archetype)概念为用户提供了大量不一样类型的工程模版(614 个)。Maven 使用下面的命令帮助用户快速建立 java 项目。
mvn archetype:generate
原型是一个 Maven 插件,它的任务是根据模板建立一个项目结构。咱们将使用 quickstart 原型插件建立一个简单的 java 应用程序。
让咱们打开命令控制台,跳转到 C:\ > MVN 目录并执行如下 mvn 命令
C:\MVN>mvn archetype:generate
Maven 将开始处理,并要求选择所需的原型
INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'archetype'. [INFO] ------------------------------------------------------------------- [INFO] Building Maven Default Project [INFO]task-segment: [archetype:generate] (aggregator-style) [INFO] ------------------------------------------------------------------- [INFO] Preparing archetype:generate ... 600: remote -> org.trailsframework:trails-archetype (-) 601: remote -> org.trailsframework:trails-secure-archetype (-) 602: remote -> org.tynamo:tynamo-archetype (-) 603: remote -> org.wicketstuff.scala:wicket-scala-archetype (-) 604: remote -> org.wicketstuff.scala:wicketstuff-scala-archetype Basic setup for a project that combines Scala and Wicket, depending on the Wicket-Scala project. Includes an example Specs test.) 605: remote -> org.wikbook:wikbook.archetype (-) 606: remote -> org.xaloon.archetype:xaloon-archetype-wicket-jpa-glassfish (-) 607: remote -> org.xaloon.archetype:xaloon-archetype-wicket-jpa-spring (-) 608: remote -> org.xwiki.commons:xwiki-commons-component-archetype (Make it easy to create a maven project for creating XWiki Components.) 609: remote -> org.xwiki.rendering:xwiki-rendering-archetype-macro (Make it easy to create a maven project for creating XWiki Rendering Macros.) 610: remote -> org.zkoss:zk-archetype-component (The ZK Component archetype) 611: remote -> org.zkoss:zk-archetype-webapp (The ZK wepapp archetype) 612: remote -> ru.circumflex:circumflex-archetype (-) 613: remote -> se.vgregion.javg.maven.archetypes:javg-minimal-archetype (-) 614: remote -> sk.seges.sesam:sesam-annotation-archetype (-) Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 203:
按下 Enter 选择默认选项 (203:maven-archetype-quickstart)
Maven 将询问原型的版本
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 1: 1.0-alpha-1 2: 1.0-alpha-2 3: 1.0-alpha-3 4: 1.0-alpha-4 5: 1.0 6: 1.1 Choose a number: 6:
按下 Enter 选择默认选项 (6:maven-archetype-quickstart:1.1)
Maven 将询问工程细节。按要求输入工程细节。若是要使用默认值则直接按 Enter 键。你也能够输入本身的值。
Define value for property 'groupId': : com.companyname.insurance Define value for property 'artifactId': : health Define value for property 'version': 1.0-SNAPSHOT: Define value for property 'package': com.companyname.insurance:
Maven 将要求确认工程细节。按 enter 或按 Y
Confirm properties configuration: groupId: com.companyname.insurance artifactId: health version: 1.0-SNAPSHOT package: com.companyname.insurance Y:
如今 Maven 将开始建立工程结构,显示以下:
[INFO] ----------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.1 [INFO] ----------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.companyname.insurance [INFO] Parameter: packageName, Value: com.companyname.insurance [INFO] Parameter: package, Value: com.companyname.insurance [INFO] Parameter: artifactId, Value: health [INFO] Parameter: basedir, Value: C:\MVN [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: C:\MVN\health [INFO] ----------------------------------------------------------------------- [INFO] BUILD SUCCESSFUL [INFO] ----------------------------------------------------------------------- [INFO] Total time: 4 minutes 12 seconds [INFO] Finished at: Fri Jul 13 11:10:12 IST 2012 [INFO] Final Memory: 20M/90M [INFO] -----------------------------------------------------------------------
如今转到 C:\ > MVN 目录。你会看到一个名为 health 的 java 应用程序项目,就像在项目建立的时候创建的 artifactId 名称同样。 Maven 将建立一个有标准目录布局的工程,以下所示:
Maven 为工程生成一个 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.insurance</groupId> <artifactId>health</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>health</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
Maven 生成一个 java 源文件示例,工程的 App.java 以下所示:
路径:C:\ > MVN > health > src > main > java > com > companyname > insurance > App.java
package com.companyname.insurance; /** * Hello world! * */ public class App { public static void main( String[] args ) { System.out.println( "Hello World!" ); } }
Maven 生成一个 java 源文件示例,工程的 AppTest.java 以下所示:
路径为: C:\ > MVN > health > src > test > java > com > companyname > insurance > AppTest.java
package com.companyname.insurance; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Unit test for simple App. */ public class AppTest extends TestCase { /** * Create the test case * * @param testName name of the test case */ public AppTest( String testName ) { super( testName ); } /** * @return the suite of tests being tested */ public static Test suite() { return new TestSuite( AppTest.class ); } /** * Rigourous Test :-) */ public void testApp() { assertTrue( true ); } }
就这样。如今你能够看到 Maven 的强大之处。你能够用 maven 简单的命令建立任何类型的工程,而且能够启动您的开发。
大型软件应用程序一般由多个模块组成,这是多个团队工做于同一应用程序的不一样模块的常见场景。例如一个团队工做负责应用程序的前端应用用户接口工程(app-ui.jar:1.0)),同时他们使用数据服务工程(data-service.jar:1.0)。
如今负责数据服务的团队可能正在进行修正 bug 或者加强功能,并快速迭代,而后他们几乎天天都会 release 工程库文件到远程仓库中。
如今若是数据服务团队天天上传新的版本,那么就会有下面的问题:
为了解决这样的状况,快照概念发挥了做用.
快照是一个特殊的版本,它表示当前开发的一个副本。与常规版本不一样,Maven 为每一次构建从远程仓库中检出一份新的快照版本。
如今数据服务团队会将每次更新的代码的快照(例如 data-service:1.0-SNAPSHOT)发布到仓库中,来替换旧的快照 jar 文件。
对于版本,Maven 一旦下载了指定的版本(例如 data-service:1.0),它将不会尝试从仓库里再次下载一个新的 1.0 版本。想要下载新的代码,数据服务版本须要被升级到 1.1。
对于快照,每次用户接口团队构建他们的项目时,Maven 将自动获取最新的快照(data-service:1.0-SNAPSHOT)。
应用用户接口工程正在使用 1.0 版本的数据服务的快照
<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> <groupId>app-ui</groupId> <artifactId>app-ui</artifactId> <version>1.0</version> <packaging>jar</packaging> <name>health</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>data-service</groupId> <artifactId>data-service</artifactId> <version>1.0-SNAPSHOT</version> <scope>test</scope> </dependency> </dependencies> </project>
数据服务工程为每一个微小的变化 release 1.0 快照
<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> <groupId>data-service</groupId> <artifactId>data-service</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>health</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
虽然,对于快照,Maven 每次自动获取最新的快照,但你能够在任何 maven 命令中使用 -U 参数强制 maven 下载最新的快照。
mvn clean package -U
让咱们打开命令控制台,进入 C:\ > MVN > app-ui 目录并执行如下 mvn 命令。
C:\MVN\app-ui>mvn clean package -U
Maven将在下载数据服务的最新快照后,开始构建工程。
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------- [INFO] Building consumerBanking [INFO] task-segment: [clean, package] [INFO] ------------------------------------------------------------------- [INFO] Downloading data-service:1.0-SNAPSHOT [INFO] 290K downloaded. [INFO] [clean:clean {execution: default-clean}] [INFO] Deleting directory C:\MVN\app-ui\target [INFO] [resources:resources {execution: default-resources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MVN\app-ui\src\main\ resources [INFO] [compiler:compile {execution: default-compile}] [INFO] Compiling 1 source file to C:\MVN\app-ui\target\classes [INFO] [resources:testResources {execution: default-testResources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MVN\app-ui\src\test\ resources [INFO] [compiler:testCompile {execution: default-testCompile}] [INFO] Compiling 1 source file to C:\MVN\app-ui\target\test-classes [INFO] [surefire:test {execution: default-test}] [INFO] Surefire report directory: C:\MVN\app-ui\target\ surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.companyname.bank.AppTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.027 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [jar:jar {execution: default-jar}] [INFO] Building jar: C:\MVN\app-ui\target\ app-ui-1.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2 seconds [INFO] Finished at: Tue Jul 10 16:52:18 IST 2012 [INFO] Final Memory: 16M/89M [INFO] ------------------------------------------------------------------------
构建自动化定义为一种场景:一旦该工程成功构建完成,其相关的依赖工程即开始构建,目的是为了保证其依赖项目的稳定。
考虑一个团队正在开发一个关于总线核心 Api(称其为 bus-core-api)的工程,依赖它的工程有 2 个,分别为网页 UI(称其为 app-web-ui)和应用程序桌面 UI(称其为 app-desktop-ui)。
app-web-ui 工程使用 1.0-SNAPSHOT 总线核心 Api 工程,其 POM 文件以下:
<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> <groupId>app-web-ui</groupId> <artifactId>app-web-ui</artifactId> <version>1.0</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
app-desktop-ui 工程也正在使用 1.0-SNAPSHOT 总线核心 Api 工程,其 POM 文件以下:
<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> <groupId>app-desktop-ui</groupId> <artifactId>app-desktop-ui</artifactId> <version>1.0</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
bus-core-api 工程的 POM 文件以下:
<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> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> </project>
如今,app-web-ui 和 app-desktop-ui 工程的团队须要保证当 bus-core-api 工程有变化时他们本身相应的工程能够随时被构建。
使用快照能够保证最新的 bus-core-api 工程能够被使用,可是为了达到上述的需求,咱们仍需作一些额外的工做。
咱们有 2 种方式:
更新 bus-core-api 工程的 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <build> <plugins> <plugin> <artifactId>maven-invoker-plugin</artifactId> <version>1.6</version> <configuration> <debug>true</debug> <pomIncludes> <pomInclude>app-web-ui/pom.xml</pomInclude> <pomInclude>app-desktop-ui/pom.xml</pomInclude> </pomIncludes> </configuration> <executions> <execution> <id>build</id> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> </plugins> <build> </project>
打开命令终端,进入到 C:\ > MVN > bus-core-api 的目录下,而后执行以下的 mvn 的命令。
C:\MVN\bus-core-api>mvn clean package -U
Maven 将会开始构建 bus-core-api 工程,输出日志以下:
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------ [INFO] Building bus-core-api [INFO] task-segment: [clean, package] [INFO] ------------------------------------------------------------------ ... [INFO] [jar:jar {execution: default-jar}] [INFO] Building jar: C:\MVN\bus-core-ui\target\ bus-core-ui-1.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------
一旦 bus-core-api 构建成功,Maven 将会自动开始构建 app-web-ui 项目, 日志以下:
[INFO] ------------------------------------------------------------------ [INFO] Building app-web-ui [INFO] task-segment: [package] [INFO] ------------------------------------------------------------------ ... [INFO] [jar:jar {execution: default-jar}] [INFO] Building jar: C:\MVN\app-web-ui\target\ app-web-ui-1.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------
等到 app-web-ui 建立成功,Maven 接着开始构建 app-desktop-ui 工程,日志输出以下:
[INFO] ------------------------------------------------------------------ [INFO] Building app-desktop-ui [INFO] task-segment: [package] [INFO] ------------------------------------------------------------------ ... [INFO] [jar:jar {execution: default-jar}] [INFO] Building jar: C:\MVN\app-desktop-ui\target\ app-desktop-ui-1.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------- [INFO] BUILD SUCCESSFUL [INFO] -------------------------------------------------------------------
因为开发人员不须要每次多一个新的依赖工程时都去更新 bus-core-api 工程的 pom 文件, 所以使用一个持续集成的服务器更加合适,例如,添加一个新的 app-mobile-ui 的工程,它一样依赖于 bus-core-ui 工程。Hudson 将会借助 Maven 的依赖管理功能实现工程的自动化建立。
Hunson 把每次建立工程看作一个工做。一旦工程代码合入到 svn 或者其余任何的映射到Hudson上的代码源管理工具上,Hunson 便开始一次的建立工做,等到该工做完成后,它将会自动建立其余相关的依赖工做或者依赖工程。
在上面的例子中,当 bus-core-api 的源代码在 SVN 上有更新时, Hudson 将会启动建立。当建立完成后,Hudson 开始自动寻找其依赖的工程,而后启动 app-web-ui 和 app-desktop-ui 工程。
Maven 核心特色之一是依赖管理。一旦咱们开始处理多模块工程(包含数百个子模块或者子工程)的时候,模块间的依赖关系就变得很是复杂,管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法。
这种情形常常可见,当一个库 A 依赖于其余库 B. 另外一工程 C 想要使用库 A, 那么该工程一样也须要使用到库 B。
Maven 能够避免去搜索全部须要的库资源的这种需求。经过读取工程文件(pom.xml)中的依赖项,Maven 能够找出工程之间的依赖关系。
咱们只须要在每一个工程的 pom 文件里去定义直接的依赖关系。Maven 则会自动的来接管后续的工做。
经过传递依赖,全部被包含的库的图形可能会快速的增加。当重复的库存在时,可能出现的情形将会持续上升。Maven 提供一些功能来控制可传递的依赖的程度。
功能
|
功能描述
|
---|---|
依赖调节 | 决定当多个手动建立的版本同时出现时,哪一个依赖版本将会被使用。 若是两个依赖版本在依赖树里的深度是同样的时候,第一个被声明的依赖将会被使用。 |
依赖管理 | 直接的指定手动建立的某个版本被使用。例如当一个工程 C 在本身的以来管理模块包含工程 B,即 B 依赖于 A, 那么 A 便可指定在 B 被引用时所使用的版本。 |
依赖范围 | 包含在构建过程每一个阶段的依赖。 |
依赖排除 | 任何可传递的依赖均可以经过 "exclusion" 元素被排除在外。举例说明,A 依赖 B, B 依赖 C,所以 A 能够标记 C 为 “被排除的”。 |
依赖可选 | 任何可传递的依赖能够被标记为可选的,经过使用 "optional" 元素。例如:A 依赖 B, B 依赖 C。所以,B 能够标记 C 为可选的, 这样 A 就能够再也不使用 C。 |
传递依赖发现能够经过使用以下的依赖范围来获得限制:
范围
|
描述
|
---|---|
编译阶段 | 该范围代表相关依赖是只在工程的类路径下有效。默认取值。 |
供应阶段 | 该范围代表相关依赖是由运行时的 JDK 或者 网络服务器提供的。 |
运行阶段 | 该范围代表相关依赖在编译阶段不是必须的,可是在执行阶段是必须的。 |
测试阶段 | 该范围代表相关依赖只在测试编译阶段和执行阶段。 |
系统阶段 | 该范围代表你须要提供一个系统路径。 |
导入阶段 | 该范围只在依赖是一个 pom 里定义的依赖时使用。同时,当前工程的POM 文件的部分定义的依赖关系能够取代某特定的 POM。 |
一般状况下,在一个共通的工程下,有一系列的工程。在这种状况下,咱们能够建立一个公共依赖的 pom 文件,该 pom 包含全部的公共的依赖关系,咱们称其为其余子工程 pom 的 pom 父。 接下来的一个例子能够帮助你更好的理解这个概念。
下面是上述依赖图表的细节:
App-UI-WAR 的 POM 文件以下:
<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> <groupId>com.companyname.groupname</groupId> <artifactId>App-UI-WAR</artifactId> <version>1.0</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>com.companyname.groupname</groupId> <artifactId>App-Core-lib</artifactId> <version>1.0</version> </dependency> </dependencies> <dependencies> <dependency> <groupId>com.companyname.groupname</groupId> <artifactId>App-Data-lib</artifactId> <version>1.0</version> </dependency> </dependencies> </project>
App-Core-lib 的 POM 文件以下:
<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"> <parent> <artifactId>Root</artifactId> <groupId>com.companyname.groupname</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.groupname</groupId> <artifactId>App-Core-lib</artifactId> <version>1.0</version> <packaging>jar</packaging> </project>
App-Data-lib 的 POM 文件以下:
<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"> <parent> <artifactId>Root</artifactId> <groupId>com.companyname.groupname</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.groupname</groupId> <artifactId>App-Data-lib</artifactId> <version>1.0</version> <packaging>jar</packaging> </project>
Root 的 POM 文件以下:
<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> <groupId>com.companyname.groupname</groupId> <artifactId>Root</artifactId> <version>1.0</version> <packaging>pom</packaging> <dependencies> <dependency> <groupId>com.companyname.groupname1</groupId> <artifactId>Lib1</artifactId> <version>1.0</version> </dependency> </dependencies> <dependencies> <dependency> <groupId>com.companyname.groupname2</groupId> <artifactId>Lib2</artifactId> <version>2.1</version> </dependency> </dependencies> <dependencies> <dependency> <groupId>com.companyname.groupname3</groupId> <artifactId>Lib3</artifactId> <version>1.1</version> </dependency> </dependencies> </project>
如今,当咱们构建 App-UI-WAR 工程时, Maven 将会经过遍历依赖图找到全部的依赖关系,而且构建该应用程序。
经过上面的例子,咱们能够学习到如下关键概念:
通常状况下,在一个工程开发进程里,一次部署的过程包含需以下步骤:
一般,将会有不少不一样的人参与到上述部署过程当中。一个团队能够负责代码的合入工做,另一个能够负责构建,以此类推。上述的任何一个步骤均可能由于人为的缘由没有被执行。例如,较旧的版本没有在网络机器上更新,负责部署的团队再一次部署了旧的版本。
经过结合以下的方案来实现自动化部署:
咱们将会使用 Maven 发布的插件来建立一个自动化发布过程:
例如: bus-core-api 工程的 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <scm> <url>http://www.svn.com</url> <connection>scm:svn:http://localhost:8080/svn/jrepo/trunk/ Framework</connection> <developerConnection>scm:svn:${username}/${password}@localhost:8080: common_core_api:1101:code</developerConnection> </scm> <distributionManagement> <repository> <id>Core-API-Java-Release</id> <name>Release repository</name> <url>http://localhost:8081/nexus/content/repositories/ Core-Api-Release</url> </repository> </distributionManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>2.0-beta-9</version> <configuration> <useReleaseProfile>false</useReleaseProfile> <goals>deploy</goals> <scmCommentPrefix>[bus-core-api-release-checkin]-< /scmCommentPrefix> </configuration> </plugin> </plugins> </build> </project>
在 pom.xml 里,咱们经常会使用到的重要元素以下表:
元素
|
描述
|
---|---|
SCM | 配置 SVN 的路径,Maven 将从该路径下将代码取下来。 |
仓库 | 成功构建出来的 WAR/EAR/JAR 或者其余的构建结果存放的路径。 |
插件 | maven-release-plugin 用以自动化部署的过程。 |
Maven 经过 maven-release-plugin 来执行以下颇有用的任务:
mvn release:clean
清理工做空间,保证最新的发布进程成功进行。
mvn release:rollback
回滚修改的工做空间代码和配置保证发布过程成功进行。
mvn release:prepare
执行以下屡次操做:
mvn release:perform
将代码切换到以前作标记的地方,运行 Maven 部署目标来部署 WAR 文件或者构建相应的结构到仓库里。
打开命令终端,进入到 C:\ > MVN >bus-core-api 目录下,而后执行以下的 mvn 命令。
C:\MVN\bus-core-api>mvn release:prepare
Maven 开始构建整个工程。一旦构建成功便可运行以下 mvn 命令。
C:\MVN\bus-core-api>mvn release:perform
一旦构建成功,你能够验证在你仓库下上传的 JAR 文件是否生效。
本教程将指导你如何使用 Maven 版本控制系统来管理一个基于 Web 的工程。在此,你将学习到如何建立/构建/部署以及运行 Web 应用程序:
创建一个简单的 Java web 应用,咱们可使用 maven-archetype-webapp 插件。首先咱们打开命令控制台,进入 C:\MVN 目录而且执行如下的 mvn 命令。
C:\MVN>mvn archetype:generate -DgroupId=com.companyname.automobile -DartifactId=trucks -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
Maven 将开始处理而且将建立完整的基于 Web 的 java 应用工程结构。
[INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'archetype'. [INFO] ------------------------------------------------------------------- [INFO] Building Maven Default Project [INFO] task-segment: [archetype:generate] (aggregator-style) [INFO] ------------------------------------------------------------------- [INFO] Preparing archetype:generate [INFO] No goals needed for project - skipping [INFO] [archetype:generate {execution: default-cli}] [INFO] Generating project in Batch mode [INFO] -------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0 [INFO] -------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.companyname.automobile [INFO] Parameter: packageName, Value: com.companyname.automobile [INFO] Parameter: package, Value: com.companyname.automobile [INFO] Parameter: artifactId, Value: trucks [INFO] Parameter: basedir, Value: C:\MVN [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: C:\MVN\trucks [INFO] ------------------------------------------------------------------- [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------- [INFO] Total time: 16 seconds [INFO] Finished at: Tue Jul 17 11:00:00 IST 2012 [INFO] Final Memory: 20M/89M [INFO] -------------------------------------------------------------------
如今进入 C:/MVN 目录,你将看到一个名为 trucks(由 artifactld 指定)的 java 应用工程。
Maven 使用一个标准的目录架构,如上示例,咱们能够理解如下的关键概念:
文件夹结构
|
描述
|
---|---|
trucks | 包含 src 文件夹和 pom.xml |
src/main/webapp | 包含 index.jsp 和 WEB-INF 文件夹. |
src/main/webapp/WEB-INF | 包含 web.xml |
src/main/resources | 包含 images / properties 文件。 |
<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.companyname.automobile</groupId> <artifactId>trucks</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>trucks 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>trucks</finalName> </build> </project>
若是仔细观察,Maven 还建立了一个示例 JSP 的源文件。
打开 C:\ > MVN > trucks > src > main > webapp > 文件夹, 你将看到 index.jsp.
<html> <body> <h2>Hello World!</h2> </body> </html>
打开终端,进入 C:\MVN\trucks 目录,而后执行以下 mvn 命令.
C:\MVN\trucks>mvn clean package
Maven 将会开始构建此工程,日志输出以下:
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------- [INFO] Building trucks Maven Webapp [INFO] task-segment: [clean, package] [INFO] ------------------------------------------------------------------- [INFO] [clean:clean {execution: default-clean}] [INFO] [resources:resources {execution: default-resources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources,i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [compiler:compile {execution: default-compile}] [INFO] No sources to compile [INFO] [resources:testResources {execution: default-testResources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources,i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MVN\trucks\src\test\resources [INFO] [compiler:testCompile {execution: default-testCompile}] [INFO] No sources to compile [INFO] [surefire:test {execution: default-test}] [INFO] No tests to run. [INFO] [war:war {execution: default-war}] [INFO] Packaging webapp [INFO] Assembling webapp[trucks] in [C:\MVN\trucks\target\trucks] [INFO] Processing war project [INFO] Copying webapp resources[C:\MVN\trucks\src\main\webapp] [INFO] Webapp assembled in[77 msecs] [INFO] Building war: C:\MVN\trucks\target\trucks.war [INFO] ------------------------------------------------------------------- [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------- [INFO] Total time: 3 seconds [INFO] Finished at: Tue Jul 17 11:22:45 IST 2012 [INFO] Final Memory: 11M/85M [INFO] -------------------------------------------------------------------
如今拷贝在 C:\ > MVN > trucks > target > 文件夹下的 trucks.war 到你的 web 服务器的 webapp 目录下,而且重启 web 服务。
使用 URL: http://\<server-name>:\<port-number>/trucks/index.jsp 来运行你的 Web 应用。
验证输出结果: