day05[Maven]
第一章.Maven介绍与使用
1.为什么使用Maven
- 添加第三方jar包
- 处理jar包之间的依赖
- 处理jar包之间的冲突(最短路径者优先和先声明者优先)
- 获取第三方jar包
- 将项目拆分成多个工程模块
- 实现项目的分布式部署
2.Maven是什么?
2.1.自动化构建工具
Maven是一款自动化构建工具,专注服务于java平台的项目构建和依赖管理
2.2.构建的概念
![$01[Maven] - 图1](/uploads/projects/liuye-6lcqc@gx6gw9/0e32c42132a61a9f10ad93aafdf93713.png)
/*构建就是以我们编写的Java代码、框架配置文件、国际化等其他资源文件、JSP页面和图片等静态资源作为“原材料”,去“生产”出一个可以运行的项目的过程。/
2.3.构建环节
- 清理:删除以前的编译结果,为重新编译做好准备。
- 编译:将Java源程序编译为字节码文件。
- 测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
- 报告:在每一次测试后以标准的格式记录和展示测试结果。
- 打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包
- 安装:在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中。
- 部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行
2.4.自动化构建
/*这是阳光明媚的一天。托马斯向往常一样早早的来到了公司,冲好一杯咖啡,进入了自己的邮箱——很不幸,QA小组发来了一封邮件,报告了他昨天提交的模块的测试结果——有BUG。“好吧,反正也不是第一次”,托马斯摇摇头,进入IDE,运行自己的程序,编译、打包、部署到服务器上,然后按照邮件中的操作路径进行测试。“嗯,没错,这个地方确实有问题”,托马斯说道。于是托马斯开始尝试修复这个BUG,当他差不多有眉目的时候已经到了午饭时间。下午继续工作。BUG很快被修正了,接着托马斯对模块重新进行了编译、打包、部署,测试之后确认没有问题了,回复了QA小组的邮件。一天就这样过去了,明媚的阳光化作了美丽的晚霞,托马斯却觉得生活并不像晚霞那样美好啊。/
![$01[Maven] - 图2](/uploads/projects/liuye-6lcqc@gx6gw9/7166bcc446f6a188092e141aea71c19d.png)
总结:Maven可以自动的从构建过程的起点一直执行到终点
![$01[Maven] - 图3](/uploads/projects/liuye-6lcqc@gx6gw9/2e707565ba37c6b0c82d924e54469ff2.png)
2.5.Maven核心概念
- POM
- 约定的目录结构
- 坐标
- 依赖管理
- 仓库管理
- 生命周期
- 插件和目标
- 继承
- 聚合
3.Maven如何使用
3.1.安装Maven核心程序
- 配置Java_HOME
- 配置M2_HOME
- 配置path: %M2_HOME%\bin
验证maven是否安装成功
mvn -v
![$01[Maven] - 图4](/uploads/projects/liuye-6lcqc@gx6gw9/cb7416c2e53a9d2737d4c9f3874c4dc4.png)
3.2.Maven连网问题
- 配置本地仓库
/*1.配置本地仓库Maven默认的本地仓库:~\.m2\repository目录 ~表示当前用户的家目录Maven的核心配置文件:E:\apache-maven-3.5.4\conf\settings.xml设置方式:<localRepository>以及准备好的仓库位置</localRepository>/
- 设置阿里云镜像
<mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>
3.3.Maven打包插件
Maven本身的打包插件不负责将依赖的jar包一并打入到jar包中。
如果项目所依赖的jar包在服务器环境中提供了还好,如果服务器环境中没有提供,则比较悲惨,运行各种ClassNotFound….你们懂的!
因此需要一款能够将项目所依赖的jar包 一并打入到jar中的插件来解决这些问题
<build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifest><!-- 指定主类 --><mainClass>xxx.xxx.XXX</mainClass></manifest></archive></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build>
第二章.Maven的核心概念
1.核心概念
- POM
- 约定的目录结构
- 坐标
- 依赖
- 仓库
- 生命周期
- 插件和目标
- 继承
- 聚合
2.POM
Project Object Mode:项目对象模型,将Java工程的相关信息封装为对象作为便于操作和管理的模型.Maven工程的核心配置,可以说学习Maven就是学习pom.xml文件中的配置
3.约定的目录结构
现在JavaEE开发领域普遍认同一个概念:约定>配置>编码,意思就是能用配置解决的问题就不编码,能基于约定的就不进行配置,而Maven正是因为指定了特定文件保存的目录才能够对我们的Java工程进行自动化构建
4.坐标
/*1.几何中的坐标在一个平面中使用x、y两个向量可以唯一的确定平面中的一个点。在空间中使用x、y、z三个向量可以唯一的确定空间中的一个点。2.Maven的坐标使用如下三个向量在Maven的仓库中唯一的确定一个Maven工程groupId:公司或组织的域名倒序+当前项目名称artifactId:当前项目的模块名称version:当前模块的版本/
<groupId>com.atguigu.maven</groupId><artifactId>Hello</artifactId><version>0.0.1-SNAPSHOT</version>
注意:我们自己的Maven工程必须执行安装操作才会进入仓库,安装的命令: mvn install
5.依赖管理
/*1.基本概念当 A jar包需要用到 B jar包的类时,我们就说A对B有依赖,例如:Commons-fileupload-1.3jar依赖于Commons-io-2.0.1.jar2.直接依赖和间接依赖如果A依赖B,B依赖C,那么A->B和B->C都是直接依赖,而A->C是间接依赖/
5.1.依赖的范围
/*1.compile[1]main目录下的Java代码可以访问这个范围的依赖[2]test目录下的Java代码可以访问这个范围的依赖[3]部署到Tomcat服务器上运行时要放在WEB-INF的lib目录下例如:对Hello的依赖。主程序、测试程序和服务器运行时都需要用到。2.test[1]main目录下的Java代码不能访问这个范围的依赖[2]test目录下的Java代码可以访问这个范围的依赖[3]部署到Tomcat服务器上运行时不会放在WEB-INF的lib目录下例如:对junit的依赖。仅仅是测试程序部分需要。3.provided[1]main目录下的Java代码可以访问这个范围的依赖[2]test目录下的Java代码可以访问这个范围的依赖[3]部署到Tomcat服务器上运行时不会放在WEB-INF的lib目录下4.其他:runtime,import,system/
![$01[Maven] - 图5](/uploads/projects/liuye-6lcqc@gx6gw9/7f5737329a746b99eb4fa354812d540a.png)
5.2.依赖的传递性
当存在间接依赖的情况时,主工程对间接依赖的jar可以使用吗?这要看间接依赖的jar包引入时的依赖范围—只有依赖范围为compile时可以访问,例如:
![$01[Maven] - 图6](/uploads/projects/liuye-6lcqc@gx6gw9/d233f250a66b349c4e1f94301a5d9cc5.png)
5.3.依赖的原则:解决jar包冲突
- 路径最短者优先
![$01[Maven] - 图7](/uploads/projects/liuye-6lcqc@gx6gw9/05211693bc4733edfda5e8013baa6e18.png)
- 路径相同时先声明者优先(这里声明的先后顺序指的是dependency标签配置的先后顺序)
![$01[Maven] - 图8](/uploads/projects/liuye-6lcqc@gx6gw9/9ac524fb14cfe645e97275f7aad71d77.png)
5.4.依赖的排除
/*有的时候为了确保程序正确可以将有可能重复的间接依赖排除。请看如下的例子:假设当前工程为MakeFriend,直接依赖OurFriends。OurFriends依赖commons-logging的1.1.1对于MakeFriend来说是间接依赖。当前工程MakeFriend直接依赖commons-logging的1.1.2加入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>
5.5统一管理目标jar包的版本
以对Spring的jar包依赖为例:Spring的每一个版本中都包含spring-context,springmvc等jar包。我们应该导入版本一致的Spring jar包,而不是使用4.0.0的spring-context的同时使用4.1.1的springmvc
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>4.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>4.0.0.RELEASE</version></dependency>
问题是如果我们想要将这些jar包的版本统一升级为4.1.1,是不是要手动一个个修改呢?显然,我们有统一配置的方式
<!--统一管理当前模块的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></dependency>
6.仓库
- 本地仓库:为当前本机电脑上的所有Maven工程服务
- 远程仓库
- 私服:架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务
- 中央仓库: 架设在Internet上,为全世界所有Maven工程服务
- 中央仓库的镜像:架设在各个大洲,为中央仓库分担流量,减轻中央仓库的压力,同时更快的响应用户请求
- 仓库中的文件
- Maven的插件
- 我们自己开发的项目的模块
- 第三方框架或工具的jar包(不管是什么样的jar包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询和依赖)
7.生命周期
/*1.什么是maven的生命周期?Maven生命周期定义了各个构建环节的执行顺序,有了这个清单,Maven就可以自动化的执行构 建命令了。Maven有三套相互独立的生命周期,分别是:Clean Lifecycle在进行真正的构建之前进行一些清理工作。Default Lifecycle构建的核心部分,编译,测试,打包,安装,部署等等。Site Lifecycle生成项目报告,站点,发布站点。再次强调一下它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期。每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean,这个clean是Clean生命周期的一个阶段。有Clean生命周期,也有clean阶段。/
default生命周期(常用阶段)
- compile 编译项目的源代码
- test-compile 编译测试源代码
- test 使用合适的单元测试框架运行测试,这些测试代码不会被打包和部署
- package 接收编译好的代码,打包成可发布的格式
- install 将包安装至本地仓库,以让其他项目依赖
运行任何一个阶段的时候,它前面的所有阶段都会被运行
8.插件和目标
- Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
- 每个插件都能实现多个功能,每个功能就是一个插件目标
- Maven的生命周期与插件目标相互绑定,以完成某个具体的构建任务
例如: compile就是插件maven-compiler-plugin的一个功能;pre-clean是插件maven-clean-plugin的一个目标。
9.继承
9.1.为什么需要继承机制
由于非compile范围的依赖信息是不能在“依赖链”中传递的,所以有需要的工程只能单独配置。例如:
![$01[Maven] - 图9](/uploads/projects/liuye-6lcqc@gx6gw9/73c00c4531bb39d142f873cd1b41016f.png)
9.2.创建父工程
父工程的打包方式为pom
<groupId>com.atguigu.maven</groupId><artifactId>Parent</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version>
父工程只需要保留pom.xml文件即可
9.3.创建子工程
<!--继承--><parent><groupId>com.atguigu.maven</groupId><artifactId>Parent</artifactId><version>1.0-SNAPSHOT</version><!--指定从当前pom.xml文件出发寻找父工程的pom.xml文件的相对路径--><relativePath>../Parent/pom.xml</relativePath></parent>
此时如果子工程的groupid和version如果和父工程重复则可以删除
9.4.在父工程中管理依赖
- 将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>
10.聚合
10.1.为什么需要聚合?
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行clean操作。而使用了聚合之后就可以批量进行Maven工程的安装、清理工作。
10.2.如何配置聚合?
在总的聚合工程中使用modules/module标签组合,指定模块工程的相对路径即可
<!--聚合--><modules><module>../MakeFriend</module><module>../OurFriends</module><module>../HelloFriend</module><module>../Hello</module></modules>
Maven可以根据各个模块的继承和依赖关系自动选择安装的顺序
第三章.Maven酷站
![$01[Maven] - 图10](/uploads/projects/liuye-6lcqc@gx6gw9/40b464e0418400ebe1983aafba619659.png)
