maven3实战之maven使用入门

编写POM

maven项目的核心是pom.xml。POM(Project ObjectModel,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。如例,新建一个名为pom.xml的文件:

 

Xml代码  

1. <?xml version="1.0" encoding="UTF-8"?>  

2. <project xmlns="http://maven.apache.org/POM/4.0.0"  

3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

4.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  

5.     <modelVersion>4.0.0</modelVersion>  

6.     <groupId>com.juvenxu.mvnbook</groupId>  

7.     <artifactId>hello-world</artifactId>  

8.     <version>1.0-SNAPSHOT</version>  

9.     <name>Maven hello world Project</name>  

10.  

11.</project>  

 

代码的第一行是xml头,指定了该xml文档的版本和编码方式。紧接着是project元素,project是所有pom.xml的根元素,它还声明了一些POM相关的命名空间及xsd元素,虽然这些属性不是必须的,但使用这些属性能够让第三方工具(如:IDE中的xml编辑器)帮助我们快速编辑POM。

根元素下的第一个子元素modelVersion指定了当前POM模型的版本,对于maven2及maven3来说,它只能是4.0.0。

这段代码中最重要的是包含groupId,artifactId和version的三行。这三个元素定义了一个项目基本的坐标,在maven的世界,任何的jar,pom或者war都是以基于这些基本的坐标进行区分的。

groupId定义了项目属于哪个组,这个组往往和项目所在的组织或公司存在关联。譬如在googlecode上建立了一个名为myapp的项目,那么groupId就应该是com.googlecode.myapp,如果你的公司是mycom,有一个项目为myapp,那么groupId应该是com.mycom.myapp。

artifactId定义了当前maven项目在组中唯一的ID,如在前面的groupId为com.googlecode.myapp的例子中,你可能会为不同的子项目(模块)分配artifactId,如:myapp-util,myapp-domain,myapp-web等。

顾名思义,version指定了项目当前的版本--1.0-SNAPSHOT。SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本。随着项目的发展,version会不断更新,如升级为1.0,1.1-SNAPSHOT,1.1,2.0等。

最后一个name元素声明了一个对于用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个pom声明name,以方便信息交流。 

编写主代码

项目主代码和测试代码不同,项目主代码会被打包到最终的构件中(如:jar,war),而测试代码只在运行测试时用到,不会被打包。默认情况下,maven假设项目主代码位于src/main/java目录。

关于java代码有两点需要注意:首先,在绝大多数情况下,应该把项目主代码放到src/main/java/目录下(遵循maven的约定),而无须额外的配置,maven会自动搜寻该目录找到项目主代码。其次,一般来说,项目中java类的包都应该基于项目的groupId和artifactId,如包名:com.juvenxu.mvnbook.helloworld,这与groupId是com.juvenxu.mvnbook,artifactId是helloworld相一致。这样更加清晰,更加符合逻辑,也方便搜索构件或者java类。

 

代码编写完毕后,使用maven进行编译,在项目根目录下运行命令: mvn clean compile

clean告诉maven清理输出目录target/,compile告诉maven编译项目主代码,从输出中看到maven首先执行clean:clean任务,删除target/目录。默认情况下,maven构建的所有输出都在target/目录中;接着执行 resources:resources任务(未定义项目资源,暂且略过);最后执行compiler:compile任务,将项目主代码编译至target/classes目录。

编写测试代码

为了使项目结构保持清晰,主代码与测试代码应该分别位于独立的目录中,maven项目中默认的主代码目录是:src/main/java,对应地,maven项目中默认的测试代码目录是:src/test/java。因此,在编写测试用例之前,应当先创建该目录。

在java世界中,由kent beck和erich gamma建立的Junit是事实上的单元测试标准。要使用JUnit,首先需要为项目添加一个JUnit依赖。如例:

 

Xml代码  

1. <?xml version="1.0" encoding="UTF-8"?>  

2. <project xmlns="http://maven.apache.org/POM/4.0.0"  

3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

4.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  

5.     <modelVersion>4.0.0</modelVersion>  

6.     <groupId>com.juvenxu.mvnbook</groupId>  

7.     <artifactId>hello-world</artifactId>  

8.     <version>1.0-SNAPSHOT</version>  

9.     <name>Maven hello world Project</name>  

10.  

11.    <dependencies>  

12.        <dependency>  

13.            <groupId>junit</groupId>  

14.            <artifactId>junit</artifactId>  

15.            <version>4.7</version>  

16.            <scope>test</scope>  

17.        </dependency>  

18.    </dependencies>  

19.      

20.</project>  

 

代码中添加了dependencies元素,该元素下可以包含多个dependency元素以声明项目的依赖。这里添加了一个依赖---groupId是junit,artifactId是junit,version是4.7。前面提到groupId,artifactId和version是任何一个Maven项目最基本的坐标,JUnit也不例外,有了这段声明,maven就能够自动下载junit-4.7.jar。也许你会问,maven从哪里下载这个jar呢?在maven之前,可以去JUnit的官方网站下载分发包,有了maven,它会自动访问中央仓库(http://repo1.maven.org/maven2/),下载需要的文件。

上述POM代码中还有一个值为test的元素scope,scope为依赖范围,若依赖范围为test则表示该依赖只对测试有效。换句话说,测试代码中的import JUnit代码是没有问题的,但是如果在主代码中用import JUnit代码,就会造成编译错误。如果不声明依赖范围,那么默认值就是compile,表示该依赖对主代码和测试代码都有效。

 

配置了测试依赖,接着就可以编写测试类。测试用例编写完毕之后就可以调用maven执行测试。运行:mvn clean test

 

注意:

由于历史原因,maven的核心插件之一---compile插件默认只支持编译java1.3,如果我们在主代码或测试代码中使用了java5或java6的语法,程序就会编译出错,这个时候我们应该显示地声明插件并注明使用java的版本,如: 

 

Xml代码  

1. <project>  

2.     ...  

3.     <build>  

4.         <plugins>  

5.             <plugin>  

6.                 <groupId>org.apache.maven.plugins</groupId>  

7.                 <artifactId>maven-compiler-plugin</artifactId>  

8.                 <configuration>  

9.                     <source>1.5</source>  

10.                    <target>1.5</target>  

11.                </configuration>  

12.            </plugin>  

13.        </plugins>  

14.    </build>  

15.    ...  

16.</project>  

打包和运行

将项目进行编译,测试之后,下一个重要步骤就是打包。pom.xml中如果没有指定打包类型,默认打包类型为:jar。我们可以简单地执行命令打包: mvn clean pachage

类似地,maven会在打包之前执行编译,测试等操作。如以打jar包为例,jar:jar任务负责打包,实际上就是jar插件的jar目标将项目主代码打包成一个名为xxxxxx-1.0-SNAPSHOT.jar的文件。该文件也位于target/输出目录中,它是根据artifact-version.jar的规则进行命名的,如有需要,还可以使用finalName来自定义该文件的名称,这里暂且不展开,后面会详细解释。

在打包之后,又执行了安装任务install:install。从输出可以看到任务将项目输出的jar安装到了maven本地仓库中,可以打开相应的文件夹看到项目的pom和jar。之前我们说只有构件被下载到本地仓库后,才能由所有Maven项目使用,这里同样的道理,只有将自己编写的项目安装到本地仓库之后,其他maven项目才能使用它。

我们已经体验了maven最主要的命令:mvn clean compilemvn clean testmvn clean packagemvn clean install。执行test之前是会先执行compile的,执行package之前是会先执行test的,而类似地,install之前会执行package。可以在任何一个maven项目中执行这些命令。

默认打包是生成jar的,如果我的项目还有main方法的,我想打包成可执行的jar包,为了生成可执行的jar文件,需要借助maven-shade-plugin,配置该插件如下:

 

 

Xml代码  

1. <plugin>  

2.     <groupId>org.apache.maven.plugins</groupId>  

3.     <artifactId>maven-shade-plugin</artifactId>  

4.     <version>1.2.1</version>  

5.     <executions>  

6.         <execution>  

7.             <phase>package</phase>  

8.             <goals>  

9.                 <goal>shade</goal>  

10.            </goals>  

11.            <configuration>  

12.                <transformers>  

13.                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  

14.                        <mainClass>com.juvenxu.mvnbook.helloworld.HelloWorld</mainClass>  

15.                    </transformer>  

16.                </transformers>  

17.            </configuration>  

18.        </execution>  

19.    </executions>  

20.</plugin>  

 

 

默认打包生成jar是不能够直接运行的,因为带有main方法的类信息不会添加到manifest中(打开jar文件中的META-INF/MANIFEST.MF文件,将无法看到Main-Class一行)。

plugin元素在POM中的相对位置应该在<project><build><plugins>下面。我们配置了mainClass为com.juvenxu.mvnbook.helloworld.HelloWorld,项目在打包时会将该信息放到MANIFEST中。现在执行mvn clean install,待构建完成之后打开target/目录,可以看到hello-world-1.0-SNAPSHOT.jar和original-hello-world-1.0-SNAPSHOT.jar,前者是带有Main-Class信息的可执行jar,后者是原始的jar,打开hello-world-1.0-SNAPSHOT.jar的META-INF/MANIFEST.MF,可以看到它包含这样一行信息:

Main-Class:com.juvenxu.mvnbook.helloworld.HelloWorld

现在,在项目根目录中执行该jar文件:

D:\code\hello-world> java-jartarget\hello-world-1.0-SNAPSHOT.jar,可以得到正确的输出了。

使用archetype生成项目骨架

maven提供了archetype以帮助我们快速勾勒出项目骨架。以Hello World为例,我们使用maven archetype来创建该项目的骨架。

 

如果是maven3,简单地运行:

mvn archetype:generate

如果是maven2,最好运行如下命令:

mvnorg.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate

 

很多资料会让你直接使用更为简单的mvn archetype:generate命令,但在maven2中这是不安全的,因为该命令没有指定archetype插件的版本,于是maven会自动去下载最新的版本,进而可能得到不稳定的SNAPSHOT版本,导致运行失败。然而maven3中,即使用户没有指定版本,maven也只会解析最新的稳定版本,因此这是安全的。

我们实际上是在运行插件maven-archetype-plugin,注意冒号的分隔,其格式为groupId:artifactId:version:goal,org.apache.maven.plugins是maven官方插件的groupId,maven-archetype-plugin是archetype插件的artifactId,2.0-alpha-5是目前该插件最新的稳定版本,generate是要使用的插件目标。

紧接着会看到一段长长的输出,有很多可用的archetype供选择,每一个archetype前面都会对应有一个编号,同时命令行会提示一个默认的编号,其对应的archetype为maven-archetype-quickstart,直接回车以选择该archetype,紧接着maven会提示输入要创建项目的groupId,artifactId,version以及包名package。

 

最后说明:我们也可以开发自己的archetype,这在后面再讲述

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值