最近在做maven plugin自定义开发方面的研究,顺带把maven相对较系统的回顾了一遍,这个系列的笔记算是一些对maven2.0在软件开发各个生命周期中的使用小结吧。
所谓“万事开头难”,开发一个java
application一开始最难的部分就是开始,如此多的逻辑概念的堆积,java代码,资源文件,应用依赖.jar应该如何组织存放?unit
testing应该在什么时候执行?项目应该如何build?documented?tested?deployed?
很多工具可以提供项目的build,比如众所周知的ant。这边不做具体说明和对比,我只罗列出maven能给我们带来什么,官方网站给出的benefits list如下:
The benefits of Maven 2.0 are numerous, as it does more than merely build your projects. If you are just starting a new Java project
and you need to get started fast, Maven 2.0 will have you up an running in minutes.
The following are some of the advantages of Maven 2.0:
Standardized project layout and project structure generator.
Standardized dependency-management mechanism.
Multiple project support.
Instant downloads of new plugins and features as the developer needs them.
Website generation for up-to-date project information.
Integration with source control: CVS and Subversion.
maven带来了标准工程组织结构,标准工程发布管理机制,多重项目支持(模块化规划工程),插件的自主开发接口及可插拔安装,website生成及实时项目信息同步更新,通过与与svn或cvs的集成实现代码版本控制。下面开始介绍maven的使用介绍。
Getting Started:
假设现在开始一个java application的开发,我们可以应用maven来快速构建应用的程序结构,而不需要按以往的习惯在ide中手动进行层级创建,(maven的安装不做介绍)
在命令窗口输入命令:
1 mvn archetype:create -DgroupId=com.as -DartifactId=my-app
执行,你会发现maven已经为我们创建了名称为my-app的项目,其中项目结构如下:
1 my-app
2 |----src
3 |----main
4 |------java
5 |--------com
6 |----------as
7 |----test
8 |------java
9 |--------com
10 |----------as
这个结构包含了两个资源目录树:java application code和unit test code。在工程根目录下maven创建了pom.xml文件,是项目的最基本部分(the meat and potatoes )。
pom.xml是一系列的操作集合,用来告诉maven怎么build项目和引入项目build所需要的外部依赖及执行其他特殊操作。默认的,maven会加载junit依赖,来鼓励开发人员对程序代码测试实现。
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/maven-v4_0_0.xsd">
3
4 <modelVersion>4.0.0</modelVersion>
5 <groupId>com.as</groupId>
6 <artifactId>my-app</artifactId>
7 <packaging>jar</packaging>
8 <version>1.0-SNAPSHOT</version>
9 <name>Maven Quick Start Archetype</name>
10 <url>http://maven.apache.org</url>
11 <dependencies>
12 <dependency>
13 <groupId>junit</groupId>
14 <artifactId>junit</artifactId>
15 <version>3.8.1</version>
16 <scope>test</scope>
17 </dependency>
18 </dependencies>
19 </project>
之前的操作已经创建了一个新的项目,并按maven提供的标准程序结构组织各个层次的代码存放目录。还是在命令窗口,切入到工程目录,以下罗列出maven的基本操作命令及说明:
1 mvn test: 运行应用的所有单元测试。
2 mvn package: 创建打包应用的.jar文件.(pom.xml文件配置为packaging操作为jar操作)
3 mvn install: 安装工程生成jar文件到maven仓库,以提供其他应用依赖应用。
4 mvn site: 生成项目信息网站。
5 mvn clean: 清除应用编译存放目录。
6 mvn eclipse:eclipse: 将应用功能转化为eclipse可以直接导入的工程。
现在我们来创建一个基于java语言的web应用,在命令窗口输入:
1 mvn archetype:create -DgroupId=com.as -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp
生成的项目目录结构如下:
my-webapp
|----src
|------main
|----resources
|----webapp
|----WEB-INF
和之前创建的项目有所不同的是创建一些将被打包到war中的资源目录,并且pom.xml文件中,packaging操作被指定为war而不是之前的jar。而且我们不用去担心在打包成war的时候如何
将所有依赖拷贝到WEB-INF/lib目录下,maven会自动的处理这一切。另外,通过修改pom.xml中的build元素的finalName元素值,可以修改打包的war的名称。
Dependency Management :
之前的创建操作,让我们快速拥有了程序架构,那么回过头来关心下maven是如何来管理应用所用到的依赖。
应用添加一个依赖是通过在pom.xml中新增dependencies元素的子元素dependency来实现。maven在下次build的时候会读
取新增的dependency信息并从远程或本地仓库中下载并加载到工程的build path.比如我们要新增个依赖:quartz
,那么我们只需要在dependencies中增加如下格式的依赖定义:
1 <dependency>
2 <groupId>quartz</groupId>
3 <artifactId>quartz</artifactId>
4 <version>1.5.1</version>
5 <scope>compile</scope>
6 </dependency>
可以不用去关心quartz本身会再用到什么依赖,maven会自动把依赖所用的所有依赖都一起下载到你的本地仓库,并配置到你的工程build path。另外,在之前的junit依赖中,maven设置了
其scope为test,那么意味着,maven只会在test phase中加载junit这个依赖。下面罗列出依赖的scope在各个阶段的定义:
1 compile: 默认值,说明依赖资源必须存在于各个build阶段或任务。
2 test: 只在test阶段加载。
3 runtime: 依赖资源只在运行时加载。
4 provided: 依赖在运行时加载,但是不会出现在打出的包里。类似你要把某个依赖当作jdk的一个部分或者application server classpath.
Configuring Repositories:
项目中的每个开发人员各自定义项目依赖仓库,貌似不是很方便且有点繁琐,为此,maven提供了在同个pom.xml文件中同时定义多个依赖仓库的功能。在下面的pom.xml文件配置片段中,
设置了两个依赖仓库配置,默认的仓库依赖路径为Ibiblio,另外添加了个镜像仓库路径作为备选,比如设置为本地局域网内的某个服务器地址,详细配置如下:
<repositories>
<repository>
<id>Ibiblio</id>
<name>Ibiblio</name>
<url>http://www.ibiblio.org/maven/</url>
</repository>
<repository>
<id>intranet</id>
<name>intranet mirror</name>
<url>http://192.168.1.120/maven2</url>
</repository>
</repositories>
Building Multiple Projects using a Parent pom.xml:
当一个项目分成多个模块子项目进行开发规划的时候,maven提供了通过parent pom.xml文件来进行多样工程配置绑定。
maven的依赖检查机制将分析检查各个子项目所用到的依赖并按互相依赖的顺序build各个子项目。下面举个例子来说明:
parent pom.xml:
1 <project>
2 <modelVersion>4.0.0</modelVersion>
3 <groupId>com.as</groupId>
4 <version>1.0-SNAPSHOT</version>
5 <artifactId>my-app</artifactId>
6 <packaging>pom</packaging>
7 <modules>
8 <module>Common</module>
9 <module>Utilities</module>
10 <module>Application</module>
11 <module>WebApplication</module>
12 </modules>
13 </project>
在这里,假设WebApplication需要确定是否包含了其他三个子项目的所有依赖,所以,把其他三个子项目按依赖的形式进行配置到WebApplication中;并且Utilities依赖于Common,
Application依赖于Common,Utilities。即体现开发中遇到的各个子模块项目存在相互依赖的情况。接下来,对各个子项目的pom.xml进行配置如下:
Utilities:
<dependencies>
<dependency>
<groupId>com.as</groupId>
<artifactId>Common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
Application:
<dependencies>
<dependency>
<groupId>com.as</groupId>
<artifactId>Common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.as</groupId>
<artifactId>Utilities</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
WebApplication:
<dependencies>
<dependency>
<groupId>com.as</groupId>
<artifactId>Common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.as</groupId>
<artifactId>Utilities</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.as</groupId>
<artifactId>Application</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
这样,只需要在parent pom.xml中添加各个模块项目的配置,来说明它们是当前build的一部分。
<parent>
<groupId>com.as</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
Common, Utilities, Application, 和WebApplication目录于parent pom.xml文件存在于同个目录下。在parent pom.xml同级目录下执行maven package命令的时候,
各个子模块项目就会按顺序进行build任务了。
Plugins and Reports:
maven2.0提供了方便的plugin注册入口。有点遗憾的是,很多maven1.x 的plugin不能在maven2.0上运行,不过,现在maven2.0的plugin已经很丰富了,所以,这个问题也就不再是问题了。
下面是配置jdk 5的编译参数的plugin配置:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
另外一个使用比较频繁的maven plugin就是maven reporting plugin了,当执行mvn site命令时,这个plugin将发挥它的作用,配置使用如下:
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</plugin>
</plugins>
</reporting>
Maven Plugin Matrix(http://docs.codehaus.org/display/MAVEN/Maven+Plugin+Matrix) ,可以搜索到相关plugin可以在说明版本的maven上使用的详细信息。
Maven and Eclipse:
如果你按之前的说明操作,创建了一个新的项目,生成了项目的程序目录结构,你只要在项目的根目录路径下,在命令窗口中执行mvn
eclipse:eclipse,就能把当前项目转化为在eclipse
ide中可以import到workspace的项目了,这样,在eclipse ide中,就可以很方便的进行进一步的代码实现了。
Conclusion:
maven2.0提供了很多有用且高效的功能,特别是提供程序标准目录结构,这样,在开发的时候就不但可以很方便的把一个项目移动到另个项目,而且可以不用太关心程序目录结构和项目编译说明,maven已经提供了标准 :)
实际应用中,maven也提供了各种build system的自定义扩展,maven可以方便的进行 run
nightly,deploy,并分布发送通知信息,从文档方面来说,maven提供了实时的项目信息site生成,每次build完毕,配置自动进行
site信息和项目实际开发进程更新同步.
maven2.0带来的可升级的build配置,方面使用,项目管理,在今后,更多的maven给出的build技术方面的标准的采用,意味着更多的效率,更多的方便。
更详细的信息可以在maven的官方网站得到。
推荐学习maven的书籍: better builds with maven (虽然个人感觉文笔不怎么样,但是,算是市面上唯一比较全面的maven使用介绍比较全的书吧)
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明.