Maven:项目的构建工具
如果我们想要创建一个Web工程,做一个基于B/S架构的项目。我们使用SSM(Spring SpringMVC MyBatis)
展示层 HTML CSS JS Jquery
控制层 SpringMVC
业务逻辑层 Spring IOC/AOP
持久化层 JDBC MyBatis
数据库 MYSQL ORACLE
Maven不是一个直接用来辅助我们编码的一个工具。它所工作的位置不是以上的任何一层。它是用来构建我们整个工程的。
为什么使用Maven?使用Maven可以解决什么样的问题?
1.添加第三方的JAR包
我们只需要通过Maven将所有的JAR下载一次就可以了,将我们所使用的所有的JAR统一的放置在Maven的仓库中,以后我们在需要使用相同的JAR包的时候,直接去Maven的仓库中引用就可以了,无需在进行重复的下载以及引用了。
2.JAR包之间依赖的关系
3.获取第三方的JAR包
4.将项目拆分成多个工程模块
Maven的中央仓库的地址:https://mvnrepository.com
Maven是Apache维护的一款自动化构建工具,专注服务于java平台的项目构建以及依赖管理的。Maven这个单词本身的含义是专家、内行。
什么是构建?
并不是指单纯的创建,创建一个工程并不等于构建一个工程。要了解什么是构建应该从以下三点看:
1.纯java代码
java是一门编译型语言,.java扩展名的源文件需要编译成.class扩展名的字节码文件才能够执行。所以编写任何java代码想要执行就必须经过编译得到对应的.class文件
2.Web工程
当我们需要通过浏览器去访问java程序的时候就必须将包含java程序的Web工程编译的结果拿到服务器上指定的目录,并且启动服务器之后才能够访问,这个拿的过程我们称之为部署
3.实际项目
在实际项目中整合第三方框架,Web工程除了java程序和JSP的页面、图片等静态资源之外,还包括了第三方框架的JAR包以及各种各样的配置文件。所以这些资源都必须按照正确的目录结构部署到服务器上,项目才可以正常运行。
所以综上所述,构建就是以我们编写的java代码、框架配置文件、国际化文件等等其他的资源文件、JSP页面和图片等静态资源作为“原材料”,去生产一个可以运行的项目的过程。
构建一个工程包含哪些环节?
1.清理:删除以前的编译结果,为重新编译做好准备。
2.编译:将java的源文件编译为字节码文件
3.测试:针对项目中的关键节点进行测试,确保项目在迭代开发中关键点的正确性
4.报告:在每一次测试之后以测试标准的格式记录和展示测试结果
5.打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或者部署。java工程对应的JAR包,web工程对应的WAR包
6.安装:在Maven环境下是指将打包的结果部署到仓库中
7.部署:将打包的结果部署到远程仓库或者是将WAR包部署到服务器上运行。
如何安装Maven?
1.检查是否安装了JAVA_HOME的环境变量。
2.解压缩maven的压缩程序,解压到一个没有中文,没有空格,没有特殊字符的目录中。
3.配置Maven的环境变量
首先在环境变量中配置MAVEN_HOME或者是M2_HOME,建议你们配置M2_HOME
其次输入变量名:M2_HOME,输入变量值:Maven解压的路径
找到path,在path的变量值中添加:%M2_HOME%\bin;
4.验证Maven的环境变量
启动命令提示符 输入mvn -v
Maven的核心概念:
Maven能够实现自动化构建是和它的内部原理分不开的,我们从九个核心概念入手。
1.pom
2.约定的目录结构
3.坐标
4.依赖管理
5.仓库管理
6.生命周期
7.插件和目标
8.继承
9聚合
第一个Maven工程:
1.创建一个约定好的目录结构
目录结构:
Hello:工程名
src:原码
main:存放主程序
java:存放java源文件
resources:存放框架或其他工具 的配置文件
test:存放测试程序
java:存放测试的java源文件
resources:测试程序的配置文件
pom.xml:Maven的配置文件
Maven的指令:
mvn compile 编译
mvn clean 清理
mvn test 测试
mvn package 打包
注意:运行Maven命令的时候一定要进入pom.xml所在的文件夹
默认的本地仓库的地址:在C盘
我们可以更改本地仓库的位置:在Maven的安装目录中找到conf文件夹,找到settings.xml,在文件中找到本地仓库的路径
POM:
Project Object Model:项目对象模型。将java工程的相关的信息封装为对象,作为便于操作和管理的模型。maven工程的核心配置就是这个pom.xml。
坐标:
Maven的坐标:
使用如下三个向量在Maven的仓库中唯一的确定一个Maven的工程:
1.grouid:公司的或者组织的域名倒写+工程名称
2.artifactId:当前项目的模块名称。
3.version:当前模块的版本
com.oracle.maven
Hello
0.0.1-SNAPSHOT
我们如何通过坐标到仓库中找打对应的JAR包
1.将GAV三个向量连接来
junit junit
4.12
test
仓库中的:junit/junit/4.12
仓库:
分类:
1.本地仓库
2.远程仓库
1.私服
2.中央仓库
3.中央仓库的镜像
仓库中的文件
1.maven的插件
2.我们自己开发的项目的模块
3.第三方框架或者工具的JAR包
依赖
:
Maven中最关键的部分,我们使用Maven最主要的就是使用它的依赖管理的功能。
1.依赖的目的是什么
当A JAR包引用到了B JAR包,这个时候A就对B产生了依赖。
2.依赖的范围
存在三个选项:
1.compile:编译的阶段就必须存在
2.test:编译的时候可以没有但是测试的时候是要求存在的
3.provided:编译的时候可以没有,测试的时候可以没有,但是部署的时候需要有
生命周期
Maven的声明周期定义了各个构建环节的执行顺序,有这个顺序清单,maven就可以自动的执行构建命令。
Maven有三套相互独立的生命周期,分别是:
1.clean life:在进行真正的构建之前进行一些清理的工作
2.default life:构建的核心部分,编译、测试、打包、安装、部署等等
3.site life:生成项目的报告,站点,发布站点等。
以上三种生命周期都是相互独立的,我们可以仅仅调用clean来清理工作目录,或者是仅仅调用site来生成站点。当然我们也可以运行mvn clean install site将三个生命周期全部运行
每一套生命周期都是由一组阶段组成,平时在命令行输入的命令会对应一个特定的阶段。比如,运行mvn clean,这个clean是clean生命周期的一个阶段。有clean的生命周期就有clean的阶段。
clean的生命周期,一共包含了三个阶段:
1.pre-clean:执行一些需要在clean之前完成的工作。
2.clean:移除所有上一次构建生成的文件。
3.post-clean:执行一些需要在clean之后立刻完成的工作
site生命周期:
1.pre-site:执行一些需要在生成站点文档之前的工作。
2.site:生成项目的站点文档。
3.post-site:执行一些需要在生成站点文档之后完成的工作,并且为部署做准备。
4.site-deploy:将生成的站点文档全部部署到特定的服务器上。
default生命周期,是Maven声明周期中最重要的一个,绝大部分的工作都是在这个声明周期中完成。
process-resources:复制并处理资源的文件,到目标目录,准备打包。
compile:编译项目的源代码
process-classes:将字节码复制目标目录
process-test-resource:复制并处理资源的文件,到目标的测试目录。
test-compile:编译测试的源代码
process-test-classes:将测试的字节码复制到目标目录
test:使用合适的单元测试框架进行测试,这些测试代码不会被打包或是部署
package:接受编译好的代码,打包成可发布的格式,Java程序:JAR Web:WAR
intall:将打好包安装到本地仓库,让其他的项目可以依赖。
deploy:将最终的包复制到远程的仓库,以便让其他的开发人员与项目共享或者是部署到服务器上。
生命周期与自动化构建:
运行任何一个阶段的时候,他前面的所有阶段都会被执行,例如我们运行mvn install的时候,代码会被编译、测试、打包。这就是maven为什么能够自动执行构建过程的各个环节的原因。此外,Maven的插件机制是完全依赖maven的生命周期的。
Maven的插件的设置:
由于MyEclipse已经很好的支持Maven的插件了,我们只需要将我们所要使用的Maven插件导入进来即可,导入的过程:
1.找到window–>preference–>MyEclipse–>Maven–>installations–>add–>Maven的路径即可–>确定
如何设置Maven默认的JDK版本:
找到Maven安装路径下的cofig文件夹,找到setting.xml:
<profile>
<id>jdk18</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>
maven的依赖
依赖传递的好处:
1.可以传递的依赖不必在每一个工程中都编写一遍,只需要在"最下面"的工程写一次就可以了。
2.注意:只有Compile范围的依赖是可以传递的,其他返回的不可以传递
依赖的排除:
排除依赖的场景:当我们在MakeFriend这个工程中将HelloFriend作为依赖的时候,会同时将HelloFriend所依赖的Hello以及Spring-Core当做自己的依赖,那么有些时候,当我们仅仅只需要HelloFriend本身而不要将HelloFriend所依赖的依赖进行传递的时候,我们可以选择将HelloFriend所依赖的哪些依赖进行排除。
依赖的原则:
1.作用:解决模块与工程之间Jar包冲突的问题。
2.情景1:
假设我们存在这样的一个工程模块结构,MakeFriend依赖于HelloFriend,HelloFriend依赖于Hello,在Hello中依赖Log4J1.2.4,在HelloFriend中依赖于Log4J1.2.6那么此时我们根据依赖的传递性,MakeFriend是依赖于Log4J1.2.4还是依赖于Log4J1.2.6?实际上,Maven采用了一个叫做就近依赖的原则,离着哪一个更近就依赖于哪一个。
3.情景2:
MakeFriend同时依赖HelloFriend和Hello,而HelloFriend依赖于Log4J1.2.6,hello依赖于Log4J1.2.4.此时由于HelloFriend与Hello与MakeFriend的距离是一样的,依赖于哪一个?实际上当距离是一样的时候,哪一个在依赖的声明的前面,就依赖于哪一个。
Maven统一管理依赖的版本号:
步骤:
1.在properties标签内使用自定的标签声明版本号
2.在需要统一版本的位置,使用${自定义的标签名}引用声明的版本号
Maven的继承:
假设我们现在有Hello、HelloFriend、MakeFriend三个Maven工程,在Hello中使用Junit4.0、在HelloFriend中使用Junit4.0,在MakeFried你中使用Junit4.1.并且这三个工程之间,存在着依赖的关系,MakeFriend依赖于HelloFriend,HelloFriend依赖于Hello。现在有一个需求,需要我们将三个工程的Junit版本都改为Junit4.9,那么怎么办??由于Junit是test范围的,而maven中除了Compile以外的范围依赖是不会传递的。所以利用依赖的传递我们是无法解决。将Junit的依赖提取到一个父工程中,在子工程中声明Junit依赖的时候,不指定依赖的版本,以父工程中统一设定的为准。
Maven的聚合
:
为什么要使用聚合?
将多个工程拆分为模块后,需要手动逐个安装到仓库之后才能生效。修改原码后需要逐个手动进行clean操作。而使用聚合之后就可以批量的进行Maven的工程的安装、清理等工作。
如何配置聚合:
<!-- 配置聚合 -->
<modules>
<module>子工程相对于父工程的路径</module>
...
</modules>