Maven

基本概念

Maven是一个项目管理工具,涉及:

  • 构建(build)

  • 报告(reporting)

  • 文档的生成(documentation)

  • 依赖(Dependencies)

  • 软件配置管理(SCMs)

  • Releases

  • Distribution

 

遵循约定大于配置。例如按Maven的约定编写好测试用例后,即可在构建过程中自动运行测试用例。

完全基于插件,通过调用不同的插件实现要实现的功能。

 

安装

  1. 下载解压

  2. 添加路径

vi ~/.bash_profile

export M2_HOME=/Users/xxx/DevInstall/apache-maven-3.6.2
export PATH=$PATH:$M2_HOME/bin

source ~/.bash_profile
  1. 查看版本

mvn -v

 

常用命令

mvn -h

# 打包指定模块
mvn pakcage -pl groupId:artifactId1,groupId:artifactId1

# 打包指定模块及其依赖模块
mvn pakcage -pl groupId:artifactId1,groupId:artifactId1 -am

# 打包指定模块、依赖模块、被依赖模块
mvn pakcage -pl groupId:artifactId1,groupId:artifactId1 -amd

 

生命周期

  • Maven将构建(build)和发布(distribute)的过程称为一个生命周期(build lifecycle),maven有三个内置的生命周期:clean、default、site。生命周期定义了各个构建环节的执行顺序。Maven有三套相互独立的生命周期,相互独立的,可以分别调用,也可以一起调用。

  • 每套生命周期都由一组阶段(Phase)组成,如default包含validate、compile、test、package、install、deploy等。不同的phase是由不同的plugin实现功能,(phase由plugin goal组成),如compile阶段由Compiler插件实现,Compiler插件包含compile:compile、compile:help、compile:testCompile 3个goal

  • 通过命令行调用不同的phase实现不同阶段的构建目标

# 获取jar包
maven package

# 执行单元测试
mvn test
  • 当执行一个phase时,Maven会依顺序依次执行当前lifecycle中的所有phase,直至目标phase。

# 执行validate compile test package verify
mvn verify

# clean和package是phase,dependency:copy-dependencies是插件的goal
# 会依次执行 clean前的所有phase、clean phase、dependency的copy-dependencie goal、package前的所有phase、package phase
mvn clean dependency:copy-dependencies package

# 忽略失败的测试
mvn test -Dmaven.test.failure.ignore=true

# 不执行测试用例,也不编译测试用例类
mvn package -Dmaven.test.skip=true

# 不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下
mvn package -DskipTests
  • 多项目情况下,Maven会在每个子项目中执行相同的命令。

  • 部分phase无法直接通过命令行调用,例如带有pre-、post-、process-前缀的的phase,只会在顺序执行的过程中被调用并生成中间结果供使用。

  • 一个phase负责lifecycle中的特定阶段,其具体功能通过绑定不同的plugin goal实现。plugin goal负责构建过程中更精细的任务,一个phase可以绑定0到多个goal。

 

clean lifecycle

进行项目的清理

PhaseDescription
pre-clean execute processes needed prior to the actual project cleaning
clean remove all files generated by the previous build
post-clean execute processes needed to finalize the project cleaning

 

default lifecycle

进行项目的构建。主要包含以下phase:

  • validate:确认项目信息正确且完整

  • compile: 编译源代码

  • test: 执行单元测试

  • pakcage: 将编译后的代码打包

  • verify: 根据Verifications文件中的表达式验证集成测试的结果

  • install: 将构建制品安装到本地仓库,用于本地其它项目的使用

  • deploy: 将构建制品发布到远程仓库

PhaseDescription
validate validate the project is correct and all necessary information is available.
initialize initialize build state, e.g. set properties or create directories.
generate-sources generate any source code for inclusion in compilation.
process-sources process the source code, for example to filter any values.
generate-resources generate resources for inclusion in the package.
process-resources copy and process the resources into the destination directory, ready for packaging.
compile compile the source code of the project.
process-classes post-process the generated files from compilation, for example to do bytecode enhancement on Java classes.
generate-test-sources generate any test source code for inclusion in compilation.
process-test-sources process the test source code, for example to filter any values.
generate-test-resources create resources for testing.
process-test-resources copy and process the resources into the test destination directory.
test-compile compile the test source code into the test destination directory
process-test-classes post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes.
test run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed.
prepare-package perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package.
package take the compiled code and package it in its distributable format, such as a JAR.
pre-integration-test perform actions required before integration tests are executed. This may involve things such as setting up the required environment.
integration-test process and deploy the package if necessary into an environment where integration tests can be run.
post-integration-test perform actions required after integration tests have been executed. This may including cleaning up the environment.
verify run any checks to verify the package is valid and meets quality criteria.
install install the package into the local repository, for use as a dependency in other projects locally.
deploy done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

 

site lifecycle

用于创建项目的站点文档

PhaseDescription
pre-site execute processes needed prior to the actual project site generation
site generate the project's site documentation
post-site execute processes needed to finalize the site generation, and to prepare for site deployment
site-deploy deploy the generated site documentation to the specified web server

 

使用build lifecycle

配置packaging

在不同的packaging下lifecycle有不同的goal绑定。

Default Lifecycle Bindings - Packaging ejb / ejb3 / jar / par / rar / war

Phaseplugin:goal
process-resources resources:resources
compile compiler:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
install install:install
deploy deploy:deploy

Default Lifecycle Bindings - Packaging pom

Phaseplugin:goal
package  
install install:install
deploy deploy:deploy

配置plugin

通过配置好的插件提供goal给maven执行。

 

插件

  • Maven 的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。

  • 每个插件都能实现多个功能,每个功能就是一个插件目标。

  • 当需要自定义构建过程时需要配置插件

 

分为两种类型

  • Build plugins will be executed during the build and they should be configured in the <build/> element from the POM.

  • Reporting plugins will be executed during the site generation and they should be configured in the <reporting/> element from the POM.

 

通用配置

mojo

显示指定版本号可以保证构建的稳定,推荐在pluginManagement中指定。

通过<configuration>标签进行配置,<configuration>标签的子标签与Mojo的字段一一对应(a Mojo maps to a goal)。

help goal

mvn javadoc:help -Ddetail -Dgoal=javadoc

参数类型

基础类型

对象类型

集合

map

build插件配置项

executions

使用executions标签,指定插件参与生命周期中的特定phases

未指定phase参与插件goal的默认phase

无默认phase则不参与build过程

绑定多个phase会执行多次

execution标签内的configurations只在当前phase生效

 

dependencies

指定build时的依赖

 

inherited

指定configurations是否继承,默认true

 

report插件配置项

reportSets

inherited

 

可用插件

http://maven.apache.org/plugins/index.html):

Core plugins:

clean

compiler

deploy

failsafe:在独立的classloader中执行集成测试

install

resources

site

surefire:在独立的classloader中执行单元测试

verifier:验证指定情况是否存在,集成测试下使用

 

Packaging types/tools:

jar

war

 

Reporting plugins

changelog:修改日志

checkstyle:风格检查

surefire-report:根据单元测试的结果生成报告

 

Tools

archetype:创建一个项目骨架

 

surefire

单元测试插件

By default the tests included are:

  • **/*Test.java

  • **/Test*.java

  • **/*TestCase.java

And the default excludes are:

  • **/Abstract*Test.java

  • **/Abstract*TestCase.java

 

<!-- 多线程执行 -->
<plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-surefire-plugin</artifactId>
               <configuration>
                   <parallel>methods</parallel>
                   <threadCount>10</threadCount>
               </configuration>
           </plugin>

 

failsafe

集成测试插件

如何使用

多级项目的使用

 

        <plugins>
<!-- 独立的集成测试目录 -->
           <plugin>
               <groupId>org.codehaus.mojo</groupId>
               <artifactId>build-helper-maven-plugin</artifactId>
               <executions>
                   <execution>
                       <id>add-it-source</id>
                       <phase>generate-test-sources</phase>
                       <goals>
                           <goal>add-test-source</goal>
                       </goals>
                       <configuration>
                           <sources>
                               <source>src/it/java</source>
                           </sources>
                       </configuration>
                   </execution>
                   <execution>
                       <id>add-it-resource</id>
                       <!--<phase>pre-integration-test</phase>-->
                       <phase>generate-test-resources</phase>
                       <goals>
                           <goal>add-test-resource</goal>
                       </goals>
                       <configuration>
                           <resources>
                               <resource>
                                   <directory>src/it/resources</directory>
                               </resource>
                           </resources>
                       </configuration>
                   </execution>
               </executions>
           </plugin>
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-failsafe-plugin</artifactId>
               <executions>
                   <execution>
                       <id>integration-test</id>
                       <goals>
                           <goal>integration-test</goal>
                       </goals>
                   </execution>
                   <execution>
                       <id>verify</id>
                       <goals>
                           <goal>verify</goal>
                       </goals>
                   </execution>
               </executions>
           </plugin>
       </plugins>
# 执行集成测试
mvn verify

 

https://maven.apache.org/surefire/maven-failsafe-plugin/index.html

 

build-helper-maven-plugin

指定额外的源码路径和资源路径。

例如指定单独文件夹下的集成测试代码。

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>build-helper-maven-plugin</artifactId>
   <version>1.5</version>
   <executions>
       <execution>
           <id>add-test-source</id>
           <phase>process-resources</phase>
           <goals>
               <goal>add-test-source</goal>
           </goals>
           <configuration>
               <sources>
                   <source>src/it/java</source>
               </sources>
           </configuration>
       </execution>
   </executions>
</plugin>

http://www.mojohaus.org/build-helper-maven-plugin/plugin-info.html

 

spring-boot-maven-plugin

对maven package打好的包重新打包成可执行的jar包,包含所有的依赖,可以使用java -jar直接运行。

  • spring-boot:repackage,默认goal。在mvn package之后,再次打包可执行的jar/war,同时保留mvn package生成的jar/war为.origin

  • spring-boot:run,运行Spring Boot应用

  • spring-boot:start,在mvn integration-test阶段,进行Spring Boot应用生命周期的管理

  • spring-boot:stop,在mvn integration-test阶段,进行Spring Boot应用生命周期的管理

  • spring-boot:build-info,生成Actuator使用的构建信息文件build-info.properties

https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/html/

 

maven-dependency-plugin

指定jar包到lib目录缩小jar包体积

 

maven-jar-plugin

 

 

仓库

  • 本地仓库:为当前本机电脑上的所有 Maven 工程服务。

  • 远程仓库-私服:架设在当前局域网环境下,为当前局域网范围内的所有 Maven 工程服务,如Nexus。

  • 远程仓库-中央仓库:架设在 Internet 上,为全世界所有 Maven 工程服务。

  • 远程仓库-中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。为当前本机电脑上的所有 Maven 工程服务。

 

依赖

当 A jar 包用到了 B jar 包中的某些类时,A 就对 B 产生了依赖

坐标

使用如下三个向量在 Maven 的仓库中定位一个 Maven 工程。

  1. groupid:公司或组织的域名倒序+当前项目名称

  2. artifactId:当前项目的模块名称

  3. version:当前模块的版本

<groupId>org.apache.maven</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>

 

使用dependency标签实现依赖

<dependency>    
 <groupId>org.apache.maven</groupId>
 <artifactId>project</artifactId>
 <version>0.0.1-SNAPSHOT</version>  
<scope>compile</scope>
</dependency>

对于自己开发的Maven工程,使用mvn install命令后就会安装到本地仓库

 

依赖的范围

compile

默认作用域,被所有依赖项目引用。

This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.

provided

仅编译和测试有效,不参与打包,正式环境提供相关依赖,不具有传递性。

This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. A dependency with this scope is added to the classpath used for compilation and test, but not the runtime classpath. It is not transitive.

runtime

仅执行阶段生效

This scope indicates that the dependency is not required for compilation, but is for execution. Maven includes a dependency with this scope in the runtime and test classpaths, but not the compile classpath.

test

仅测试阶段生效,不参与打包,正式环境不包含相关依赖,不具有传递性,如测试框架Junit和Mockito或仅测试时使用的依赖。

This scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases. This scope is not transitive. Typically this scope is used for test libraries such as JUnit and Mockito. It is also used for non-test libraries such as Apache Commons IO if those libraries are used in unit tests (src/test/java) but not in the model code (src/main/java).

system

类似provided,但是必须手动提供jar包,相关依赖不在仓库中。

This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.

import

仅pom中有效,引入其他pom

This scope is only supported on a dependency of type pom in the section. It indicates the dependency is to be replaced with the effective list of dependencies in the specified POM's section. Since they are replaced, dependencies with a scope of import do not actually participate in limiting the transitivity of a dependency.

 

依赖的传递性

A依赖B,B依赖C,若C的依赖范围是compile的则A可以依赖C

 

排除依赖

使用exclusion标签

 

统一管理所依赖jar包的版本

 

依赖冲突

遵循原则:

  1. 路径最短者优先,例如a-b-c1.0和a-e-f-g-c1.1,会优先使用前者较短的路径

  2. 路径相同者先声明者优先,例如a-b-c1.0和a-e-c.1.1会使用先声明的版本

使用mvn dependency:tree可以查看依赖树

 

解决冲突:

  1. 修改引入顺序

  2. 使用exclusion排除某个依赖

 

配置

POM

Project Object Model:项目对象模型。

Maven 工程的核心配置,将Java工程的相关信息封装为对象作为便于操作和管理的模型。

  • 配置项目信息

  • 配置依赖

  • 配置插件、goal

  • 配置profile等

 

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>

 <!-- The Basics -->
 <groupId>...</groupId>
 <artifactId>...</artifactId>
 <version>...</version>
 <packaging>...</packaging>
 <dependencies>...</dependencies>
 <parent>...</parent>
 <dependencyManagement>...</dependencyManagement>
 <modules>...</modules>
 <properties>...</properties>

 <!-- Build Settings -->
 <build>...</build>
 <reporting>...</reporting>

 <!-- More Project Information -->
 <name>...</name>
 <description>...</description>
 <url>...</url>
 <inceptionYear>...</inceptionYear>
 <licenses>...</licenses>
 <organization>...</organization>
 <developers>...</developers>
 <contributors>...</contributors>

 <!-- Environment Settings -->
 <issueManagement>...</issueManagement>
 <ciManagement>...</ciManagement>
 <mailingLists>...</mailingLists>
 <scm>...</scm>
 <prerequisites>...</prerequisites>
 <repositories>...</repositories>
 <pluginRepositories>...</pluginRepositories>
 <distributionManagement>...</distributionManagement>
 <profiles>...</profiles>
</project>

 

parent

配置父级项目。relativePath用于指定父级项目相对路径,默认为上一级文件夹。

父级项目配置package类型为pom和modules

这样所有在父级项目执行的命令都会在自己项目中执行

 

properties

预定义变量。

  • project.*

  • project.basedir

  • project.baseUri

  • maven.build.timestamp

 

profiles

配置文件多版本

dependencies

依赖管理。涉及坐标、作用域、exclusion等

 

dependencyManagement

对所依赖jar包进行统一版本管理的管理器

  • 如果dependencies里的dependency自己没有声明version元素,那么maven就会到dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明,如果有,就继承它,如果没有就会报错,告诉你必须为dependency声明一个version

  • 如果dependencies中的dependency声明了version,那么无论dependencyManagement中有无对该jar的version声明,都以dependency里的version为准。

 

build

分为project build和profile build

  • defaultGoal

  • directory:输出目录,默认${basedir}/target

  • finalName:制品名称,默认{version}

  • filter:定义*.properties的resources过滤器,可以在资源文件被复制到目标目录的同时,替换其中的placeholders。

 

Resources
  • resources: is a list of resource elements that each describe what and where to include files associated with this project.

  • targetPath: Specifies the directory structure to place the set of resources from a build. Target path defaults to the base directory. A commonly specified target path for resources that will be packaged in a JAR is META-INF.

  • filtering: is true or false, denoting if filtering is to be enabled for this resource. Note, that filter *.properties files do not have to be defined for filtering to occur - resources can also use properties that are by default defined in the POM (such as ${project.version}), passed into the command line using the "-D" flag (for example, "-Dname=value") or are explicitly defined by the properties element. Filter files were covered above.

  • directory: This element's value defines where the resources are to be found. The default directory for a build is ${basedir}/src/main/resources.

  • includes: A set of files patterns which specify the files to include as resources under that specified directory, using * as a wildcard.

  • excludes: The same structure as includes, but specifies which files to ignore. In conflicts between include and exclude, exclude wins.

  • testResources: The testResources element block contains testResource elements. Their definitions are similar to resource elements, but are naturally used during test phases. The one difference is that the default (Super POM defined) test resource directory for a project is ${basedir}/src/test/resources. Test resources are not deployed.

 

Plugins

 

pluginManagement

plugin的详细配置,供子项目继承,但只有在子项目中明确引用后才会生效

 

repositories

 

 

 

Settings.xml

The settings element in the settings.xml file contains elements used to define values which configure Maven execution in various ways, like the pom.xml, but should not be bundled to any specific project, or distributed to an audience.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                         https://maven.apache.org/xsd/settings-1.0.0.xsd">
     <localRepository/> 本地仓库地址
     <interactiveMode/> 交互模式
     <offline/> 离线模式
     <pluginGroups/> 默认plugin groupId
     <servers/> repositories and distributionManagement服务器
     <mirrors/> 镜像,central表示中央仓库
     <proxies/> 代理
     <profiles/> 配置文件
     <activeProfiles/> 激活的配置文件
   </settings>

 

目录结构

  • src

src/main/javaApplication/Library sources
src/main/resources Application/Library resources (the structure which is copied to the target classpath given the default resource definition)
src/main/filters Resource filter files
src/main/webapp Web application sources
src/test/java Test sources
src/test/resources Test resources
src/test/filters Test resource filter files
src/it Integration Tests (primarily for plugins)
src/assembly Assembly descriptors
src/site Site
LICENSE.txt Project's license
NOTICE.txt Notices and attributions required by libraries that the project depends on
README.txt Project's readme
  • target:存放构建后的文件和目录,jar包、war包、class文件

  • pom.xml

 

版本管理

SNAPSHOT后缀的表示开发版本,意味着代码随时可能变化

不带SNAPSHOT后缀的表示发布版本,保证代码不会再变化,每次发布不带后缀的版本后意味着SNAPSHOT版本号加1。

 

posted @ 2020-08-05 00:11  purified  阅读(143)  评论(0编辑  收藏  举报