maven入门(二)
像Make的Makefile、Ant的build.xml一样,Maven是基于pom.xml来管理配置的。POM(Project Object Model,项目对象模型)定义了项目的基本信息,描述了项目如何构建、声明项目依赖等信息。
编写POM
我们不需要手动创建pom.xml文件,可以使用开发工具创建初始文件。这里我使用的IntelliJ IDEA创建个maven工程。
选择Maven工程 输入GroupId、ArtifactId、Version 输入工程名称 工程目录结构目录结构为maven约定的目录结构
maven-p1/src/main主目录
maven-p1/src/test测试目录
maven-p1/pom.xml POM文件
同时我们会看到工程目录下有pom.xml文件。文件内容为:
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.buff.study</groupId>
<artifactId>maven-p1</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
其中groupId、artifactId、version是我们在创建工程时输入的内容。
编写工程代码
创建好pom.xml,即创建好maven工程后,需要编写工程代码。这里我们写个包含main方法的测试类
package com.buff.study.mvnp1;
/**
* @Author: Buff
* @Description:测试类
* @Date: Created in 2018/6/8 12:46
*/
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命令。我们会看到日志中三个maven插件以及对应的三个操作,三个插件分别是maven-clean-plugin、maven-resources-plugin、maven-compiler-plugin,如果是安装完maven环境后第一次执行该命令的话,maven会自动下载这三个插件,同时会打印下载日志。这个三个插件顺序对应的三个操作分别是clean、resources、compile。
我们的命令mvn clean compile只指定了clean和compile,为啥会有resources呢,这个是由maven的生命周期过程决定的,后续会详细讲解。我们只需要感性的体会一下mavne的命令执行即可。
clean:清空输出目录target目录
resources:由于工程没有定义资源文件,所以这里没执行实际的动作
compile:将项目源码编译至target/classes目录下
C:\Users\vicya\data\study\maven-p1>mvn clean compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-p1 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven-p1 ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-p1 ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-p1 ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to C:\Users\vicya\data\study\maven-p1\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.279 s
[INFO] Finished at: 2018-06-08T12:52:10+08:00
[INFO] Final Memory: 13M/198M
[INFO] ------------------------------------------------------------------------
编写工程测试代码
由于我们使用Junit框架作为测试工具,所以需要添加junit的jar包。如果不使用maven的话,我们需要从网上下载junit的jar包,并且通过IDE引入到工程中。但是如果使用maven的话,我们只需要在pom.xml配置文件 中做以下配置,maven就可以帮我们自动下载对应的jar包,并完成工程引入,非常方便。maven下载的jar文件是从仓库中获取,关于仓库我们后续再详细讲解。
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
在配置文件中添加以上内容后,IDEA监听到pom.xml作了修改,会提示我们进行pom的重构,点击Import Changes即可。注意<scope>test</scope>配置,scope表示依赖范围,设置为test就是说junit只会在测试目录中使用,在主目录中是不可见的,如果在主目录代码中使用junit会编译不过的。这样的话在工程打包的时候的也不会引入junit相关包。
maven提示
添加完依赖包之后就可以编写junit测试代码,代码如下:
import static org.junit.Assert.assertEquals;
/**
* @Author: Buff
* @Description:
* @Date: Created in 2018/6/8 13:05
*/
public class HelloWorldTest {
@Test
public void testSayHello(){
HelloWorld helloWorld = new HelloWorld();
String result = helloWorld.sayHello();
assertEquals("hello maven!", result);
}
}
maven测试
在工程目录下执行mvn clean test,会看到对maven进行了以下操作
1.clean输出目录
2.主目录resources资源文件处理
3.主目录源码编译
4.测试目录resources资源文件处理
5.测试目录源码编译
6.进行测试代码
7.输出测试报告
C:\Users\vicya\data\study\maven-p1>mvn clean test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-p1 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven-p1 ---
[INFO] Deleting C:\Users\vicya\data\study\maven-p1\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-p1 ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-p1 ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to C:\Users\vicya\data\study\maven-p1\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-p1 ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\Users\vicya\data\study\maven-p1\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-p1 ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to C:\Users\vicya\data\study\maven-p1\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-p1 ---
[INFO] Surefire report directory: C:\Users\vicya\data\study\maven-p1\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.buff.study.mvnp1.HelloWorldTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.067 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.484 s
[INFO] Finished at: 2018-06-08T13:27:20+08:00
[INFO] Final Memory: 15M/210M
[INFO] ------------------------------------------------------------------------
maven打包和运行
以上内容我们基本完成了代码的编写和测试工作,接下来我们需要进行打包并运行。
maven在没有指定打包文件格式时,默认的是打成jar包。在控制台运行mvn clean package命令后,在target目录下会生成maven-p1-1.0-SNAPSHOT.jar。以下是部分maven日志。
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-p1 ---
[INFO] Building jar: C:\Users\vicya\data\study\maven-p1\target\maven-p1-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.115 s
[INFO] Finished at: 2018-06-08T13:37:50+08:00
[INFO] Final Memory: 16M/211M
[INFO] ------------------------------------------------------------------------
接下来运行jar包,结果运行失败。
C:\Users\vicya\data\study\maven-p1>java -jar ./target/maven-p1-1.0-SNAPSHOT.jar
./target/maven-p1-1.0-SNAPSHOT.jar中没有主清单属性
这是由于我们在打包的时候没有指定main方法,所以这个jar包是无法正常启动运行的。如果我们的工程本身没有main方法,只是提供给其他工程做依赖的,那这个打包是没问题的。可如果我们要运行这个jar包则class中必须要有main方法,并且jar包的MANIFAST.MF必须指定该方法。所以这就需要我们做额外的工作来添加MANIFAST.MF。使用maven插件来帮我们完成这些工作,在pom.xml中配置以下内容,主要是告诉maven插件我们的main方法所在类即可。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.2.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.buff.study.mvnp1.HelloWorld
</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
配置完成后,再次打包并运行,可以看到正确结果
C:\Users\vicya\data\study\maven-p1>java -jar ./target/maven-p1-1.0-SNAPSHOT.jar
hello maven!