Maven [ˈmevən] ,跨平台的项目管理工具,主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。
何为构建?什么是依赖?为什么要用Maven?他有什么优点。先不急着明白这些概念,我们从一个简单的maven java项目入手,慢慢理解。
本文适合对概念有一定了解,但没使用过,掌握不是很透彻的同学阅读。
一、Maven java项目结构:
一个简单的maven java项目结构如下图所示,我们按照maven的规范创建项目路径如下:
- 项目名为hello-world,src/main/java目录下存放项目主代码,src/test/java目录下存放测试代码
- target为项目编译后自动生成的文件存放处
- pom配置文件
- ps:src/main/resources一般存放图片、属性文件,此处为了简单起见,暂不创建,
二、编写POM配置文件:
POM 包含了关于工程和各种配置细节的信息,Maven 使用这些信息,构建工程。是构建执行的入口。
每一个工程只有一个POM文件,POM文件需要project元素和三个必须的字段:groupId、artifactId和version。
- groupId对应工程目录的com.xiaomi.mvnbook,不要求一定这么编写,可自定义,但建议这样编写。
- artifactId对应helloworld,不要求一定这么编写,可自定义,但建议这样编写。
需要明白的是,groupId、artifactId和version,就像一个maven的坐标系统,maven通过坐标系统,在自己的中央库/私库中,准确定位到每一个构件(artifact),通过坐标能够找到任何一个java类库。
他和代码中的对应关系,详见注释:
1 <?xml version="1.0" encoding="uft-8"?> <!--指定了xml文档的版本和编码方式 --> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!--所有project的根元素--> 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!--声明了pom相关的命名空间及xsd元素--> 4 <modelVersion>4.0.0</modelVersion> <!--指定了pom模型的版本--> 5 <groupId>com.xiaomi.mvnbook</groupId> <!--groupId定义了项目属于哪个组,比如xiaomi公司的mvnbook项目,对应工程目录com.xiaomi.mvnbook--> 6 <artifactId>helloworld</artifactId> <!--artifactId定义了组中的唯一的id,对应com.xiaomi.mvnbook下的helloworld--> 7 <version>1.0-SNAPSHOT</version> <!--定义了hello-world项目版本号--> 8 <name>Maven Hello World Project</name> <!--自定义的项目名,方便查阅 --> 9 </project>
三、编写主代码:
该java类的包名是com.xiaomi.mvnbook.helloworld,这与之前POM定义的groupId和artifactid相吻合。一般来说,java类的包都应该基于项目的groupId和artifactId,这样更方便搜索构件或者java类。
maven对于项目目录结构、测试用例命名方式等都有既定的规则。默认java主代码在src/main/java目录。
HelloWorld.java
1 package com.xiaomi.mvnbook.helloworld; 2 3 public class HelloWorld{ 4 public String sayHello(){ 5 return "Hello Maven"; 6 } 7 public static void main(String []args){ 8 System.out.print(new HelloWorld().sayHello()); 9 } 10 }
四、mvn clean compile 编译主代码:
代码编写完成后我们使用maven进行编译。回到pom.xml同级目录。cmd执行mvn clean compile,输出如下:
mvn clean compile的意思是:clean告诉Maven执行前,清理输出目录target/,compile告诉Maven编译项目主代码,也就是main/java/下的代码
从执行的日志来看,首先是执行了clean:clean目标任务,删除target目录
接着执行resource:resource目标任务(没有定义项目资源,skip略过)
五、编写测试代码并执行mvn clean test:
测试代码,需要调用junit类,依赖的代码包,可以用maven进行管理,此时就需要继续编写pom文件。
1 <?xml version="1.0" encoding="utf-8"?> <!--指定了xml文档的版本和编码方式 --> 2 <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"> <!--所有project的根元素--> <!--声明了pom相关的命名空间及xsd元素--> 3 <modelVersion>4.0.0</modelVersion> <!--指定了pom模型的版本--> 4 <groupId>com.xiaomi.mvnbook</groupId> <!--groupId定义了项目属于哪个组,比如xiaomi公司的mvnbook项目,就是com.xiaomi.mvnbook --> 5 <artifactId>helloworld</artifactId> <!--artifactid定义了组中的唯一的id--> 6 <version>1.0-SNAPSHOT</version> <!--定义了helloworld项目版本号--> 7 <name>Maven Hello World Project</name> <!--自定义的项目名,方便查阅 --> 8 <dependencies> <!--dependencies元素下可以包含多个dependency,用来声明项目的依赖--> 9 <dependency> <!--这里添加的是junit的依赖,之前的groupId等是junit的坐标,有了这个坐标就可以从中央仓库自动下载junit-4.7.jar--> 10 <groupId>junit</groupId> 11 <artifactId>junit</artifactId> 12 <version>4.7</version> 13 <scope>test</scope> <!--此处值为test,对应是依赖范围,指该依赖只对测试有效,即测试代码中importJUnit代码没问题,但在主代码中引用就会报错,若想全部都能引用则scope默认值为compile--> 14 </dependency> 15 </dependencies> 16 </project>
编写测试类,对应主程序,测试的类路径为hello-worldsrc estjavaHelloWorldTest.java
1 package com.xiaomi.mvnbook.helloworld; 2 import static org.junit.Assert.assertEquals; 3 import org.junit.Test; 4 //一个标准的测试用例包含三个步骤 5 //①准备测试类和测试数据 6 //②执行要测试的行为 7 //③检查结果 8 public class HelloWorldTest{ 9 @Test 10 public void testSayHello(){ 11 HelloWorld helloWorld = new HelloWorld(); 12 String result = helloWorld.sayHello(); 13 assertEquals("Hello Maven",result); 14 } 15 }
运行mvn clean test,从输出日志中,可以看出,执行过程如下:
- 先读取pom文件,然后根据依赖包配置,从maven中央库中,进行下载,下载junit的pom文件,然后再下载对应的jar包。
- 清除target中的文件,然后是主程序的resources,然后执行主程序的compile
- 再执行test的compile,通过之后,执行test单元测试surefire:test,最后输出测试的结果。注:surefire是Maven中负责执行测试的插件,这里他运行测试用例HelloWorldTest
六、打包 mvn clean package:
项目编译完了,测试通过了,就可以打包了,pom中没有明确规定打包的格式,默认为jar,打包名默认为artifact-version.jar
mvn clean package
执行的输出如下:【执行packge命令,仍然会先执行主代码编译,测试代码编译,测试执行的步骤,篇幅较长,只截取打包的日志】
这样就可以copy生成的jar到其他项目的classpath中进行调用。但若要其他maven项目进行调用,则需要执行install安装/部署到私有库中,再进行类似之前Junit的这种调用。
mvn clean install