第一章 为什么用Maven
1.1 什么是Maven
自动化构建工具:Java平台的项目构建和依赖管理。如jar包管理,你只需要在你的项目中以坐标的方式依赖一个jar包,Maven就会自动从中央仓库进行下载,并同时下载这个jar包所依赖的其他jar包——规范、完整、准确!
1.2 Jar包之间的依赖关系
Maven就可以替我们自动地将当前jar包所依赖的其他所有jar包全部导入进来,无需人工参与
1.3 Jar包之间的冲突处理
最短路径者优先
先声明者优先
1.4 Maven的自动化构建环节
(1)清理:删除以前的编译结果,为重新编译做好准备。
(2)编译:将Java源程序编译为字节码文件。
(3)测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
(4)报告:在每一次测试后以标准的格式记录和展示测试结果。
(5)打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包。
(6)安装:在Maven环境下,特指将打包的结果——jar包或war包安装到本地仓库中。
(7)部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行。
第二章 Maven如何使用
2.1 自动化构建
2.2 安装Maven核心程序
1.检查JAVA_HOME环境变量。Maven是使用Java开发的,所以必须知道当前系统环境中JDK的安装目录。
C:\Windows\System32>echo %JAVA_HOME%
D:\MyWork\Program\jdk1.8.0_211
- 解压Maven的核心程序。将apache-maven-3.8.1-bin.zip解压到一个非中文无空格的目录下。
- 配置环境变量。
系统变量里面:
值写Maven的解压目录,就是bin上面的那级apache-maven-3.8.1
变量:MAVEN_HOME
值:D:\develop\Maven\apache-maven-3.8.1
path变量中:
变量:path
值:%MAVEN_HOME%\bin或D:\develop\Maven\apache-maven-3.8.1\bin
- 查看Maven版本信息验证安装是否正确
按Win +r,进入电脑运行模式
输入cmd
在管理员窗口输入
mvn -v
如下图出现版本号就成功了
2.3 Maven联网问题
- Maven默认的本地仓库:~.m2\repository目录。这个目录在C盘,一般会自定义一个位置
- Maven的核心配置文件位置
解压目录D:\develop\Maven\apache-maven-3.8.1\conf\settings.xml
- 更改本地仓库地址默认在
C:\Users\Administrator\.m2\repository
-><localRepository>D:\develop\RepMaven</localRepository>
- 配置阿里云镜像(下载速度快)
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
2.4 Maven编译版本
在settings.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>
2.5 在IDEA中配置Maven
-
创建一个空的Project
-
创建一个Maven工程
约定: -
main目录用于存放主程序
-
java目录用于存放源代码文件
-
resources目录用于存放配置文件和资源文件
-
test目录用于存放测试程序
Maven的使用:
2.7 Maven打包插件
能够将项目所依赖的jar包一并打入到jar中
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
第三章 Maven的核心概念
POM、约定的目录结构、坐标、依赖、仓库、生命周期、插件和目标、继承、聚合。
3.1 pom.xml
全称Project Object Model,Maven工程的核心配置
3.2 约定的目录结构
约定>配置>编码
3.3 坐标
groupId:公司或组织的域名倒序+当前项目名称
artifactId:当前项目的模块名称
version:当前模块的版本
<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
<artifactId>DemoLXY</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
在pom.xml配置文件中配置当前工程依赖Hello工程(前提是本地repo有Hello.jar–在Hello工程中install一下)
<dependencies>
<dependency>
<groupId>com.maven</groupId>
<artifactId>Hello</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
主程序
在src/main/java目录下写代码(新建HelloFriend.java)
public class HelloFriend {
public String sayHelloToFriend(String name){
Hello hello = new Hello();
String str = hello.sayHello(name)+" I am "+this.getMyName();
return str;
}
public String getMyName(){
return "Idea";
}
}
测试程序
在src/test/java目录下写代码(新建HelloFriendTest.java)
一般测试哪个方法的程序名字会以该方法名称开头Test结尾
import org.junit.Test;
import static junit.framework.Assert.*;
public class HelloFriendTest {
@Test
public void testHelloFriend(){
HelloFriend helloFriend = new HelloFriend();
String results = helloFriend.sayHelloToFriend("Maven");
assertEquals("Hello Maven! I am Idea",results);
}
}
3.5 依赖管理
3.5.1 依赖的生效范围scope
compile: 默认就是这个范围
(1)main目录下的Java代码可以访问这个范围的依赖
(2)test目录下的Java代码可以访问这个范围的依赖
(3)部署到Tomcat服务器上运行时要放在WEB-INF的lib目录下
test:
(1)main目录下的Java代码不能访问这个范围的依赖
(2)test目录下的Java代码可以访问这个范围的依赖
(3)部署到Tomcat服务器上运行时不会放在WEB-INF的lib目录下
provided:
(1)main目录下的Java代码可以访问这个范围的依赖
(2)test目录下的Java代码可以访问这个范围的依赖
(3)部署到Tomcat服务器上运行时不会放在WEB-INF的lib目录下
3.5.2 依赖的传递性
A <- B 表示B依赖A
Maven工程 | 依赖范围 | 对A的可见性 |
---|---|---|
A <- B <- C | compile | √ |
A <- B <- D | test | × |
A <- B <- E | protected | × |
3.5.3 依赖的原则:解决jar包冲突
1)路径最短者优先
2)路径相同时先声明者优先
这里“声明”的先后顺序指的是dependency标签配置的先后顺序。
3.5.4 依赖的排除
有的时候为了确保程序正确可以将有可能重复的间接依赖排除。请看如下的例子:
(1)假设当前工程为MakeFriend,直接依赖OurFriends。
(2)OurFriends依赖commons-logging的1.1.1对于MakeFriend来说是间接依赖。
(3)当前工程MakeFriend直接依赖commons-logging的1.1.2。
(4)加入exclusions配置后可以在依赖OurFriends的时候排除版本为1.1.1的commons-logging的间接依赖。
<dependency>
<groupId>com.atguigu.maven</groupId>
<artifactId>OurFriends</artifactId>
<version>1.0-SNAPSHOT</version>
<!--依赖排除-->
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.2</version>
</dependency>
统一管理jar包版本
properties
<!--统一管理当前模块的jar包的版本-->
<properties>
<spring.version>4.0.0.RELEASE</spring.version>
</properties>
……
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
3.6 仓库
(1)Maven的插件。
(2)我们自己开发的项目的模块。
(3)第三方框架或工具的jar包。
※不管是什么样的jar包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询或依赖。
第四章 继承
4.1 在子工程中引用父工程
- 父工程坐标
<parent>
<!-- 父工程坐标 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<!--指定从当前pom.xml文件出发寻找父工程的pom.xml文件的相对路径-->
<relativePath>..</relativePath>
</parent>
- 继承
<!--继承-->
<parent>
<groupId>com.atguigu.maven</groupId>
<artifactId>Parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--指定从当前pom.xml文件出发寻找父工程的pom.xml文件的相对路径-->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
4.2 在父工程中管理依赖
- 将Parent项目中的dependencies标签,用dependencyManagement标签括起来。
<!--依赖管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 在子项目中重新指定需要的依赖,删除范围和版本号。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
第五章 聚合
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行clean操作。而使用了聚合之后就可以批量进行Maven工程的安装、清理工作。
5.1 如何配置聚合
在总的聚合工程中使用modules/module标签组合,指定模块工程的相对路径即可。
<!--聚合-->
<modules>
<module>../MakeFriend</module>
<module>../OurFriends</module>
<module>../HelloFriend</module>
<module>../Hello</module>
</modules>
Maven可以根据各个模块的继承和依赖关系自动选择安装的顺序。
第六章 Maven酷站
我们可以到Maven仓库搜索需要的jar包的依赖信息。
国外的
第七章 Maven常见问题解决方法
7.1 8.1jar未下载完成
在使用Maven过程中,我们所使用的jar包是会到中央仓库中进行下载的,但是如果在下载过程中因为网络不通畅等原因,会导致jar包下载失败,并且会形成一个xxxx.lastupdated的文件,但是此时Maven并不会将其删掉后重新下载,而是认为它下载过了,我们需要做的是将.xxxxlastupdated文件手动删除后,再次重新下载。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
- 解决方案1
手动删除.lastupdate文件,让其重新下载就好了。 - 解决方案2
直接在仓库下搜索.lastupdated文件,然后ctrl+a全选后ctrl+d删除 就能直接删掉所有没下载号的jar包。
7.2 jar包冲突问题
jar包冲突往往是发生在,同一个项目在运行时导入了两个相同jar包的不同版本,又因为两个不同版本的jar包代码是不一样的,是冲突的,导致在运行时,报出各种莫名其妙的错误。
图是将有问题的jar包版本排除掉 exclusion