安装以后开始建立一个最简单的Hello World项目。 ###3.1 编写POM### 就像Make的Makefile,Ant的build.xml,Maven的核心是pom.xml。POM(Project Object Model,项目对象模型)定义了项目的对象信息,用于描述项目如何构建,声明项目依赖等等。 先为Hello World项目编写一个最简单的pom.xml。 首先建立一个名为hello-world的文件夹,打开文件夹,新建一个pom.xml文件,输入以下内容:java
<?xml version="1.0" encoding="UTF-8"?> <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.learn.mvn</groupId> <artifactId>hello-world</artifactId> <version>1.0-SNAPSHOT</version> <name>Maven Hello World Project</name> </project>
代码的第一行是XML头,指定了该xml文档的版本和编码方式。紧接着是project元素,project是全部pom.xml的根元素,它还声明了一些POM相关的命名空间及xsd元素,虽然这些属性不是必须的,但使用这些属性能让第三方工具能提供该xml的随笔功能。
modelVersion指定当前POM模型的版本,对于Maven2及Maven3来讲,它只能是4.0.0。
groupId、artifactId、version这三个元素定义了一个项目基本的坐标。groupId定义了项目属于哪一个组,这个组每每和项目所在的组织或公司有关联。譬如在googlecode上创建一个名为myphone的组,那么groupId就是com.googlecode.myphone。
artifactId定义了当前Maven项目在组中惟一的ID,一般状况下是一个项目或者子项目的名字。例如myphone组下有一个项目为google-phone,你可能会为不一样的子项目(模块)分配artifactId,如google-phone-util、google-phone-domain、google-phone-web。
version指定了项目当前的版本 1.0-SNAPSHOT,SNAPSHOT意为快照,说明还在开发中,是不稳定的版本。version会不断升级,如1.0、1.1-SNAPSHOT。 ###3.2 编写主代码### 项目主代码会被打包到最终的构件中(如jar),而测试代码只会在运行测试时用到。默认状况下,项目主代码位于src/main/java目录,建立在该目录下的好处是无须额外的配置,在之后使用的过程当中,Maven会自动搜寻该目录找到项目主代码。
咱们编写HelloWorld.java所在目录是src/main/java/com/learn/mvn/helloworld/HelloWorld.java,则该java的文件包名为:com.learn.mvn.helloworld,这与POM中定义的gruopId和artifactId相吻合,通常来讲,项目中java类的包名都应该基于项目的groupId和artifactId,这样更加清晰,也更符合逻辑,也方便搜索构件。web
package com.learn.mvn.helloworld; public class HelloWorld { public String sayHello() { return "Hello Maven!"; } public static void main(String[] args) { System.out.println(new HelloWorld().sayHello()); } }
代码编写完后,使用maven进行编译,在项目根目录下运行命令 mvn clean compile会获得如下输出:
clean告诉Maven清理出target/目录,compile告诉Maven编译项目主代码。从输出中能够看到Maven首先执行了clean:clean任务,删除target/目录。默认状况下,Maven的全部输出都在target目录中;接着执行resources:resources任务;最后执行compiler:compile任务,将项目主代码编译至target/classes目录。
能够看到其中执行了三个插件,maven-clean-plugin、maven-resources-plugin、maven-compile-plugin,clean会清理输出目录target/,resouce会处理资源文件,compile会编译项目主代码放在target/classes中(编译好的类为com/learn/mvn/helloworld/HelloWorld.Class)。 ###3.3 编写测试代码### 为了保持项目结构清晰,主代码与测试代码应该分别位于独立的目录中。Maven项目中的默认的测试代码目录是src/test/java。
为了使用JUnit进行单元测试咱们须要在pom.xml中添加对JUnit构件的依赖,修改后的pom.xml以下:apache
<?xml version="1.0" encoding="UTF-8"?> <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.learn.mvn</groupId> <artifactId>hello-world</artifactId> <version>1.0-SNAPSHOT</version> <name>Maven Hello World Project</name> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> <scope>test</scope> </dependency> </dependencies> </project>
代码中添加了dependencies元素,该元素下能够包含多个dependency元素以声明项目的依赖。这里添加了Junit的一个坐标。有了这段声明,Maven会自动访问中央仓库 http://search.maven.org/#browse 下载所需的文件。上面pom.xml代码中还有一个值为test的元素scope,scope为依赖范围,若依赖范围为test,则表示该依赖只对测试有效,则在主代码中使用该JUnit就会出错,而在测试代码中使用不会出错。scope默认值为compile,表示该依赖对主代码和测试代码都有效。
接下来编写测试代码:app
package com.learn.mvn.helloworld; import static org.junit.Assert.assertEquals; import org.junit.Test; public class HelloWorldTest { @Test public void testSayHello() { HelloWorld helloWorld = new HelloWorld(); String result = helloWorld.sayHello(); assertEquals("Hello Maven!", result); } }
一个典型的单元测试包含三个步骤:1.准备测试类和数据;2.执行要测试的行为;3.验证测试结果。
测试用例编写完以后就能够掉用Maven执行测试:mvn clean test:dom
E:\MavenProject\hello-world>mvn clean test [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Hello World Project 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello-world --- [INFO] Deleting E:\MavenProject\hello-world\target [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-worl d --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e . build is platform dependent! [INFO] skip non existing resourceDirectory E:\MavenProject\hello-world\src\main\ resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil d is platform dependent! [INFO] Compiling 1 source file to E:\MavenProject\hello-world\target\classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ he llo-world --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e . build is platform dependent! [INFO] skip non existing resourceDirectory E:\MavenProject\hello-world\src\test\ resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello-w orld --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil d is platform dependent! [INFO] Compiling 1 source file to E:\MavenProject\hello-world\target\test-classe s [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello-world --- [INFO] Surefire report directory: E:\MavenProject\hello-world\target\surefire-re ports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.learn.mvn.helloworld.HelloWorldTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.26 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 6.750 s [INFO] Finished at: 2015-09-13T23:59:21+08:00 [INFO] Final Memory: 11M/29M [INFO] ------------------------------------------------------------------------
命令行虽然只输入了mvn clean test,而maven实际所作的处理有:clean:clean(执行maven-clean-plugin的clean目标,下面类同)、resources:resources、compile:compile、resources:testRescources、compile:testCompile、surefire:test。须要知道的是,在Maven执行测试(surefire:test)以前,会先执行项目主资源的处理、主代码的编译、测试资源的处理、测试代码的编译等工做,这是maven生命周期的一个特性。测试代码经过编译以后在target/test-classes下生成了测试文件。
maven在执行上诉处理以前,会读取pom.xml,执行一些操做,如查看相关依赖是否在本地仓库中存在,若是不存在则前往中央仓库下载。在上面的例子中,maven会去下载junit-4.9.pom和junit-4.9.jar文件。
###3.4 打包和运行### hello-world的POM中没有指定打包类型,使用默认的打包类型jar。执行命令 mvn clean package进行打包。maven会在打包以前执行编译、测试等操做,打包后的文件位于target/中,它时根据artifact-version.jar规则来进行命名的。
为了让其余的maven项目直接能够该jar包,还须要执行一个安装的命令, mvn clean install ,将其安装在本地仓库中。maven
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hello-world --- [INFO] Installing E:\MavenProject\hello-world\target\hello-world-1.0-SNAPSHOT.ja r to C:\Users\Administrator\.m2\repository\com\learn\mvn\hello-world\1.0-SNAPSHO T\hello-world-1.0-SNAPSHOT.jar [INFO] Installing E:\MavenProject\hello-world\pom.xml to C:\Users\Administrator\ .m2\repository\com\learn\mvn\hello-world\1.0-SNAPSHOT\hello-world-1.0-SNAPSHOT.p om [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
打开本地仓库的相应目录能够看到hello-world项目的pom和jar。
已经学习了Maven的最主要命令:mvn clean compile、mvn clean test、mvn clean package、mvn clean install。执行compile以前会先执行clean,执行test以前会先执行compile,执行package以前会先执行test、执行install以前会先执行package。
在HelloWorld类中存在一个main方法,可是默认打包生成的jar是不能直接运行的,咱们须要额外在pom.xml中配置maven-shade-plugin插件来实现这个功能。函数
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.learn.mvn.helloworld.HelloWorld</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
plugin元素在POM中的相对位置应该在<project><build><plugins>下面。而后从新执行mvn clean package进行打包。看jar包的MANIFEST.MF文件能够看到有一行Main-Class: com.learn.mvn.helloworld.HelloWorld 在项目根目录中执行该jar文件,能够看到咱们的main函数执行成功了。
###3.5 使用Archetype生成项目骨架### Maven中有一些约定:在项目的根目录中放置pom.xml,在src/main/java目录中放置项目的主代码,在src/test/java中放置项目的测试代码.... 若是咱们每次都手动创建这些文件夹,那就太费劲了。为此,maven提供了Archetype以帮助咱们快速勾勒出项目骨架。
在workspace目录下输入:mvn archetype:generate命令。以下图:工具
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: Define value for property 'groupId': : com.learn.mvn Define value for property 'artifactId': : my-app Define value for property 'version': 1.0-SNAPSHOT: : 1.0-SNAPSHOT Define value for property 'package': com.learn.mvn: : com.learn.mvn.myapp Confirm properties configuration: groupId: com.learn.mvn artifactId: my-app version: 1.0-SNAPSHOT package: com.learn.mvn.myapp Y: : Y [INFO] ------------------------------------------------------------------------- --- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.1
maven会要求你选择archetype的类型,通常状况下使用默认的maven-archetype-quickstart,无需输入直接回车便可,而后会要求选择这类型的版本,推荐maven-archetype-quickstart使用1.1。而后会要求输入该项目的一些配置信息,如groupId、artifactId、version、package。
这里使用的是一个基本的archetype,若是有不少项目拥有相似的自定义项目结构以及配置文件,则能够定义本身的Archetype,在之后的项目中用本身的Archetype生成骨架。 ###3.6 Maven在Eclipse中配置###性能