Maven实战(四)生命周期

Posted on

Maven实战(四)生命周期

1. 三套生命周期 Maven拥有三套相互独立的生命周期,它们分别为clean,default和site。 每个生命周期包含一些阶段,这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和Maven最直接的交互方式就是调用这些生命周期阶段。 以clean生命周期为例,它包含的阶段有pre-clean, clean 和 post clean。当用户调用pre-clean的时候,只有pre-clean得以执行,当用户调用clean的时候,pre-clean和clean阶段会得以顺序执行;当用户调用post-clean的时候,pre-clean,clean,post-clean会得以顺序执行。 较之于生命周期阶段的前后依赖关系,三套生命周期本身是相互独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default生命周期的某个阶段,而不会对其他生命周期产生任何影响。 2. clean 生命周期

  clean生命周期的目的是清理项目,它包含三个阶段:

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

 2)**clean** 清理上一次构建生成的文件。

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

3. default 生命周期

   default生命周期定义了真正构件时所需要执行的所有步骤,它是生命周期中最核心的部分,它包含的阶段如下:

   1) validate 验证项目是否正确和所有需要的相关资源是否可用

   2) initialize 初始化构建

   3) generate-sources

   4)   process-sources 处理源代码

   5) generate-resources 

   6)   process-resources 处理项目主资源文件。对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中。

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

   8) process-classes

   9)   generate-test-sources

   10) process-test-sources 处理项目测试资源文件

   11)generate-test-resources

   12)  process-test-resources 处理测试的资源文件

   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项目使用

4. site 生命周期

  site生命周期的目的是建立和发布项目站点,Maven能够基于POM所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息。该生命周期包含如下阶段:

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

  2)site 生成项目站点文档

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

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

来源: [http://tangyanbo.iteye.com/blog/1503890](http://tangyanbo.iteye.com/blog/1503890)

Maven实战(六)依赖

Posted on

Maven实战(六)依赖

我们项目中用到的jar包可以通过依赖的方式引入,构建项目的时候从Maven仓库下载即可。


1. 依赖配置 依赖可以声明如下:

Xml代码 收藏代码

  1. ...
  2. group-a
  3. artifact-a
  4. 1.0
  5. group-c
  6. excluded-artifact
  7. group-a
  8. artifact-b
  9. 1.0
  10. bar
  11. runtime
  12. 我们在Maven实战(二)中就遇到了依赖的概念,项目中测试需要依赖junit jar包,依赖配置如下:

Xml代码 收藏代码

  1. junit
  2. junit
  3. 3.8.1
  4. test
  5. 依赖会包含基本的groupId, artifactId,version等元素,根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或者多个依赖。 下面详细讲解每个依赖可以包含的元素:

groupId,artifactIdversion:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖

type: 依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值是jar

scope: 依赖的范围,下面会进行详解

optional: 标记依赖是否可选

exclusions: 用来排除传递性依赖,下面会进行详解

大部分依赖声明只包含基本坐标。

2. 依赖范围

Maven在编译主代码的时候需要使用一套classpath,在编译和执行测试的时候会使用另一套classpath,实际运行项目的时候,又会使用一套classpath。

依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系,Maven有以下几种依赖范围:

compile: 编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效。

test: 测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子就是JUnit,它只有在编译测试代码及运行测试的时候才需要。

provided: 已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复地引入一遍。

runtime: 运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。

system: 系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量,如: Xml代码 收藏代码

  1. javax.sql
  2. jdbc-stdext
  3. 2.0
  4. ${java.home}/lib/rt.jar

import(Maven 2.0.9及以上): 导入依赖范围。该依赖范围不会对三种classpath产生实际的影响,稍后会介绍到。

3. 传递性依赖

下面我们看一个简单的项目,读者可从附件中下载源码

POM.xml配置如下: Xml代码 收藏代码

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. 4.0.0
  4. com.mycompany.app
  5. my-app-simple
  6. 0.0.1-SNAPSHOT
  7. jar
  8. my-app-simple
  9. http://maven.apache.org
  10. UTF-8
  11. junit
  12. junit
  13. 3.8.1
  14. test
  15. org.springframework
  16. spring-core
  17. 2.5.6
  18. 我们可以看到此项目引入依赖junit和spring-core,我们可以在Maven仓库中查找spring-core构件,如图:

点击POM我们会看到该文件包含了一个commons-logging依赖: Xml代码 收藏代码

  1. commons-logging
  2. commons-logging
  3. 1.1.1

那么该依赖会传递到当前项目中,这就是依赖的传递性,打开项目查看Maven dependencies:

4. 可选依赖

有时候我们不想让依赖传递,那么可配置该依赖为可选依赖,将元素optional设置为true即可,例如: Xml代码 收藏代码

  1. commons-logging
  2. commons-logging
  3. 1.1.1
  4. true

那么依赖该项目的另以项目将不会得到此依赖的传递

5. 排除依赖



   当我们引入第三方jar包的时候,难免会引入传递性依赖,有些时候这是好事,然而有些时候我们不需要其中的一些传递性依赖

比如上例中的项目,我们不想引入传递性依赖commons-logging,我们可以使用exclusions元素声明排除依赖,exclusions可以包含一个或者多个exclusion子元素,因此可以排除一个或者多个传递性依赖。需要注意的是,声明exclusions的时候只需要groupId和artifactId,而不需要version元素,这是因为只需要groupId和artifactId就能唯一定位依赖图中的某个依赖。换句话说,Maven解析后的依赖中,不可能出现groupId和artifactId相同,但是version不同的两个依赖。

如下是一个排除依赖的例子: Xml代码 收藏代码

  1. org.springframework
  2. spring-core
  3. 2.5.6
  4. commons-logging
  5. commons-logging

5. 依赖归类

如果我们项目中用到很多关于Spring Framework的依赖,它们分别是org.springframework:spring-core:2.5.6, org.springframework:spring-beans:2.5.6,org.springframework:spring-context:2.5.6,它们都是来自同一项目的不同模块。因此,所有这些依赖的版本都是相同的,而且可以预见,如果将来需要升级Spring Framework,这些依赖的版本会一起升级。因此,我们应该在一个唯一的地方定义版本,并且在dependency声明引用这一版本,这一在Spring Framework升级的时候只需要修改一处即可。 Xml代码 收藏代码

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. 4.0.0
  4. com.mycompany.app
  5. my-app-simple
  6. 0.0.1-SNAPSHOT
  7. jar
  8. my-app-simple
  9. 2.5.6
  10. junit
  11. junit
  12. 3.8.1
  13. test
  14. org.springframework
  15. spring-core
  16. ${springframework.version}
  17. org.springframework
  18. spring-beans
  19. ${springframework.version}

6. 在Eclipse中管理依赖

安装好m2eclipse之后(第2课有详细讲解)就可以用eclipse来管理依赖。

如图,在该项目的pom.xml中点击Dependency Hierarchy可以看到依赖树:

点击Dependencies可以添加新的依赖,点击选择一个依赖,点击remove可以删除,点击Add可以新增一个依赖,如图:

如下图,搜素org.springframework(此处是从Maven中心仓库进行搜索),选择你想要的模块和版本,点击OK即可:

来源: [http://tangyanbo.iteye.com/blog/1503957](http://tangyanbo.iteye.com/blog/1503957)

Maven环境配置

Posted on

Maven环境配置

Maven 是基于Java 的工具,所以第一要求是JDK有安装在你的机器上。

系统要求

JDK1.5 or above.Memoryno minimum requirement.Disk Spaceno minimum requirement.Operating Systemno minimum requirement.

Step 1 - 验证Java已经在你的机器上安装

现在,打开控制台,然后执行下面的java命令。 OSTaskCommandWindowsOpen Command Consolec:> java -versionLinuxOpen Command Terminal$ java -versionMacOpen Terminalmachine:~ joseph$ java -version

让我们来验证所有操作系统的输出:

OSOutputWindowsjava version "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b07) Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)Linuxjava version "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b07) Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)Macjava version "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b07) Java HotSpot(TM)64-Bit Server VM (build 17.0-b17, mixed mode, sharing)

如果没有安装Java,安装Java软件开发工具包(SDK)http://www.oracle.com/technetwork/java/javase/downloads/index.htmll。我们假设在本教程中安装的版本Java1.6.0_21。

Step 2: 设置Java环境

设置JAVA_HOME环境变量指向的基目录位置在您的机器上已安装Java。例如: OSOutputWindowsSet the environment variable JAVA_HOME to C:\Program Files\Java\jdk1.6.0_21Linuxexport JAVA_HOME=/usr/local/java-currentMacexport JAVA_HOME=/Library/Java/Home

添加到系统路径中的Java编译器的位置。

OSOutputWindowsAppend the string ;C:\Program Files\Java\jdk1.6.0_21\bin to the end of the system variable, Path.Linuxexport PATH=$PATH:$JAVA_HOME/bin/Macnot required

验证Java安装使用java-version命令解释上述。

Step 3: 下载Maven档案

http://maven.apache.org/download.htmll 下载Maven2.2.1 OSArchive nameWindowsapache-maven-2.0.11-bin.zipLinuxapache-maven-2.0.11-bin.tar.gzMacapache-maven-2.0.11-bin.tar.gz

Step 4: 提取Maven的存档

解压压缩包,希望安装Maven2.2.1的目录。从归档文件中将创建的子目录中的Apache Maven2.2.1。 OSLocation (can be different based on your installation)WindowsC:\Program Files\Apache Software Foundation\apache-maven-2.2.1Linux/usr/local/apache-mavenMac/usr/local/apache-maven

Step 5: 设置Maven的环境变量

添加 M2_HOME,M2,MAVEN_OPTS 环境变量。 OSOutputWindowsSet the environment variables using system properties.

M2_HOME=C:\Program Files\Apache Software Foundation\apache-maven-2.2.1

M2=%M2_HOME%\bin

MAVEN_OPTS=-Xms256m -Xmx512mLinuxOpen command terminal and set environment variables.

export M2_HOME=/usr/local/apache-maven/apache-maven-2.2.1

export M2=%M2_HOME%\bin

export MAVEN_OPTS=-Xms256m -Xmx512mMacOpen command terminal and set environment variables.

export M2_HOME=/usr/local/apache-maven/apache-maven-2.2.1

export M2=%M2_HOME%\bin

export MAVEN_OPTS=-Xms256m -Xmx512m

Step 6: Maven bin目录位置添加到系统路径

现在,附加M2变量系统路径 OSOutputWindowsAppend the string ;%M2% to the end of the system variable, Path.Linuxexport PATH=$M2:$PATHMacexport PATH=$M2:$PATH

Step 8: 验证Maven安装

现在打开控制台,执行以下mvn命令 OSTaskCommandWindowsOpen Command Consolec:> mvn --versionLinuxOpen Command Terminal$ mvn --versionMacOpen Terminalmachine:~ joseph$ mvn --version

最后,验证上述的命令的输出,这应该是如下的内容:

OSOutputWindowsApache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530) Java version: 1.6.0_21 Java home: C:\Program Files\Java\jdk1.6.0_21\jreLinuxApache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530) Java version: 1.6.0_21 Java home: C:\Program Files\Java\jdk1.6.0_21\jreMacApache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530) Java version: 1.6.0_21 Java home: C:\Program Files\Java\jdk1.6.0_21\jre 来源: [http://www.yiibai.com/maven/maven_environment_setup.html](http://www.yiibai.com/maven/maven_environment_setup.html)

Maven实战(一)安装与配置

Posted on

Maven实战(一)安装与配置

1. 简介 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. 如果你已经有十次输入同样的Ant targets来编译你的代码、jar或者war、生成javadocs,你一定会自问,是否有一个重复性更少却能同样完成该工作的方 法。 Maven便提供了这样一种选择,将你的注意力从作业层转移到项目管理层。Maven项目已经能够知道如何构建和捆绑代码,运行测试,生成文档并宿主项目网页 2.核心价值 /* 简单 Maven 暴露了一组一致、简介的操作接口,能帮助团队成员从原来的高度自定义的、复杂的构建系统中解脱出来,使用Maven现有的成熟的、稳定的组件也能简 化构建系统的复杂度。 /* 交流与反馈 与版本控制系统结合后,多有人都能执行最新的构建并快速得到反馈。此外,自动生成的项目报告也能帮助成员了解项目的状态,促进团队的交流。 /* 测试驱动开发 TDD强调测试先行,所有产品都应该由测试用例覆盖。而测试是maven生命周期的最重要组成部分之一,并且Maven有现成的成熟插件支持业界流行的测试框架,如Junit和TestNG。 /* 快速构建 只需要一些配置,之后用一条简单的命令就能让Maven帮你清理、编译、测试、打包、部署,然后得到最终产品。[/size] /* 持续集成 更加方便的持续集成 /* 富有信息的工作区 2.主要内容 我将会发表一系列课程来讲解Maven的应用,基于Maven3.0,主要内容如下: 1)安装和配置 2)Maven使用入门 3)坐标和依赖 4)Maven仓库 5) 生命周期和插件 6)聚合与继承 7)使用Nexus创建私服 8)使用Maven进行测试 9)m2eclipse的使用 10)自动部署maven项目 11)使用Hudson进行持续集成 3. 安装好JDK 以JDK1.5以上为例 4. Maven 的下载 下载地址:http://maven.apache.org/download.html 5.Maven安装 将下载到的文件解压到指定目录即可,如:C:\maven\apache-maven-3.0.4 6.环境变量的配置 在系统环境变量中新增如下环境变量 M2_HOME: Maven的安装目录,如:C:\maven\apache-maven-3.0.4 M2: %M2_HOME%\bin 并在path中添加%M2%,这样便可以在任何路径中执行mvn命令 7. 检测安装是否成功 Cmd窗口执行命令:mvn –v 得到如下图所示结果:

8.设置代理

有时候你所在的公司基于安全因素考虑,要求你使用通过安全认证的代理访问因特网。这时就需要为Maven配置HTTP代理。

在目录~/.m2/setting.xml文件中编辑如下(如果没有该文件,则复制$M2_HOME/conf/setting.xml): Xml代码 收藏代码

  1. optional
  2. true
  3. http
  4. proxyuser
  5. proxypass
  6. proxy.host.net
  7. 80
  8. local.net|some.host.com

来源: [http://tangyanbo.iteye.com/blog/1502578](http://tangyanbo.iteye.com/blog/1502578)

NOfM

Posted on

NOfM

[Algorithm Gossip: m元素集合的n个元素子集]

说明

假设有个集合拥有m个元素,任意的从集合中取出n个元素,则这n个元素所形成的可能子集有那些?

解法

假设有5个元素的集点,取出3个元素的可能子集如下: {1 2 3}、{1 2 4 }、{1 2 5}、{1 3 4}、{1 3 5}、{1 4 5}、{2 3 4}、{2 3 5}、{2 4 5}、{3 4 5} 这些子集已经使用字典顺序排列,如此才可以观察出一些规则:

  1. 如果最右一个元素小于m,则如同码表一样的不断加1
  2. 如果右边一位已至最大值,则加1的位置往左移
  3. 每次加1的位置往左移后,必须重新调整右边的元素为递减顺序 所以关键点就在于哪一个位置必须进行加1的动作,到底是最右一个位置要加1?还是其它的位置? 在实际撰写程式时,可以使用一个变数positon来记录加1的位置,position的初值设定为n-1,因为我们要使用阵列,而最右边的索引值为最大 的n-1,在position位置的值若小于m就不断加1,如果大于m了,position就减1,也就是往左移一个位置;由于位置左移后,右边的元素会 经过调整,所以我们必须检查最右边的元素是否小于m,如果是,则position调整回n-1,如果不是,则positon维持不变。

实作

  • C /#include /#include /#define MAX 20 int main(void) { int set[MAX]; int m, n, position; int i; printf("输入集合个数 m:"); scanf("%d", &m); printf("输入取出元素 n:"); scanf("%d", &n); for(i = 0; i < n; i++) set[i] = i + 1; // 显示第一个集合 for(i = 0; i < n; i++) printf("%d ", set[i]); putchar('\n'); position = n - 1; while(1) { if(set[n-1] == m) position--; else position = n - 1; set[position]++; // 调整右边元素 for(i = position + 1; i < n; i++) set[i] = set[i-1] + 1; for(i = 0; i < n; i++) printf("%d ", set[i]); putchar('\n'); if(set[0] >= m - n + 1) break; } return 0; }

  • Java public class NofM { private int m; private int[] set; private boolean first; private int position; public NofM(int n, int m) { this.m = m; first = true; position = n - 1; set = new int[n]; for(int i = 0; i < n; i++) set[i] = i + 1; } public boolean hasNext() { return set[0] < m - set.length + 1; } public int[] next() { if(first) { first = false; return set; } if(set[set.length-1] == m) position--; else position = set.length - 1; set[position]++; // 调整右边元素 for(int i = position + 1; i < set.length; i++) set[i] = set[i-1] + 1; return set; } public static void main(String[] args) { NofM nOfm = new NofM(3, 5); while(nOfm.hasNext()) { int[] set = nOfm.next(); for(int i = 0; i < set.length; i++) { System.out.print(set[i]); } System.out.println(); } } }