maven(翻译为“专家”,“内行”)百度百科这么描述 “maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件”。其实maven就是一个服务于java平台的项目构建工具,还可以对项目的jar包进行依赖管理。
举个例子,我们开始学习javaweb项目的时候,除了jdk提供的jar包外,其他第三方jar包都需要我们自己导入。每次创建项目都需要将所需的jar包拷贝到项目中,导致每个项目占用空间比较大,而且我们需要关注jar包的版本,方式jar包冲突等问题,然而如果使用maven管理项目的话,我们不需要手动导入jar包,而且jar包的版本控制也很方便。maven有两大核心,maven对项目的管理依赖的就是这两大核心,分别是依赖管理和项目构建。
使用maven工具的时候会设置配置文件setting.xml,在setting中设置了jar包的仓库等配置,使用IDE开发工具也会在开发工具中配置maven插件,我们创建的maven项目会有一个pom.xml文件,maven项目就是通过pom.xml文件管理项目的,首先pom文件中会有本项目的坐标即groupid,artifactId,version,针对jar包其实每一jar包都是有各自的坐标,pom文件就是配置了这些jar包的坐标,通过坐标可以在maven仓库中获取到对应的jar包,所以不需要将jar导入到项目中,直接引用仓库中的jar包就可以了,如果需要修改jar包的版本,也很方便即修改version就可以。
如果比较大的项目可能需要将多个模块分别创建成一个工程,那么就可以为这些工程创建一个统一的父工程,父工程可以规则jar包的版本,或者引入指定的jar包,那么其他子工程就可以将父工程引入到自己工程中就可以使用父工程的jar包,依赖管理就是本项目依赖的jar包引入之后会将jar包依赖的jar包也会引入。
通过maven可以对项目进行清理,编译,测试,打包,部署等功能,比如我们之前运行javaweb项目需要借助Eclipse将项目部署到tomcat上,启动tomcat运行项目。如果使用maven可以在项目根目录下,即pom.xml所在目录,在cmd中使用命令:mvn tomcat:run,就将项目发布到tomcat上,并且返回项目的访问路径。
注意:使用命令mvn tomcat:run,是将项目发布到maven自带的tomcat上,maven有自带的tomcat插件,设置如下:
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8090</port> <path>/</path> </configuration> </plugin> 复制代码
maven的安装配置其实很简单,就是从maven官网 maven.apache.org/download.cg… 下载maven程序,再解压,解压后的目录结构如下图,然后修改目录conf中的setting.xml文件配置本地仓库路径,私服从库路径,然后为我们的开发工具配置maven。
注意:maven是java开发的,所以它的运行需要依赖jdk,需要配置jdk环境变量,当然我们使用maven命令也需要配置maven的环境变量。
maven下载解压即可:
环境变量配置如下(win10):
(1)配置MAVEN_HOME
(2)将MAVEN_HOME配置到path中
配置完环境变量,查看maven安装是否成果可以通过cmd命令查询:
maven的解压后的目录如下:
bin目录:可执行脚本命令
boot目录:maven的类加载器
conf目录:maven的配置文件,我们常操作的setting.xml文件就在这里。
lib目录:maven运行的依赖jar包
maven仓库一般有三种:本地仓库,私服仓库,中央仓库或者其他公共仓库。
当然我们一般使用的是本地仓库,如果本地仓库没有所需要的jar包就会从远程仓库获取(私服中获取或者中央仓库获取),但是中央仓库在国外由于网速的限制,一般下载很慢,当然我们可以使用国内的远程仓库,比如阿里云的。
我们常用的配置<localRepository>、<mirror>、<plugins>
配置本地仓库地址,开发工具中配置maven的setting.xml,就会自动定位到本地仓库的位置,如下:
<localRepository>C:/JAVA/maven/maven_warehouse</localRepository> 复制代码
配置远程仓库,如下:
<!-- 这是阿里云的远程仓库 公司的maven会配置公司的私服仓库--> <mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> </mirror> 复制代码
配置jdk版本,配置jdk版本有两种方式,如下:
第一种是局部配置,只配置本项目的jdk版本,可以通过在pom文件中设置;
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> 复制代码
第二种是全局配置,修改setting.xml文件;
<profile> <id>jdk</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile> 复制代码
当然maven的setting不仅仅只有这些功能还有很多,在这里我们不一一介绍。
MavenProjectRoot(项目根目录)
|----src | |----main | | |----java ——存放项目的.java文件 | | |----resources ——存放项目资源文件,如spring配置文件 | |----test | | |----java ——存放所有测试.java文件,如JUnit测试类 | | |----resources ——存放项目资源文件,如spring配置文件 |----target ——项目输出位置 |----pom.xml ----用于标识该项目是一个Maven项目 复制代码
pom(Project Object Model)项目对象模型,是maven的基本工作单元,其中包含了maven构建项目和各种配置的信息。
所有项目都需要配置:
<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.cxd.demo</groupId> <artifactId>studyDemo</artifactId> <version>1.0</version> <project> 复制代码
所有pom文件都需要三个字段:groupId,artifactId,version
groupId代表项目名称,通常是独一无二的,一般是公司名+项目组名称
artifactId代表项目名称
version代表版本号
modelVersion代表Maven模板版本,目前我们一般都取值4.0.0,这标志着我们现在使用的是maven2
groupId和artifactId合起来作为当前项目的唯一标识也就是坐标,maven2最终会根据这两个值,决定项目发布到仓库上是所处的位置。
子工程也可以继承父工程,那么子工程的pom文件可以使用将父工程引入。例如:创建Springboot项目就会生成一个,并且可以使用父工程所继承的jar包
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> <relativePath /> </parent> 复制代码
有些情况我们可以创建一个父工程用于管理子模块,可以在父工程中规定一些jar包版本,那么子工程在引入jar包时不设定版本,版本统一由父工程管理。
项目聚合与项目继承类似,有些大的项目可能会有很多个模块,构建的时候需要逐个构建,比较繁琐,那么可以使用来解决,只需要对父工程执行maven命令就可以同时实现对子工程的操作,当然子工程也需要继承父工程。例如:
父工程:
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1</version> <packaging>pom</packaging> <modules> <module>my-module</module> </modules> </project> 复制代码
子工程:
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.module</groupId> <artifactId>my-module</artifactId> <version>1</version> <parent> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1</version> <relativePath>../parent/pom.xml</relativePath> </parent> </project> 复制代码
在pom文件中如版本号可能是多个jar包的引用都使用同一个版本号,那么就需要多次引用,若需要修改的时候都得修改,可能会漏掉,为了方便可以通过<properties>设置一些变量,通过${变量名称}来引用即可,<properties>还能添加属性,maven有6类属性,内置属性,POM属性,自定义属性,setting属性,java系统属性和环境变量,例如:
如当前项目版本${version}、当前项目根目录${basedir} 复制代码
POM属性:用户可以使用该类属性引用POM文件中对应元素的值。例如
${project.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/. ${project.build.testSourceDirectory}:项目的测试源码目录,默认为/src/test/java/. ${project.build.directory}:项目构建输出目录,默认为target/. 复制代码
<!--自己定义的一些属性spring-cloud.version、jetty.version通过${spring-cloud.version}、${jetty.version}引用--> <properties> <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version> <jetty.version>9.4.14.v20181114</jetty.version> </properties> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-annotations</artifactId> <version>${jetty.version}</version> </dependency> 复制代码
与POM属性同理,用户使用以settings. 开头的属性引用settings.xml文件中的XML元素的值。 如${settings.localRepository} 本地仓库。 复制代码
所有java系统属性都可以用Maven属性引用 如${user.home}指向了用户目录。 复制代码
所有环境变量属性都可以使用以env. 开头的Maven属性引用 如${env.JAVA_HOME}指代了JAVA_HOME环境变量的的值。 复制代码
根据POM 4.0.0 XSD,build元素概念性的划分为两个部分:BaseBuild(包含poject build和profile build的公共部分,见下)和poject build包含的一些高级特性。
<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 Build" contains more elements than just the BaseBuild set --> <build>...</build> <profiles> <profile> <!-- "Profile Build" contains a subset of "Project Build"s elements --> <build>...</build> </profile> </profiles> </project> 复制代码
<build> <defaultGoal>install</defaultGoal> <directory>${basedir}/target</directory> <finalName>${artifactId}-${version}</finalName> <filters> <filter>filters/filter1.properties</filter> </filters> ... </build> 复制代码
defaultGoal:执行build任务是,如果没有指定目标,那么就是用默认的,如上设置,在命令行执行mvn命令,就相当于执行mvn install
directory:指定项目构建的位置,默认在target下;
finalName:指定最后构建的jar包名称,默认为“项目名称-版本”;
filter:定义*.properties文件,包含一个properties列表,该列表会应用的支持filter的resources中。也就是说,定义在filter的文件中的"name=value"值对会在build时代替${name}值应用到resources中。Maven的默认filter文件夹是${basedir}/src/main/filters/。
build的另一个特征是指定你的项目中resources的位置。resources(通常)不是代码,他们不被编译,但是被绑定在你的项目或者用于其它什么原因,例如代码生成。
<build> ... <resources> <resource> <targetPath>META-INF/java</targetPath> <filtering>false</filtering> <directory>${basedir}/src/main/java</directory> <includes> <include> **/*.xml</include> </includes> <excludes> <exclude>>**/*.java</exclude> </excludes> </resource> <resource> <directory>${basedir}/src/main/resources</directory> <excludes> <exclude>logback-test.xml</exclude> </excludes> </resource> </resources> <testResources> ... </testResources> ... </build> 复制代码
resources:一个resource元素的列表,每一个都描述与项目关联的文件是什么和在哪里;
targetPath:指定build后的resource存放的文件夹。该路径默认是basedir。通常被打包在JAR中的resources的目标路径为META-INF;
filtering:true/false,表示为这个resource,filter是否激活。
directory:定义resource所在的文件夹,默认为${basedir}/src/main/resources;
includes:指定作为resource的文件的匹配模式,用*作为通配符;
excludes:指定哪些文件被忽略,如果一个文件同时符合includes和excludes,则excludes生效;
testResources:定义和resource类似,但只在test时使用,默认的test resource文件夹路径是${basedir}/src/test/resources,test resource不被部署。
我们常用plugin设置maven插件
使用Apache的maven插件构建项目,并锁定jdk版本
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> 复制代码
如果创建的是springboot项目,那么就会有自带的maven构建插件
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> 复制代码
注意:使用Apache的maven打包的结构和springboot自带的maven插件结构不一样
如下的项目结构
|----src | |----main | | |----java ——存放项目的.java文件 | | |----com | | |----name | | |----resources ——存放项目资源文件,如spring配置文件 | | |----com | | |----docker | | |----prop | | |----application.properties | |----test | | |----java ——存放所有测试.java文件,如JUnit测试类 | | |----resources ——存放项目资源文件,如spring配置文件 |----target ——项目输出位置 |----pom.xml ----用于标识该项目是一个Maven项目 复制代码
使用Apache的maven打成jar包,解压后的结构如下图
使用springboot的maven插件打成jar包后的结构,如下:
其中BOOT-INF中classes目录中存放在编译后的.class文件
注意:
<!--插件maven-compiler-plugin是用于编译项目的,可以设定jdk版本,用此插件打jar包不能使用java -jar xxx.jar 启动,会报此异常‘中没有主清单属性’,但是若直接依赖此包,调用jar包中的接口可以使用--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <!--锁定jdk版本也可以用下面的方式--> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> 复制代码
<!-- springboot的maven插件,可以通过java -jar xxx.jar直接运行--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> 复制代码
依赖管理是maven的核心功能,pom文件可以通过maven配置的仓库获取jar包,使用
<dependencies> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency> </dependencies> 复制代码
当我们有多个maven项目,有共同需要的jar包,那么就可以创建一个父工程去管理jar包,如果父工程通过<dependencies>引入了jar包,那么所有子工程只要继承父工程就可以使用该jar包,不需要再引入;还有另一种情况,A, B, C三个子工程只有其中A和B需要引入某个jar包,而C不需要,那么可以通过<dependecyManagement>,此标签可以实现jar包的统一管理,只是管理不会引入jar包,子工程继承之后如果需要可以自己引入,不需要就可以不引入,例如:
<dependencyManagement> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencyManagement> 复制代码
父工程管理Springcloud,只是规定了jar包的版本,范围,类型,但是没有将该jar包引入,如果子工程需要那么就可以自行引入该jar包
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> 复制代码
jar包在依赖传递中有一个标签<scope>影响传递范围(6种)
依赖范围 | 对于编译 classpath有效 |
对于测试 classpath有效 |
对于运行时 classpath有效 |
例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | - | Y | - | Junit |
provided | Y | Y | - | slrvlet-api |
runtime | - | Y | Y | JDBC驱动 |
system | Y | Y | - | 本地的,maven从库之外的类库 |
import |
compile 当 scope 未指定时的默认值,在编译,测试,运行时都需要,在所有的类路径都是可用的。
provided 类似 compile,表示你希望在运行时由 JDK 或者容器去提供这些依赖。例如,当构建一个 web 项目的时候,我们会设置 Servlet API 相关的依赖的 scope 为 provided,因为这些类应该由容器提供,所以如果容器提供的jar包需要将依赖范围设置为provided,比如:项目运行在tomcat容器中,那么有些jar包Tomact可以提供,所以就不需要项目提供,可以将此jar包的影响范围设置为provided,只编译,测试时有效,运行时有tomcat提供,可以防止jar包冲突。
runtime 表示依赖在项目运行时需要被使用。
test 表示依赖在测试的时候需要被使用。
system 类似于 provided,只是本地依赖,有时候我们用到一些远程仓库中没有的依赖,就需要使用这个 scope,表示使用本地的依赖,配合systemPath使用,通过systemPath指定本地jar包的位置,如:E:/lib/fastjson-1.2.29-SNAPSHOT.jar或者导入第三方jar包。
import (在 Maven 2.0.9 或更高版本中可用)
此 scope 仅支持 pom 文件中 type 配置为 pom 的依赖,并只能在 <dependencyManagement> 中使用。相当于引入依赖管理。例如:
<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-testng</artifactId> <scope>test</scope> <version>1.6.5</version> </dependency> <dependencyManagement> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencyManagement> <!--导入第三方jar包--> <dependency> <groupId>com.hope.cloud</groupId> <!--自定义--> <artifactId>cloud</artifactId> <!--自定义--> <version>1.0</version> <!--自定义--> <scope>system</scope> <!--system,类似provided,需要显式提供依赖的jar以后,Maven就不会在Repository中查找它--> <systemPath>${basedir}/lib/cloud.jar</systemPath> <!--项目根目录下的lib文件夹下--> </dependency> 复制代码
传递依赖:A项目依赖B,B依赖C,那么就有C依赖A,假如A依赖jar包版本为1.0,而C依赖相同的jar包,但是依赖的版本是2.0那么就会出现版本冲突的问题。例如:struts2-spring-plugin和spring-context都存在spring-beans这个jar包,但是版本不一样,struts2-spring-plugin-2.3.24.jar中有spring-beans-3.0.5.RELEASE.jar而spring-context-4.2.4.RELEASE.jar中 有spring-beans-4.2.4.RELEASE.jar那么就会导致jar包冲突
解决方式:
(1)第一声明者优先原则,即谁先声明就使用谁,所以可以调整jar包依赖顺序
<!-- 此时项目中就会导入spring-beans-4.2.4.RELEASE.jar,因为spring-context-4.2.4.RELEASE.jar声明的早--> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.24</version> </dependency> </dependencies> 复制代码
(2)路径近者优先原则,即需要那个jar包那就直接自己引入,并指明版本,那么就会覆盖掉其他间接引起的jar包,也就是直接依赖优先于传递依赖。
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.24</version> </dependency> <!-- 直接引入指定的jar包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.4.RELEASE</version> </dependency> </dependencies> 复制代码
(3)排除依赖,<exclusions>标签排除间接依赖的jar包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> <!--排除jar包那么就会使用后声明的jar包即项目导入的是spring-beans-3.0.5.jar--> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.24</version> </dependency> </dependencies> 复制代码
(4)版本锁定,即指定项目中依赖的版本( 推荐 )
<!--此时就通过<dependencyManagement>标签指定了版本,那么即使spring-context-4.2.4.RELEASE.jar先声明也不会引起它集成的jar包--> <dependencyManagement> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>3.0.5.RELEASE</version> </dependency> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.24</version> </dependency> </dependencies> 复制代码
例如:cloud.jar
一、将外部jar包打入本地maven仓库
cmd进入到jar包所在的路径,执行以下命令
mvn install:install-file -Dfile=cloud.jar -DgroupId=com.hope.cloud -DartifactId=cloud -Dversion=1.0 -Dpackaging=jar 复制代码
然后在pom中引入jar包
<dependency> <groupId>com.hope.cloud</groupId> <artifactId>cloud</artifactId> <version>1.0</version> </dependency> 复制代码
二、使用maven的scope
<!--导入第三方jar包--> <dependency> <groupId>com.hope.cloud</groupId> <!--自定义--> <artifactId>cloud</artifactId> <!--自定义--> <version>1.0</version> <!--自定义--> <scope>system</scope> <!--system,类似provided,需要显式提供依赖的jar以后,Maven就不会在Repository中查找它--> <systemPath>${basedir}/lib/cloud.jar</systemPath> <!--项目根目录下的lib文件夹下--> </dependency> 复制代码
mvn clean:清理项目中的临时文件,target目录(target目录中存放的是编译后class文件) ,对应执行的是maven-clean-plugin jar包
mvn compile:编译项目即将.java文件编译成.class文件,生成target目录,对应执行的是maven-compile-plugin jar包
mvn test:执行单元测试,将项目根目录下src/test/java 目录下的单元测试类都会执行(注意:单元测试的类名必须是XxxTest.java格式)
mvn package:打包,根据项目打成什么包,web project打成war包,java project打成jar包,并且将包存放在target目录下,如果打成jar包用到了maven-jar-plugin,如果打成war包用到了maven-war-plugin。
mvn install:安装,将项目打包发布到本地仓库,项目中的一些组件可以打成jar包放在仓库中供多个项目使用。
mvn deploy:上传私服
mvn -v --version 显示版本信息
mvn -h --help 显示帮助信息
mvn -e --errors 控制maven的日志级别,产生执行错误相关信息
mvn -X --debug 控制maven的日志级别,产生执行调试信息
mvn -Dxxx=yyy 指定java全局属性
mvn -U 强制更新snapshot类型的插件或依赖库(否则maven一天只会更新一次snapshot依赖);
我们有时候打包不执行单元测试那么就可以通过命令跳过测试:
mvn package -DskipTests 不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下。
或者
mvn package -Dmaven.test.skip=true 不执行测试用例,也不编译测试用例类。
maven有三个内置的生命周期:清洁Clean Lifecycle、默认Default Lifecycle、站点Site Lifecycle
每一个生命周期都是独立的,比如我们使用mvn compile,那么只会执行Default Lifecycle中的流程,不会执行clean的操作,当然也可以mvn clean compile,那么就会先执行clean操作,再执行compile操作。
每一个生命周期内部,执行后面的操作,也会自动执行前面的流程,比如:mvn install那么就会将compile、test、package等前面流程都执行完之后才执行install操作。
对项目进行清理,包含三个阶段,命令mvn clean
流程 | 功能 |
---|---|
预清洁(pre-clean) | 执行实际项目清理之前所需的流程 |
清洁(clean) | 删除以前构建生成的所有文件 |
后清洁(post-clean) | 执行完成项目清理所需的流程 |
对项目进行构建,命令:mvn compile、mvn test、mvn package、mvn install、mvn deploy
流程 | 功能 |
---|---|
验证 (validate) |
验证项目是正确的,所有必要的信息可用。 |
初始化 (initialize) |
初始化构建状态,例如设置属性或创建目录。 |
产生来源 (generate-sources) |
生成包含在编译中的任何源代码。 |
流程源 (process-sources) |
处理源代码,例如过滤任何值。 |
生成资源 (generate-resources) |
生成包含在包中的资源。 |
流程资源 (process-resources) |
将资源复制并处理到目标目录中,准备打包。 |
编译 (compile) |
编译项目的源代码。 |
工艺类 (process-classes) |
从编译后处理生成的文件,例如对Java类进行字节码增强。 |
生成测试来源 (generate-test-sources) |
生成包含在编译中的任何测试源代码。 |
流程测试来源 (process-test-sources) |
处理测试源代码,例如过滤任何值。 |
生成测试资源 (generate-test-resources) |
创建测试资源。 |
流程测试资源 (process-test-resources) |
将资源复制并处理到测试目标目录中。 |
测试编译 (test-compile) |
将测试源代码编译到测试目标目录中 |
流程检验类 (process-test-classes) |
从测试编译中处理生成的文件,例如对Java类进行字节码增强。对于Maven 2.0.5及以上版本。 |
测试 (test) |
使用合适的单元测试框架运行测试。这些测试不应该要求代码被打包或部署。 |
制备包 (prepare-package) |
在实际包装之前,执行必要的准备包装的操作。这通常会导致打包的处理版本的包。(Maven 2.1及以上) |
打包 (package) |
采取编译的代码,并以其可分发的格式(如JAR)进行打包。 |
预集成测试 (pre-integration-test) |
在执行集成测试之前执行所需的操作。这可能涉及诸如设置所需环境等。 |
集成测试 (integration-test) |
如果需要,可以将该包过程并部署到可以运行集成测试的环境中。 |
整合后的测试 (post-integration-test) |
执行集成测试后执行所需的操作。这可能包括清理环境。 |
校验 (verify) |
运行任何检查以验证包装是否有效并符合质量标准。 |
安装 (install) |
将软件包安装到本地存储库中,以作为本地其他项目的依赖关系。 |
部署 (deploy) |
在集成或发布环境中完成,将最终软件包复制到远程存储库,以与其他开发人员和项目共享。 |
虽然默认生命周期有这么多阶段,其实对于构建项目只有几个特定阶段有意义,其他的只是中间作用,就是一个过客。不同的包对应不同的生命周期,比如jar包和war包就有区别。maven都是以插件的形式存在的,生命周期就是一个个不同的插件的组成。比如:jar包绑定的生命周期
流程资源(process-resources) | resources:resources | maven-resources-plugin |
---|---|---|
编译(compile) | compiler:compile | maven-compiler-plugin |
流程测试资源(process-test-resources) | resources:testResources | maven-resources-plugin |
测试编译(test-compile) | compiler:testCompile | maven-compiler-plugin |
测试(test) | surefire:test | maven-surefire-plugin |
打包(package) | jar:jar | maven-jar-plugin |
安装(install) | install:install | maven-install-plugin |
部署(deploy) | deploy:deploy | maven-deploy-plugin |
通过cmd我们就能看到流程的运行情况比如:
流程 | 功能 |
---|---|
预网站(pre-site) | 在实际的项目现场生成之前执行所需的进程 |
网站(site) | 生成项目的站点文档 |
后网站(post-site) | 执行完成站点生成所需的进程,并准备站点部署 |
网站部署(site-deploy) | 将生成的站点文档部署到指定的Web服务器 |
maven的概念模型就是对maven的两大核心(依赖管理和项目构建)的描述,maven根据pom文件将它转成项目对象模型(POM),通过依赖管理从仓库中获取需要的jar包,项目的构建可以通过命令实现,其底层是一个个插件Pulg-in,它们在执行过程中会产生一些中间文件,比如:compiler会将.java文件编译成.class文件,供后续打包使用。