Maven
一、初识Maven
1、传统管理缺点
传统开发项目的问题,没有使用maven管理的项目,你需要自己做以下事情
1)管理工程模块,模块之间的关系
2)管理第三方功能
需要很多jar文件,需要手工从网络中获取各个jar
3)管理jar的版本
你需要的是mysql.5.1.5.jar 拿你不能给给一个mysql.4.0.jar
4)管理jar文件之间的依赖
你的项目要使用a.jar 需要使用b.jar里面的类。必须首先获取到b.jar才可以, 然后才能使用a.jar.
…
2、什么是Maven
Maven是Apache组织维护的自动化构建工具,服务于Java平台的项目构建和依赖管理。
Maven 这个单词的本意是:专家,内行。读音是['meɪv(ə)n]或['mevn]。
作用
Maven 是目前最流行的自动化构建工具,对于生产环境下多框架、多模块整合开发有重要作用,Maven 是一款在大型项目开发过程中不可或缺的重要工具。
Maven 可以整合多个项目之间的引用关系,我们可以根据业务和分层需要任意拆分一个项目;
Maven 提供规范的管理各个常用 jar 包及其各个版本,并且可以自动下载和引入项目中;
Maven 可以根据指定版本自动解决 jar 包版本兼容问题;
Maven 可以把 jar 包所依赖的其它 jar 包自动下载并引入项目。
类似自动化构建工具还有:Ant, Maven, Gradle。
环节
构建过程中的各个环节:清理、编译、测试、报告、打包、安装、部署。
构建(build),是面向过程的(从开始到结尾的多个步骤),涉及到多个环节的协同工作。
构建过程的几个主要环节
①清理(clean):删除以前的编译结果,为重新编译做好准备。
②编译(compile):将Java源程序编译为字节码文件。
③测试(test):针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
④报告:在每一次测试后以标准的格式记录和展示测试结果。
⑤打包(package):将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web
工程对应war包。
⑥安装(install):在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中。
⑦部署(deploy):将打包的结果部署到远程仓库或将war包部署到服务器上运行
package、install、deploy的异同
package
命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
install
命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库【供其他项目使用】,但没有布署到远程maven私服仓库
deploy
命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
3、核心概念
Maven能够实现自动化构建是和它的内部原理分不开的,这里我们从 Maven的九个核心概念入手,
看看Maven是如何实现自动化构建的
①POM
一个文件名称pom.xml , pom翻译过来叫做项目对象模型。 maven把一个项目当做一个模型使用。
控制maven构建项目的过程,管理jar依赖。
②约定的目录结构
maven项目的目录和文件的位置都是规定的。
③坐标
唯一的字符串,用来表示资源的。通常说是GAV(group artifactId version)坐标
④依赖管理
管理你的项目使用jar
⑤仓库管理
资源存放的位置
⑥生命周期
maven工具构建项目的过程,就是生命周期。
⑦插件和目标
执行maven构建的时候用的工具是插件
⑧继承
多模块项目pom中包含很多配置信息是重复的,后续变更修改的时候,改动较大 通过继承的方式来实现统一管理可继承的属性; 目的时消除重复配置
⑨聚合
当项目以多模块的形式构建的时候,需要每个依赖模块单独编译,而聚合即实现统一编译. 目的是方便快速构建
4、简单安装
下载maven的安装包
稳定 :apache-maven-3.3.9-bin.zip
这里我用的是 apache-maven-3.6.1-bin.zip
1)确保安装java环境
maven 本身就是 java 写的,所以要求必须安装 JDK
2)下载并解压 maven 安装程序,
最好创建非中文目录
3)配置 Maven 的环境变量:
> MAVEN_HOME=E:\software\apache-maven-3.6.1
> path=%MAVEN_HOME%\bin
或者
> M2_HOME=E:\software\apache-maven-3.6.1
> path=%M2_HOME%\bin
如下:
注意这里win10不要加 符号 ;
4)验证是否安装成功
mvn –v
二、Maven核心概念
1、POM
<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>
<!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.companyname.project-group,maven会将该项目打成的jar包放本地路径:/com/companyname/project-group -->
<groupId>com.companyname.project-group</groupId>
<!-- 项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
<artifactId>project</artifactId>
<!-- 版本号 -->
<version>1.0</version>
</project>
标签 | 解释 | 说明 |
modelVersion | 模型的版本 | 对于Maven2和Maven3来说,它只能是 4.0.0 |
groupId | 组织id | 一般是公司域名的倒写。 格式:域名倒写+项目名 例如:com.baidu+project。 |
artifactId | 项目名称(模块名称) | 对应groupId中项目中的子项目 |
version | 项目的版本号 | 如果项目还在开发中,是不稳定版本,通常在版本后带SNAPSHOT version使用三位数字标识,例如 1.1.0 |
packaging | 打包的类型 | jar、 war、 rar、 ear、 pom,默认是 jar |
dependencies | 依赖 | 管理 jar包,依赖的其他的 jar包被称为依赖。 依赖的配置正是通过坐标来定位的。 |
properties | 配置属性 | properties是用来定义一些配置属性 例如project.build.sourceEncoding(项目构建源码编码方式),可以设置为UTF 8,防止中文乱码,也可定义相关构建版本号,便于日后统一升级。 |
build | 构建 | build表示与构建相关的配置 例如设置编译插件的 jdk版本主类,打包配置 |
parent | 继承 | 在 Maven中,如果多个模块都需要声明相同的配置,例如: groupId、version、 有相同的依赖 、或者相同的组件配置等, 也有类似 Java的继承机制, 用 parent声明要继承的父工程的 pom配置。 |
modules | 聚合 | 在 Maven的多模块开发中,为了统一构建整个项目的所有模块,可以提供一个额外的模块,该模块打包方式为 pom,并且在其中使用 modules聚合的其它模块,这样通过本模块就可以一键自动识别模块间的依赖关系来构建所有模块,叫 Maven的聚合。 |
2、约定(创建第一个工程)
maven约定的目录结构, 约定是大家都遵循的一个规则。
每一个maven项目在磁盘中都是一个文件夹(项目-Hello)
Hello/
—/src
------/main #放你主程序java代码和配置文件
----------/java #你的程序包和包中的java文件
----------/resources #你的java程序中要使用的配置文件
------/test #放测试程序代码和文件的(可以没有)
----------/java #测试程序包和包中的java文件
----------/resources #测试java程序中要使用的配置文件
—/pom.xml #maven的核心文件(maven项目必须有)
例如:
1)工程结构
按上面说的创建好结构
2)命令执行
pom文件目录下面执行命令。 mvn compile 编译src/main目录下的所有java文件。
mvn compile
执行mvn compile, 结果是在项目的根目录下生成target目录(结果目录),
maven编译的java程序,最后的class文件都放在target目录中
3)第一次下载说明
首次执行会出现很多Downloading
Downloading:https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-parameter-documenter-2.0.9.pom
其中https://repo.maven.apache.org 为中央仓库地址。
1)为什么要下载
maven工具执行的操作需要很多插件(java类–jar文件)完成的
2)下载什么东西了
jar文件–叫做插件–插件是完成某些功能
3)下载的东西存放到哪里了。
默认仓库(本机仓库):
C:\Users\(登录操作系统的用户名)Administrator.m2\repository
4)本地配置修改
设置本机存放资源的目录位置(设置本机仓库):
- 先备份 settings.xml
- 修改maven的配置文件, maven安装目录/conf/settings.xml
- 修改 指定你的目录(不要使用中文目录)
<localRepository>E:\\localRepository</localRepository>
3、坐标
1)坐标解释
使用如下三个向量在 Maven 的仓库中唯一的确定一个 Maven 工程。
①groupid:公司或组织的域名倒序+当前项目名称
②artifactId:当前项目的模块名称
③version:当前模块的版本
2)定位
[1]将gav三个向量连起来
com.alibaba + fastjson + 1.2.4
[2]以连起来的字符串作为目录结构到仓库中查找
com\alibaba\fastjson\1.2.4
※注意:我们自己的 Maven 工程必须执行安装操作才会进入本地仓库。安装的命令是:
mvn install
4、依赖管理
1)依赖的范围
从三个方面看这三种依赖范围的区别
- 是否对主程序有效(main目录下的程序):主程序代码是否可以引用这个依赖
- 是否对测试程序有效(test目录下的程序):测试程序是否可以引用这个依赖
- 是否参与打包(部署):打包(package)后,这个依赖是否会被打到包内(lib文件夹内)
依赖范围(scope) | 是否对主程序有效 | 是否对测试程序有效 | 是否参与打包(部署) | 典型例子 |
compile | 有效 | 有效 | 参与 | spring-core |
test | 无效 | 有效 | 不参与 | junit |
provided | 有效 | 有效 | 不参与 | servlet-api.jar |
①compile
默认的依赖范围,在开发,测试,部署阶段都需要这个artifact对应的jar包在classpath中
例如:spring的依赖
<!--spring最新依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
②test
主程序(main)是无法依赖test范围的jar的,开发时就不可以(那些jar主程序也是用不到的),只有测试程序可以依赖。要知道,测试程序常规是不会参与打包的,test范围的依赖也不参与打包,只是在开发阶段会用到,或者maven编译(compile)时会执行测试程序。
例如: 在我们进行单元测试时候用到junit,但是打包时候test下的类根本不会被编译,也用不到junit
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
③provided
开发时,由于没有运行时环境,有些jar我们需要暂时依赖(不依赖有些方法就会找不到,用不了),但是项目打包部署运行时,由于运行时环境(servlet容器,比如:tomcat)会提供一些jar包,所以开发时那些暂时依赖的jar包就不能参与打包了,否则会发生冲突导致报错。
例如:servlet
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
2)依赖的排除
如果我们在当前工程中引入了一个依赖是 A,而 A 又依赖了 B,那么 Maven 会自动将 A 依赖的 B 引入当前工程,但是个别情况下 B 有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时候将 B 排除。
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.1</version>
<exclusions>
<exclusion>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
</exclusion>
</exclusions>
</dependency>
3)属性的抽取
统一管理所依赖 jar 包的版本对同一个框架的一组 jar 包最好使用相同的版本。为了方便升级框架,可以将 jar 包的版本信息统一提取出来
编译版本配置,编码设置也可以放在这里
<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>
<log4j2.version>2.9.1</log4j2.version>
<slf4j.version>1.7.25</slf4j.version>
</properties>
<!-- Logging -->
<!--log4j2核心包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<!-- Web项目需添加 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>${log4j2.version}</version>
</dependency>
<!--用于与slf4j保持桥接-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j2.version}</version>
</dependency>
<!-- slf4j核心包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
4)优先原则
①声明优先原则
在pom.xml配置文件中,如果有两个名称相同版本不同的依赖声明,那么先写的会生效。
所以,先声明自己要用的版本的jar包即可。
②最短路径优先
直接依赖优先于传递依赖,如果传递依赖的jar包版本冲突了,那么可以自己声明一个指定版本的依赖jar,即可解决冲突。
5、仓库管理
1)仓库中的文件
Maven的插件,插件也是一些 jar,这些 jar可以完成一定的功能。
我们自己开发项目的模块
第三方框架或工具的 jar包
2)分类
本地仓库
为当前本机电脑上的所有Maven 工程服务。
远程仓库
不在本机上,通过网络才能使用。多电脑共享使用的。
(1)私服:架设在当前局域网环境下,为当前局域网范围内的所有 Maven 工程服务。
(2)中央仓库:架设在 Internet 上,为全世界所有 Maven 工程服务。
(3)中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。
3)Maven对仓库的使用
在 Maven构建项目的过程中如果需要某些插件,
①首先会到 Maven的本地仓库中查找,如果找到则可以直接使用;
②如果找不到,它会自动连接外网,到远程中央仓库中查找;
③如果远程仓库中能找到,则先把所需要的插件下载到本地仓库,然后再使用,并且下次再用到相同的插件也可以直接使用本地仓库的;
④如果没有外网或者远程仓库中也找不到,则构建失败。
资源搜索地址:链接: https://mvnrepository.com/
4)maven配置之使用阿里云仓库
当前地址对资源访问过慢,可以使用阿里云的镜像
①在项目的pom.xml里直接加入
<repositories>
<repository>
<id>central</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<layout>default</layout>
<!-- 是否开启发布版构件下载 -->
<releases>
<enabled>true</enabled>
</releases>
<!-- 是否开启快照版构件下载 -->
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
②settings.xml配置
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>;
<mirrorOf>central</mirrorOf>
</mirror>
6、生命周期
maven对项目的构建分为三套相互独立的生命周期。
①cleanLifecycle
在项目构建前,先进行一些清理工作
②defaultLifecycle
构建的核心部分,编译,测试,打包,部署
③siteLifecycle
生成项目报告,站点,发布报告
maven的每个生命周期都有很多阶段,每个阶段对应一个执行命令。
1)clean生命周期
清理项目
1 | pre-clean | 执行清理前需要完成的工作 |
2 | clean | 清理上一次构建生成的文件 |
3 | post-clean | 执行清理后需要完成的工作 |
2)default生命周期
构建项目
1 | validate | 验证工程是否正确,所有需要的资源是否可用。 |
2 | compile | 编译项目的源代码。 |
3 | test | 使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。 |
4 | package | 把已编译的代码打包成可发布的格式,比如jar。 |
5 | integration-test | 如有需要,将包处理和发布到一个能够进行集成测试的环境。 |
6 | verify | 运行所有检查,验证包是否有效且达到质量标准。 |
7 | install | 把包安装到maven本地仓库,可以被其他工程作为依赖来使用。 |
8 | deploy | 在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。 |
3)site生命周期
建立和发布项目站点
1 | pre-site | 生成项目站点之前需要完成的工作 |
2 | site | 生成项目站点文档 |
3 | post-site | 生成项目站点之后需要完成的工作 |
4 | site-deploy | 将项目站点发布到服务器 |
7、插件和目标
官网插件说明: http://maven.apache.org/plugins/
Maven 的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。每个插件都能实现多个功能,每个功能就是一个插件目标。Maven 的生命周期与插件目标相互绑定,以完成某个具体的构建任务。
1)clean插件
阶段是独立的一个阶段,功能就是清除工程目前下的 target目录
2)resources插件
resource插件的功能就是把项目需要的配置文件拷贝到指定的目当,默认是拷贝 src\main\resources目录下的件到classes目录下
3)compile插件
执行时先调用 resouces插件,功能就是把 src\mainjava源码编译成字节码生成 class文件,并把编译好的 class文件输出到 target\classes目录下
4)test测试插件
单元测试所用的 compile和 resources插件和主代码是相同的,但执行的目标不行,目标 testCompile和 testResources是把 src\test\java下的代码编译成字节码输出到 target\test classes,同时把 src\test\resources下的配置文件拷贝到target\test-classes
5)package打包插件
这个插件是把class文件、配置文件打成一个文件、配置文件打成一个jar(war或其它格式)包
6)deploy发布插件
插件的功能就是把构建好的artifact部署到本地仓库,还有一个deploy插件是将构建好的插件是将构建好的artifact部署到远程仓库
7)等等…
常用插件常用插件可以在自己的项目中设置,最常使用的是最常使用的是maven编译插件。设置项目使用的jdk版本时通过编译插件指定。
pom.xml文件文件中设置。
8、继承
1)为什么需要继承机制?
由于非 compile 范围的依赖信息是不能在“依赖链”中传递的,所以有需要的工程只能单独配置。
例如:
Hello
HelloFriend
HelloBrother
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
有三个模块都需要引入junit
此时如果项目需要将各个模块的junit版本统一为4.9,那么到各个工程中手动修改无疑是非常不可取的。使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。
2)创建父工程
创建父工程和创建一般的 Java 工程操作一致,唯一需要注意的是:打包方式处要设置为 pom。
<groupId>top.kegh</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
在子工程中引用父工程
<parent>
<!-- 父工程坐标 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<relativePath>从当前目录到父项目的 pom.xml 文件的相对路径</relativePath>
</parent>
样例如下:
<parent>
<groupId>top.kegh</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 指定从当前子工程的pom.xml文件出发,查找父工程的pom.xml的路径 -->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
此时如果子工程的 groupId 和 version 如果和父工程重复则可以删除,在父工程中管理依赖
将 Parent 项目中的 dependencies 标签,用 dependencyManagement 标签括起来
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
在子项目中重新指定需要的依赖,删除范围和版本号
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
9、聚合
1)为什么要使用聚合?
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行 clean 操作。而使用了聚合之后就可以批量进行 Maven 工程的安装、清理工作。
2)如何配置聚合?
在总的聚合工程中使用 modules/module 标签组合,指定模块工程的相对路径即可
<modules>
<module>../Hello</module>
<module>../HelloFriend</module>
<module>../MakeFriends</module>
</modules>
三、在idea中的使用maven
也是我自己整理的
链接: https://blog.csdn.net/qq_33301866/article/details/108698043
完结!撒花!
码字整理不易,感谢各位大佬支持↓↓↓↓↓↓↓↓↓↓↓
【微信】二维码:如本文对你10分帮助,就赏个10分(一毛)吧