Maven简介
Maven简介
什么是Maven
Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)
如图蓝色部分为 Maven,其不包括外部其他部分,上部分为核心,下部分为各种插件。Maven 的作用如下
- 项目构建: 提供标准的、跨平台的自动化项目构建方式
- 依赖管理: 方便快捷的管理项目依赖的资源包,避免资源之间的版本冲突问题
- 统一开发结构: 规定了
src、resource、target等统一项目结构

Maven 是由 Java 语言编写的,同样采用了面向对象的思想
Maven安装
- 点击进入
Maven官网进行下载 maven.apache.org/ - 解压文件到没有空格、没有中文的目录下
- 【可选】打开
maven目录/conf/settings.xml配置文件,配置阿里镜像地址(配置到<mirrors>标签里)
【可选】配置环境变量:新建 MAVEN_HOME:Maven根目录,修改Path添加 %MAVEN_HOME%\bin (注意:Maven 依赖环境变量中有 JAVA_HOME),CMD输入 mvn -v 验证
【可选】因为Java默认的最大可用内存往往不够满足Maven运行需要,比如较大的项目时,使用Maven生成项目站点需要占用大量内存,可选配置 MAVEN_OPTS:-Xms128m -Xmx512m
注意 Maven 是由 Java 研发的,所以 Maven 依赖 Java
Maven概念
仓库概念:仓库用于存储资源(各种 Jar 包),其分为本地仓库、远程仓库、中央仓库
- 本地仓库: 自己电脑上存储资源的仓库
- 远程仓库: 也叫作
Maven私服,部门/公司范围内储存资源的仓库 - 中央仓库:
Maven团队维护的,维护所有资源的仓库
坐标概念:坐标用于描述仓库中资源的位置,其构成部分及说明如下:
gourpId`:组织名,定义该 `Maven` 项目隶属组织,常是域名反写,如 `org.example.demo
artifactId:项目名,定义该 Maven 项目名称
version:版本号,定义该 Maven 项目的版本号
packaging:定义项目的打包方式,如成果物类型 war 或 jar,如组织项目的 pom 类型
Jar 包的获取会逐级搜索,如本地仓存在则直接使用本地仓,如不存在则到远程仓获取。以此类推
Maven使用
生命周期命令
生命周期命令
| 命令 | 说明 |
|---|---|
mvn archetype:generate | 创建 Maven 项目,可通过参数指定坐标等 可以使用骨架:常用7号 quickstart 普通项目,10号 webappWEB 项目 |
mvn clean | 把已经编译好的项目的所有信息清除(target 文件夹) |
mvn compile | 自动导入 POM 中的依赖,并把核心代码部分编译后,放置在 target 目录下 |
mvn test | 通过此命令可以执行 test 文件夹下的测试用的内容,实现项目测试(同时执行了 compile) |
mvn package | 将 Maven 项目进行打包,放置在 target 目录下(同时执行了 test) |
mvn install | 将刚刚项目打完的包安装到本地仓库,由 maven 进行管理(同时执行了 package) |
mvn deploy | 项目发布,将 maven 本地库中管理的资源发布到远程库中 |
POM文件结构
<!--当前项目的maven资源坐标-->
<groupId>org.example</groupId>
<artifactId>MVNDemo01</artifactId>
<version>1.0-SNAPSHOT</version><!--此项目在mvn package的过程中,要打成什么样的包,通常是jar或war,也可能是pom-->
<packaging>jar</packaging><!-- 项目相关信息 -->
<name>MVNDemo01</name>
<description>xxx</description>
<url>http://maven.apache.org</url><!-- 参数配置 -->
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties><!-- 依赖管理 -->
<dependencies><dependency></dependency>
</dependencies><!-- 依赖版本管理 -->
<dependencyManagement>
</dependencyManagement><!-- 项目构建 -->
<build><plugins><plugin></plugin></plugins>
</build>
依赖传递
依赖是可以传递的,很有可能会发生依赖传递冲突问题,其优先级如下:
- 路径优先: 当依赖中出现相同的资源时(可能版本号不同),层级越浅,优先级越高
- 声明优先: 当资源在相同层级被依赖时,配置顺序考前的覆盖配置顺序靠后的
- 特殊优先: 当在同
POM文件中声明时,后配置的覆盖先配置的
处理依赖传递有如下两种标签:
- 可选依赖: 控制引用该资源的项目无法看到该依赖
- 排除依赖: 主动排除掉该资源中的指定依赖
<dependency><groupId>org.springframework</groupId><artifactId>springboot</artifactId><version>1.1</version><!-- 可选依赖(默认false,可传递) --><optional>true</optional><!-- 排除依赖 --><exclusions><exclusion><groupId>org.springframework</groupId><artifactId>bbb</artifactId></exclusion></exclusions>
</dependency>
依赖范围
依赖范围: 可以通过 <scope> 标签指定其依赖范围,其作用如下:
| scope | 编译 | 测试 | 打包 | 范例 |
|---|---|---|---|---|
| compile(默认) | Y | Y | Y | log4j |
| test | Y | junit(仅测试使用) | ||
| provided | Y | Y | 不传递 | servlet-api(Tomcat中包含) |
| runtime | Y | jdbc(可防止编写时意外导入) | ||
| system | Y | Y | 插件配置 includeSystemScope | 依赖来自本地系统,需要配合标签 systemPath 使用 |
| import | 引入依赖项目,配合 <type>pom</type> 使用 |
依赖范围具有传递性,开发时根据实际情况使用
插件使用
插件的使用可以通过官网查询,不同插件有不同使用方式,根据文档说明进行操作。如下简单示例源码插件配置
xml复制代码<build><plugins><!-- 使用具体插件 --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.3.RELEASE</version><!-- 配置执行条件/位置:具体使用参考插件文档 --><executions><execution><!-- 操作目标,如下为主代码及test代码 --><goals><goal>jar</goal><goal>test-jar</goal></goals><!-- 插件执行阶段(生命周期哪个阶段) --><phase>generate-resources</phase></execution></executions></plugin></plugins>
</build>
多模块管理
Model聚合
聚合用于快速构建 Maven 工程,一次性构建多个项目/模块。如多个项目/模块依赖,执行命令时需要每一个工程都进行编译,打包,安装,测试,部署等生命周期的命令,一个一个去执行这些命令效率非常低
Maven 提供了聚合的配置,实现统一执行命令,实现方法:创建一个无代码聚合工程,并在 POM 中配置所有聚合的项目/模块
xml复制代码<!-- 打包类型为聚合 -->
<packaging>pom</packaging>
<!-- 配置模块名称 -->
<modules><!-- 标签内部值为子模组pom.xml所在路径 --><!-- 表示与自己同级的child1项目目录 --><module>../child1</module><!-- 表示为自己目录下child2项目目录 --><module>child2</module></modules>
只是聚合项目关心有什么模块,模块不需要知道被谁聚合了
Maven继承
Maven 项目提供继承的特性,可以利用继承实现所有项目资源版本统一的问题。其继承的父类资源包括:
| 继承项 | 说明 |
|---|---|
groupId version | 项目相关的内容。可以重写,默认父类的值 |
properties | 父级工程在 properties 标签中定义的变量,子工程使用 ${} 使用 |
dependencies | 相当于强制继承,子工程中一定被导入父工程该标签内的 Jar 包 |
dependencyManagement | 常用的一种统一资源的继承方式,只会继承版本而不会强制让子工程依赖资源 子工程通过在 dependency 内添加 groupId 和 artifactId 即可,当然也可以重写 version 版本号 |
build pluginManagement | 如上的一种统一资源的继承方式,其使用如上,不仅继承版本号,还会继承声明的使用方式 |
继承的实现需要子项目声明父项目,注意 Maven 是单继承,其声明方式如下:
xml复制代码<!-- 定义工程的父工程 -->
<parent><groupId>org.example.parent</groupId><artifactId>demo-parent</artifactId><version>1.0.0.RELEASE</version><!-- 填写父工程的POM位置,省略不写视为在父工程内/父工程为远程项目,仓库获取 --><relativePath>../parent/pom.xml</relativePath>
</parent>
只是子项目声明了父项目是谁,父项目不需要知道被谁继承了
属性管理
Maven 提供属性管理,其管理方式属性类型有:自定义属性、内置属性、Setting属性、Java系统属性、环境变量属性
xml复制代码<!-- 定义自定义属性 -->
<properties><mybatis-plus.version>3.1.2</mybatis-plus.version><druid.version>1.1.17</druid.version>
</properties><!-- 使用自定义属性 -->
<version>${druid.version}</version><!-- 内置属性:含 ${basedir} ${version} 等 --><!-- Setting属性:配置文件 setting.xml 中的标签属性,属于动态属性,如 ${settings.localRepository} 等 --><!-- Java系统属性、环境变量属性:通过命令 mvn help:system 可以获取到属性 -->
Maven 提供资源加载属性值功能,其为项目内的其他资源文件使用定义的自定义属性,调用方式相同 ${} 使用如下
xml复制代码<!-- 定义哪个文件夹下文件开启POM属性过滤功能,检测到 ${} 就替换属性 -->
<build><resources><resource><directory>${project.basedir}/src/main/resources</directory><filtreing>true<filtering></resource></resources>
</build>
版本管理含
RELEASE和SNAPSHOT,正式版、快照版
Maven可以进行多环境配置参数,通过打包命令添加参数完成,可了解一下
Maven私服
【Nexus】为常用私服,安装及使用绕道参考
常用插件使用
JDK版本
更改编译 Java 源码的 jdk 版本
xml复制代码<!-- 通过更改项目的 pom.xml,添加 java 编译插件 -->
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target><encoding>utf-8</encoding></configuration></plugin></plugins>
</build><!-- 或者在 properties 设置 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>
更改 Maven 默认的 JDK 版本,更改 Maven 目录下的 conf/settings.xml 文件,以后建立的项目源码编译都是指定的 jdk 版本
xml复制代码<profile><id>jdk-1.8</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>
各种常用插件
xml复制代码<!-- Spring项目打包插件:可能和 appassembler-maven-plugin 不兼容 -->
<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>
</plugin><!-- 测试插件:不写进行默认测试,这里配置了该插件跳过测试 -->
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><skipTests>true</skipTests></configuration>
</plugin><!-- 应用不部署到远程仓库中 -->
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><configuration><skip>true</skip></configuration>
</plugin>
Appassembler打包
Appassembler 打包有三种核心打包方式,其中常用打包为可执行程序和守护服务方式。如下介绍最为常用的守护方式,该方式可生成资源后直接在服务器中运行为服务
Appassembler 打包方式的优点:
- 通过
wrapper方式进行管理,直接运行bin/下的可执行文件start | stop | console | restart - 分包管理
lib依赖,其打包方式不会将所有依赖打包到一个可执行文件中,分包管理,方便更改部分jar包代码,进行部分更新 - 管理资源文件,可以通过设置,让程序首先使用
conf/文件夹下的资源/配置文件,当找不到时才找jar包内资源 - 当更新程序时,操作步骤更为简单:
- 把需要更新的
jar包覆盖到lib/下 - 保证是否需要更新配置文件
conf/ - 运行可执行文件
xxx restart重启服务
xml复制代码<!-- 使用说明: -->
<!-- 1. 修改对应的项目名称 -->
<!-- 2. 修改属性值,输出文件夹目录 -->
<!-- 3. 修改启动类,如下 mainClass 标签 --><!-- 配置项目名称及属性,后期配置使用 -->
<name>demo</name>
<properties><appassembler.out.name>appassembler-out</appassembler.out.name>
</properties><plugin><groupId>org.codehaus.mojo</groupId><artifactId>appassembler-maven-plugin</artifactId><version>2.1.0</version><!-- 配置插件启动时机 --><executions><execution><phase>package</phase><goals><goal>generate-daemons</goal></goals></execution></executions><configuration><!-- 打包后生成的目录位置及各目录 --><target>${project.build.directory}/${appassembler.out.name}</target><binFolder>bin</binFolder><logsDirectory>logs</logsDirectory><repositoryName>lib</repositoryName><!-- 为系统配置文件指定一个目录 --><configurationDirectory>conf</configurationDirectory><!-- 源代码中对应的系统配置文件的位置 --><configurationSourceDirectory>src/main/resources</configurationSourceDirectory><!-- 是否将配置文件包含到classpath --><includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath><!-- 是否拷贝源代码中配置文件中的目录 --><copyConfigurationDirectory>true</copyConfigurationDirectory><!-- 依赖的lib包的目录格式,flat表示不分目录平铺到lib目录下 --><repositoryLayout>flat</repositoryLayout><daemons><daemon><!-- 基本信息配置:名称及启动类 --><id>${project.name}</id><mainClass>org.example.Starter</mainClass><!-- JVM配置设置 --><jvmSettings><maxStackSize>128</maxStackSize><extraArguments><extraArgument>-server</extraArgument><extraArgument>-XX:+AggressiveOpts</extraArgument><extraArgument>-Xmx1G</extraArgument><extraArgument>-XX:+HeapDumpOnOutOfMemoryError</extraArgument></extraArguments></jvmSettings><!-- 打包平台配置 --><platforms><platform>jsw</platform></platforms><generatorConfigurations><generatorConfiguration><generator>jsw</generator><includes><!-- include>linux-x86-32</include --><!-- include>linux-ppc-64</include --><include>linux-x86-64</include><include>windows-x86-64</include></includes><configuration><!-- 手动添加一个系统启动时依赖的第一个classpath,这里通常写为配置文件的目录名,如果不配置,配置文件无法找到 --><property><name>configuration.directory.in.classpath.first</name><value>conf</value></property><!-- 依赖jar包位置 --><property><name>set.default.REPO_DIR</name><value>lib</value></property><!-- 日志文件位置 --><property><name>wrapper.logfile</name><value>logs/wrapper-${project.name}.log</value></property><!-- 日志文件格式:MB兆的方式格式 --><property><name>wrapper.logfile.format</name><value>M</value></property><!-- 日志文件最大值:10MB --><property><name>wrapper.logfile.maxsize</name><value>10m</value></property><!-- 日志文件最大分割值:5 --><property><name>wrapper.logfile.maxfiles</name><value>5</value></property><!-- 配置Windows服务:效果未检测 --><property><name>wrapper.ntservice.interactive</name><value>true</value></property></configuration></generatorConfiguration></generatorConfigurations></daemon></daemons></configuration>
</plugin>
该插件可能与
Spring Boot打包插件冲突,如出现找不到主类清单错误,可选择注释掉Spring Boot打包插件(spring-boot-maven-plugin)
Assembly打包
Assembly 打包是 Maven 提供的一种打包方式,可以输出自定义的包类型。如上输出守护服务的资源后,可以再通过该插件进行打包输出
xml复制代码<!-- 集合打包插件 -->
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><executions><execution><phase>package</phase><goals><!-- 只执行一次 --><goal>single</goal></goals></execution></executions><configuration><!-- 描述文件所在位置 --><descriptors><descriptor>src/main/assembly/assembly-linux.xml</descriptor><descriptor>src/main/assembly/assembly-win.xml</descriptor></descriptors></configuration>
</plugin>
描述文件用于描述输出文件,如下输出两个压缩文件(文件内容来自上个插件的输出结果)
xml复制代码<!-- src/main/assembly/assembly-linux.xml -->
<assemblyxmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"><id>linux</id><includeBaseDirectory>false</includeBaseDirectory><formats><format>tar.gz</format></formats><fileSets><fileSet><directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/bin</directory><outputDirectory>${project.name}/bin</outputDirectory><fileMode>0755</fileMode><includes><include>${project.name}</include><include>wrapper-linux*</include></includes></fileSet><fileSet><directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/lib</directory><outputDirectory>${project.name}/lib</outputDirectory><includes><include>*.jar</include><include>libwrapper-linux*</include></includes></fileSet><fileSet><directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/conf</directory><outputDirectory>${project.name}/conf</outputDirectory><includes><include>*.yml</include><include>banner.txt</include><include>wrapper.conf</include></includes></fileSet><fileSet><directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/logs</directory><outputDirectory>${project.name}/logs</outputDirectory><excludes><exclude>**/*</exclude></excludes></fileSet></fileSets>
</assembly>
xml复制代码<!-- src/main/assembly/assembly-win.xml -->
<assemblyxmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"><id>win</id><includeBaseDirectory>false</includeBaseDirectory><formats><format>zip</format></formats><fileSets><fileSet><directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/bin</directory><outputDirectory>${project.name}/bin</outputDirectory><fileMode>0755</fileMode><includes><include>${project.name}</include><include>wrapper-windows*</include></includes></fileSet><fileSet><directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/lib</directory><outputDirectory>${project.name}/lib</outputDirectory><includes><include>*.jar</include><include>libwrapper-windows*</include></includes></fileSet><fileSet><directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/conf</directory><outputDirectory>${project.name}/conf</outputDirectory><includes><include>*.yml</include><include>banner.txt</include><include>wrapper.conf</include></includes></fileSet><fileSet><directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/logs</directory><outputDirectory>${project.name}/logs</outputDirectory><excludes><exclude>**/*</exclude></excludes></fileSet></fileSets>
</assembly>
资源打包插件
Maven 项目默认资源在 src/main/resources 目录下,如果资源不在此目录下,需要添加 maven-resources-plugin 插件,并在 resource 中配置资源路径
xml复制代码<!-- 资源打包插件 -->
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId>
</plugin><!-- 配合 resources 插件添加资源目录 -->
<resources><resource><directory>src/main/resources</directory><!-- 打开变量替换声明 --><!-- filtering>true</filtering --></resource><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource>
</resources>
Tomcat插件
下面介绍的是 tomcat7 插件在 pom.xml 文件中的配置,端口默认是 8080,path 默认是项目名称(可以在 configuration 标签内进行修改)。执行命令 mvn tomact7:run 运行
xml复制代码<!-- 构建 -->
<build><plugins><!-- 添加tomcat服务器插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><!-- 配置tomcat端口 --><port>8080</port><!-- Web应用的访问路径<path>HelloWorld</path>--><!-- 配置tomcat编码,解决GET乱码 --><uriEncoding>UTF-8</uriEncoding></configuration> </plugin></build>
</plugins>
使用技巧
清理小工具
Maven 本地仓库同步的时候会产生很多不存在的 Jar 包下载准备文件,可以通过该命令行脚本进行清理,保存到 .bat 文件中,在 windows 双击使用
bash复制代码set REPOSITORY_PATH=E:\MavenRepo
rem 正在搜索...
for /f "delims=" %%i in ('dir /b /s "%REPOSITORY_PATH%\*lastUpdated*"') do (del /s /q %%i
)
rem 搜索完毕
pause