Maven实战:Maven生命周期
前言
之前有写过一篇文章Maven实战,介绍了Maven的一些基本概念,以及对于一个初学者而言的Maven基础知识,当时在我看来掌握了这些基本是够用的。
随着工作的深入,越来越感觉对于Maven的理解不够,很多时候使用Maven出了问题都无法很快地解决,因此打算深入地从搭建Maven工程开始学习一下Maven,这篇文章就将自己的学习历程记录下来和网友朋友们分享。
从搭建最简单的Maven项目开始
LZ使用的是MyEclipse,那么就是用MyEclipse搭建一个简单的Maven项目。第一步,new一个Maven Project:

点击next:

这里不推荐勾选"Create a simple project(skip archetype selection)",这样就可以使用很多Maven Archetype,也就是Maven原型,点击next:

看到这里出现了很多Maven推荐给开发者的原型,"org.apache.maven"开头的都是maven官方推荐的,选择一个简单的"maven-archetype-quickstart",接着就是填入一些基本信息:

这些信息填写比较自由,当然之后也会对Group Id、Artifact Id、Version、Package等再做解释,点击finish,MyEclipse就给我们生成好了一个Maven工程:

这就是"maven-archetype-quickstart"原型生成的标准目录结构,"src/main/java"用于编写Java代码、"src/test/java"用于编写测试类,看一下其中最重要的pom.xml:
<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>org.xrq.mvnstart</groupId>
<artifactId>hello-world</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>hello-world</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
看到"maven-archetype-quickstart"原型给我们导入了一个junit的jar包,用于单元测试。注意一下,默认生成JUnit版本是3.8.1的,该版本的JUnit不支持注解,后面的单元测试是用的注解,因此把这里改成4.10的版本。
另外,还有个重点就是,最终打包出来的文件类型是一个jar包(packaging)。
OK,那接下来我们就开始编写Java代码以及测试类的代码。
编写主代码及编译
项目主代码和测试代码不同,项目的主代码会被打包到最终的构件中,而测试代码只在运行测试时用到,不会被打包。
生成的工程下,默认有一个App类,稍作修改:
public class App
{
public String sayHelloWorld()
{
return "Say Hello World!";
} public static void main( String[] args )
{
System.out.println(new App().sayHelloWorld());
}
}
代码写完,接着编译,由于Maven使用命令进行操作,因此进入控制台,进入工程目录,输入"mvn clean compile":

此时工程的变化是,在target下有编译好的App.java对应的App.class:

这条命令的意思是:
1、clean告诉Maven清理输出目录target/
2、compile告诉Maven编译项目主代码
从输出中可以看到Maven首先执行了clean:clean任务,删除target/目录;紧接着执行resources:resources任务(因为未定义项目资源,因此此项略过);最后执行compiler:compile任务,将项目主代码编译至target/classes目录。
要说一点,clean:clean、resources:resources、compiler:compile对应了一些Maven插件及插件目标,比如clean:clean是clean插件的clean目标,compiler:compile是compiler插件的compile目标,这在后面的文章中会说明。
编写测试代码及编译
为了保证项目结构清晰,主代码与测试代码应当分别位于独立的目录中。Maven项目中默认的主代码目录是src/main/java,相应地Maven项目中默认的测试代码目录是src/test/java,因此如果在编写测试用例之前没有该目录,应当首先创建该目录。
测试代码为:
public class AppTest
{
@Test
public void testSayHelloWorld()
{
App app = new App();
String result = app.sayHelloWorld();
Assert.assertEquals(result, "Say Hello World!");
}
}
用了JUnit,上面的pom.xml中依赖项,JUnit的scope是test,这表示JUnit的包只对测试目录是有效的,换句话说,在主目录下使用JUnit将会导致编译报错。
这里还有一个问题要特别说明,由于历史原因,Maven的核心插件之一compiler插件默认只支持编译Java1.3,这个版本并不支持JUnit,因此需要配置该插件使其支持Java5才可以使用JUnit。因此在pom.xml中加入一段:
<build>
<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>
</build>
这样就使得插件支持Java5编译。此时命令行中输入mvn clean test:

测试通过,没有问题。
打包
在项目编译、测试通过之后,就会进行一项操作,就是打包(package)。
同样,使用命令行操作,输入"mvn clean package",打包前会先编译、测试,这些信息就不截取了,只看打包的部分:

打包的名字是按照artifactId+version来的,如有需要也可以自定义,这个这里也不讲了。
打包完毕,再看一下工程目录:

多出了一个jar文件,这样就可以在别的地方使用这个jar文件了。
安装
上面生成的jar文件,可以直接复制到别的项目的CLASSPATH下供其他项目使用,那么如何让其他项目直接使用这个jar包呢?可以使用install。
在命令行中输入"mvn clean install",同样我只截取关键的部分:

看到生成的jar和pom被安装到本地仓库中了,只有当构建被下载到本地仓库之后,才能供其他Maven项目使用。这里也是同样道理,只有将Hello World的构件安装到本地仓库之后,其他Maven项目才能使用它。
Maven生命周期
上面的内容,包含了Mavan最主要的命令:mvn clean compile、mvn clean test、mvn clean package、mvn clean install。执行test之前,先执行compile、执行package之前先执行test、执行install之前先执行package,这就涉及到一个概念:Maven生命周期。
在Maven中有三套独立的生命周期:
- Clean Lifecycle:在进行真正的构建之前进行一些清理工作
- Default Lifecycle:构建的核心部分,编译、测试、打包、部署
- Site Lifecycle:生成项目报告、生成站点、发布站点
第一个和第三个比较简单也比较好理解,看一下Maven的最重要的Default生命周期,绝大部分工作都发生在这个生命周期中,在这个阶段中,比较重要和常用的阶段有:
- validate
- generate-sources
- process-sources
- generate-resources
- process-resources:复制并处理资源文件至目标目录,准备打包
- compile:编译项目源代码
- process-clases
- generate-test-sources
- procss-test-sources
- generate-test-resources
- process-test-resources:复制并处理资源文件至目标测试目录
- test-compile:编译测试源代码
- process-test-classes
- test:使用合适的单元测试框架测试运行,这些测试代码将不会被打包或部署
- prepare-package
- package:接受编译好的代码,打包成可发布的格式,如jar
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install:将包安装至本地仓库,以便让其它项目依赖
- deploy:将最终的包复制到远程仓库,以便让其它开发人员与项目共享
基本上,只要根据名称我们就可以猜测出每个阶段的用途。要记住的是,任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么我们运行mvn clean install的时候,代码会被编译、测试、打包。
此外,Maven的插件机制是完全依赖Maven生命周期的,因此理解生命周期至关重要。
Maven实战:Maven生命周期的更多相关文章
- 介绍maven构建的生命周期
介绍maven构建的生命周期 这篇是 https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html 的 ...
- maven核心概念--生命周期
maven有一个命令,mvn package,该命令行并没有指定一个插件目标, 而是指定了一个Maven生命周期阶段.一个阶段是在被Maven称为"构建生命周期"中的一个步骤.生命 ...
- Maven整理笔记の生命周期和插件
项目构建的生命周期,其实软件开发人员每天都在干这个事,即项目清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等,可以说几乎所有项目的构建都可以映射到这样一个生命周期上. Maven的插件 ...
- Maven的构建生命周期理解
以下引用官方的生命周期解释https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html: 一.构建生命 ...
- Maven构建的生命周期
什么是构建生命周期 构建生命周期是一组阶段的序列(sequence of phases),每个阶段定义了目标被执行的顺序.这里的阶段是生命周期的一部分.举例说明,一个典型的 Maven 构建生命周期是 ...
- Maven专题3——生命周期与插件
三套生命周期 Maven有3套相互独立的生命周期,用户可以调用某个生命周期的阶段,而不会对其他生命周期产生影响. 每个生命周期包含一些有先后顺序的阶段,后面的阶段依赖于前面的阶段,意味着用户调用后面的 ...
- maven的三大生命周期
一.Maven的生命周期 Maven的生命周期就是对所有的构建过程进行抽象和统一.包含了项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几乎所有的构建步骤. Maven的生命周期 ...
- Maven项目的生命周期
Maven中存在三套生命周期,每一套生命周期相互独立,互不影响.在一套生命周期内,执行后面的命令前面的命令会自动执行. CleanLifeCycle:清理生命周期 mvn clean DefaultL ...
- 项目构建之maven篇:6.生命周期与插件
项目生命周期 清理 初始化 编译 測试 打包 部署 三套生命周期 1.clean pre-clean 运行一些须要在clean之前完毕的工作 clean 移除全部上一次构建生成的文件 post-cle ...
- 010.[转] maven的三大生命周期
一.Maven的生命周期 Maven的生命周期就是对所有的构建过程进行抽象和统一.包含了项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几乎所有的构建步骤. Maven的生命周期 ...
随机推荐
- 【.net 深呼吸】细说CodeDom(4):类型定义
上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...
- Asp.Net WebApi核心对象解析(下篇)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
- BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]
1911: [Apio2010]特别行动队 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 4142 Solved: 1964[Submit][Statu ...
- 游戏编程系列[1]--游戏编程中RPC协议的使用[3]--体验
运行环境,客户端一般编译为.Net 3.5 Unity兼容,服务端因为用了一些库,所以一般为4.0 或往上.同一份代码,建立拥有2个项目.客户端引用: WindNet.Client服务端引用: OpL ...
- C# 正则表达式大全
文章导读 正则表达式的本质是使用一系列特殊字符模式,来表示某一类字符串.正则表达式无疑是处理文本最有力的工具,而.NET提供的Regex类实现了验证正则表达式的方法.Regex 类表示不可变(只读)的 ...
- Android学习探索之Java 8 在Android 开发中的应用
前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...
- javascript之Object.defineProperty的奥妙
直切主题 今天遇到一个这样的功能: 写一个函数,该函数传递两个参数,第一个参数为返回对象的总数据量,第二个参数为初始化对象的数据.如: var o = obj (4, {name: 'xu', age ...
- [C#] 简单的 Helper 封装 -- SQLiteHelper
using System; using System.Data; using System.Data.SQLite; namespace SqliteConsoleApp { /// <summ ...
- Entity Framework 教程——Entity Framework中的实体类型
Entity Framework中的实体类型 : 在之前的章节中我们介绍过从已有的数据库中创建EDM,它包含数据库中每个表所对应的实体.在EF 5.0/6.0中,存在POCO 实体和动态代理实体两种. ...
- springmvc 多数据源 SSM java redis shiro ehcache 头像裁剪
获取下载地址 QQ 313596790 A 调用摄像头拍照,自定义裁剪编辑头像 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单; 技术:31359679 ...