Maven的简介
Apache Maven,是一个软件项目管理及自动构建工具,由Apache软件基金会所提供。基于项目对象模型概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。 Maven也可被用于构建和管理各种项目,例如C#,Ruby,Scala和其他语言编写的项目。
使用Maven的好处有哪些
- 依赖管理,对jar包进行统一管理,大幅度缩小工程的大小,因为可以使用pom.xml来导入依赖即可,而依赖也只是一个引用所以不占用很大空间
- 将一个工程可以拆分成多个子模块,有利于分工开发提高效率
- 一键构建
- 可以跨平台
安装
第一步:Maven 是由 Java 语言开发所以需要依赖于 JDK,所以进入终端使用“java -version”检查自己电脑是否已经装好 JDK,如果没有请自行百度
第二步:到 Maven 的官网下载 https://maven.apache.org/download.cgi#
第三步:解压 Maven 核心程序压缩包
第四步:配置 Maven 相关的环境变量
1.新建用户变量 变量名:MAVEN_HOME 变量值:解压Maven的根目录如D:\apache-maven-3.2.2
2.编辑用户变量 变量名:path 变量值:解压Maven\bin目录
第五步:验证 运行mvn -v命令查看 Maven版本
注意:Maven3.3以上的版本需要依赖 JDK 1.7或者更高版本,安装Mavne本身大约 10MB,但Maven还有本地库的使用会需要额外空间,所以至少需要 500MB
修改本地仓库位置
一般默认位置是在 C:\Users|[登录当前系统的用户名].m2\repository
但是我们为了以后方便所以修改默认本地仓库位置,换成我们自己准备好的仓库
- 找到Maven解压目录\conf]settings.xml
- 在settings.xml文件中找到 localRepository标签
- 将/path/to/local/repo从注释中取出
- 将标签体内修改为已经准备好的 Maven 仓库目录
<localRepository>D:\RepMaven</localRepository>
仓库
说到依赖首先通过依赖的坐标去找我们的本地仓库,如果本地仓库没有找到就回去远程仓库去下载,因此如果自己的本地仓库没有这个依赖,那么就必须要联网才可以进行下载
仓库的分类
- 本地仓库:当前电脑上部署的仓库目录,为当前电脑上所有Maven工程服务
- 远程仓库
- 私服:搭建在局域网环境中,为局域网范围内的所有Maven工程服务
- 中央仓库:假设在 Internet 上,为全世界所有Maven工程服务
- 中央仓库镜像:为了分担中央仓库的流量,提升访问速度
构建Maven的各个环节
- 清理:将以前编译得到的旧的class字节码文件删除,为下一次编译做准备
- 编译:将Java源程序编译成class字节码文件
- 测试:自动测试,自动调用junit程序
- 报告:测试程序执行的结果
- 打包:动态Web工程打war包,Java工程打jar包
- 安装:将打包得到的文件复制到“仓库”中的指定位置
- 部署:将动态web工程生成的war包复制到servlet容器的指定目录下,使其可以运行
Maven命令
- mvn clean:清理
- mvn compile:编译主程序
- mvn test-compile:编译测试程序
- mvn test:执行猜测程序
- mvn package:打包
- mvn install:安装
- mvn site:生成站点
Maven工程
现在对Maven也有些了解了那么我们就可以搭建自己的Maven工程了,但在搭建之前我们要知道 Maven工程跟Java工程的结构有些不同,下面是Maven工程的目录结构我们可以按照下面来创建目录
my-app
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- mycompany
| `-- app
| `-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
创建好之后我们需要引入pom.xml 下面解释一下各个标签的含义,然后我们在App.java写代码,在AppTest.java里面写测试代码即可
-
groupId :公司或组织域名倒序 + 项目名
-
artifactid:模块名
-
version:版本 如后缀带有SNAPSHOT表示是一个分支版本可能不稳定所以尽量使用后缀RELEASE表示正式版
-
packaging:表示Maven对这个模块用什么方式进行打包
- pom:表示为父类工程
- jar :为packaging的默认类型表示maven 将该项目打包jar包
- war:一般用于是web工程
-
properties:对项目用于版本号的统一管理
-
dependencies:管理整个项目的所有依赖
-
dependency:对一个jar包的依赖将其引用到项目当中groupId、artifactId、version相当于是坐标
-
scope:作用域,maven解析依赖信息会到本地仓库中查找依赖的jar包,对于自己开发的maven项目,使用 mvn install命令安装后就可以进入仓库,此时就需要依赖的范围进行把控
- compile:对主程序、测试程序都有效,并且参与打包和部署(spring-core)
- test:对于主程序无效、测试程序有效,并且不参与打包和部署(junit)
- provided :对主程序、测试程序有效,并且不参与打包和部署,如果正常使用compile会报错原因是我们的tomcat容器会提供servlet-api所以有冲突(servlet-api)
<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.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- packaging>jar</packaging -->
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
依赖
上面的 dependency 标签就是添加依赖,除了添加依赖的方法之外,还需要强调的是依赖的传递性
场景一:Maven工程A和B,B依赖于spring-core的jar包,A依赖于B,那么A不用引入spring-core就有了jar包,这就是maven的传递性
这样我们可以通过传递性不必再每个模块工程都重复声明,在“最下面”的工程中依赖一次就行,上面的工程来依赖下面的工程,那么上面的工程也就拥有了下面的jar包
注意:非compile范围的依赖不能传递,所以各个工程模块中,如果有需要就得重复声明依赖
依赖排除
通过依赖的方式我们引入了别的maven工程就相当于引入了它们的jar包,如果我们不想要引入它们jar包中的某一个不稳定的包我们可以这样来设置将它从中排除
场景二:如我们不想引入B工程spring-core中的commons-logging包
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
依赖的原则
依赖的原则的作用其实就是解决模块工程之间jar包的冲突
- 原则一:最短路径原则
- 原则二:路径相同时先声明者优先
A->B->C,B和C都有log4j,B的是1.2.14,C的是1.2.17,A最后依赖的版本就是log4j1.2.14也就是B的这就是原则一中的最短路径原则
A——>B
|
——>C 此时A到B的路径与A到C的路径相等,这就要看在A的pom.xml文件中是B模块先声明还是C模块先声明,谁先声明就依赖谁
注意:上面两句话很重要面试问到Maven必问的知识点,你 get 到了吗
统一版本号
在开发过程中如果有很多个依赖,当我们要对这些依赖升级事就会发现很头疼的事情,比如我们要升级spring要对其所有的jar包都进行依次升级这样就会很麻烦,作为程序猿的我们肯定希望要是只改动一个地方就可以修改大部分相同的版本号该多好,Maven提供了properties标签我们可以对其进行定义,然后引入到version标签当中。
<properties>
<spring.version>4.0.0.RELEASE<spring.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
继承
继承其实就是创建maven工程的时候父类在选择类型的时候选择pom打包的方式,子类可以是别的类型如jar,然后在子类当中声明父类工程
子类pom.xml中声明如下:
<parent>
<groupId>父类组织</groupId>
<artifactId>父类模块名</artifactId>
<version>父类版本号</version>
</parent>
因为子类声明父类的工程,在子类工程的坐标依赖中就会有很多重复的会出现黄色的波浪线我们就可以删除掉,父类就可以统一的管理版本号
聚合
有了继承我们在install到本地仓库的时候如果不是按照一定的顺序,我们会发现安装会失败,原因是有些模块依赖于上一个模块。所以我们采用聚合的方式,不用考虑顺序随便在一个“总的聚合工程”中配置各个参与聚合的模块
<!-- 配置聚合 -->
<modules>
<!-- 指定各个子工程的相对路径 -->
<module>../B工程名</module>
<module>../C工程名</module>
</modules>
注意上面代码的"点点"实际是从要聚合的工程的pom.xml来算的所以要先 点点 出去这个工程然后才能找到要聚合的工程