文章目录
Maven知识点
1:目前掌握的技术
2:目前的技术在开发中存在的问题【why】
- 一个项目就是一个工程
- 如果一个项目非常庞大,就不适合继续使用package来划分模块。最好是每一个模块对应一个工程,利于分工协作
- 借助于Maven就可以将一个项目拆分成多个工程
- 项目中需要的jar包必须手动复制到WEB-INF/lib目录下
- 带来的问题:同样的jar包文件重复出现在不同的项目工程中,一方面浪费存储空间,另外也让工程比较臃肿
- 借助Maven,可以将jar包仅仅保存在仓库中,有需要使用的工程引用这个文件接口,并不需要真的把jar包复制过来
- jar包需要别人替我们准备好,或到官网下载
- 不同技术的官网提供jar包下载的形式五花八门
- 有些技术的官网就是通过Maven或SVN等专门的工具来提供下载的
- 如果是以不规范的方式下载的jar包,那么其中的内容也是不规范的
- 借助于Maven可以以一种规范的方式下载jar包。因为所有知名框架或第三方工具的jar包以及按照统一的规范存放在了Maven的中央仓库中
- 以规范的方式下载的jar包,内容也是可靠的
- Tips:“统一的规范”不仅是对IT开发领域非常重要,对于整个人类社会都是非常重要的
- 一个jar包依赖的其他jar包需要自己手动加入到项目中
- FileUpload组件->IO组件。commons-fileupload-1.3.jar依赖于commons-io-2.0.1.jar
- 如果所有jar包的依赖关系都需要程序员自己非常了解清楚,会极大的增加学习成本
- Maven会自动的将依赖的jar包导入进来
3:Maven是什么【what】
-
Maven是一款服务于Java平台的自动化构建工具
- Make->Ant->Maven->Gradle
-
构建
-
[1]概念:以Java源文件、框架配置文件、JSP、HTML、图片等资源为原材料,去生产一个可以运行的项目的过程
- 编译
- 部署
- 搭建
-
[2]编译:Java源文件[User.java]->编译->Class字节码文件[User.class]->交给JVM去执行
-
[3]部署:一个BS项目最终运行的并不是动态Web工程本身,而是这个动态Web工程编译的结果
生的鸡->处理->熟的鸡
动态Web工程->编译、部署->编译的结果
开发过程中,所有的路径或配置文件中配置的类路径都是以编译结果的目录结构为标准的Tips:运行时环境
其实是一组jar包的引用,并没有把jar包本身复制到工程中,所以不是目录
-
-
构建过程中的各个环节
- 清理:将以前编译得到的旧的class字节码文件删除,为下一次编译做准备
- 编译:将java源程序编译成class字节码文件
- 测试:自动测试,自动调用junit程序
- 报告:测试程序执行的结果
- 打包:动态Web工程打war包,java工程打jar包
- 安装:Maven特定的概念–将打包得到的文件复制到“仓库”中的指定位置
- 部署:将动态Web工程生成的war包复制到Servlet容器的指定目录下,使其可以运行
-
自动化构建
4:安装maven核心程序
-
检查JAVA_HOME环境变量
C:\Users\28653>echo %java_home% C:\Program Files\Java\jdk1.8.0_221
-
解压Maven核心程序的压缩包,放在非中文和无空格的目录
-
配置Maven环境变量
- MAVEN_HOME或M2_HOME(向下兼容,防止一些奇怪的错误)
- path
- MAVEN_HOME或M2_HOME(向下兼容,防止一些奇怪的错误)
-
验证:运行mvn -v命令查看Maven版本
C:\Users\28653>mvn -v Apache Maven 3.6.2 (40f52333136460af0dc0d7232c0dc0bcf0d9e117; 2019-08-27T23:06:16+08:00) Maven home: D:\working\apache-maven-3.6.2\bin\.. Java version: 1.8.0_221, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk1.8.0_221\jre Default locale: zh_CN, platform encoding: GBK OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
5:Maven的核心概念
- 约定的目录结构
- POM
- 坐标
- 依赖
- 仓库
- 生命周期/插件/目标
- 继承
- 聚合
6:第一个Maven工程
-
创建约定的目录结构
Hello |---src |---|---main |---|---|---java |---|---|---resources |---|---test |---|---|---java |---|---|---resources |---pom.xml
- 根目录:工程名
- src目录:源码
- pom.xml:Maven工程的核心配置文件
- main目录:存放主程序
- test目录:存放测试程序
- java目录:存放java源文件
- resources目录:存放框架或其他工具的配置文件
-
为什么遵守约定的目录结构
-
Maven要负责我们这个项目的自动化构建,以编译为例,Maven要想自动进行编译,那么它必须知道java源文件保存在哪里
-
如果我们自定义的东西想要让框架或工具知道,有两种方法
-
以配置的方式明确告诉框架
-
遵守框架内部已经存在的约定
log4j.properties log4j.xml
-
约定>配置>编码
-
-
7:常用Maven命令
-
注意:执行与构建过程相关的Maven命令,必须进入pom.xml所在的目录
与构建过程相关:编译、测试、打包、…
-
常用命令
-
mvn clean#清理target
-
-
mvn compile#编译主程序
-
mvn test-compile#编译测试程序
-
mvn test#执行测试
-
mvn package#打包
-
mvn install#安装
-
mvn site#生成站点
-
Maven命令执行后target生成的产品
(classes:main编译的字节码;test-classes:test编译的字节码;surefire-reports:测试运行产生的报告;Hello-0.0.1-SNAPSHOT.jar:打成的jar包;maven-status:;maven-archiver:辅助性文件)
8:关于联网的问题
-
Maven的核心程序中仅仅定义了抽象的生命周期,但是具体的工作必须由特定的插件来完成,而插件本身并不包含在Maven的核心程序中。
-
当我们执行的Maven命令需要用到某些插件时,Maven核心程序会首先到本地仓库查找
-
本地仓库的默认位置:[系统当前用户的家目录].m2\repository
C:\Users\28653\.m2\repository
-
Maven核心程序如果在本地仓库中找不到需要的插件,那么它会自动连接外网,到中央仓库下载
-
如果此时无法连接外网,则构建失败
-
修改默认本地仓库的位置可以让Maven核心程序到我们事先准备好的目录下查找插件
-
找到Maven的解压目录\conf\settings.xml:
D:\working\apache-maven-3.6.2\conf\settings.xml
-
在settings.xml文件中找到标签
-
将从注释中取出,将内容修改为准备好的Maven仓库
-
9:POM
- 含义:project object Model:项目对象模型
- Dom Document Object Model:文档对象模型
- pom.xml对于Maven工程是核心配置文件,与构建过程相关的一切设置都在这个文件中进行配置
- 重要程度相当于web.xml对于动态Web工程
10:坐标
-
数学中的坐标:
- 在平面上使用x,y两个向量可以唯一定位平面中的任何一个点
- 在空间上使用x,y,z三个向量可以唯一定位空间中的任何一个点
-
Maven的坐标
-
使用下面三个向量在仓库中唯一定位一个Maven工程(g-a-v)
-
gruopid:公司或组织域名倒叙+项目名
<groupid>com.zdww.maven</groupid>
-
artifactid:模块名
<artifactid>Hello</artifactid>
-
version:版本
<version>1.0.0</version>
-
-
-
Maven工程的坐标与仓库中路径的对应关系
<groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.6.RELEASE</version>
org/springframework/spring-core/4.1.6.RELEASE/spring-core-4.1.6.RELEASE.jar
根据坐标找到jar包
11:仓库
- 仓库的分类
- 本地仓库:当前电脑部署的仓库目录,为当前电脑上所有的Maven工程服务
- 远程仓库
- 私服:搭建在局域网环境中,为局域网范围内的所有Maven工程服务
- 中央仓库:架设在Internet上,为全世界所有Maven工程服务
- 中央仓库的镜像:为了分担中央仓库的流量,提升用户访问速度
- 仓库中保存的内容:Maven工程
- Maven自身所需要的插件
- 第三方框架或工具的jar包
- 我们自己开发的Maven工程
12:依赖
-
Maven解析依赖信息时会到本地仓库中查找被依赖的jar包。
- 对于自己开发的Maven工程,使用
mvn install
安装后就可以进入仓库
- 对于自己开发的Maven工程,使用
-
依赖的范围
-
compile范围依赖
- 对主程序是否有效:有效
- 对测试程序是否有效:有效
- 是否参与打包:参与
-
test范围依赖
- 对主程序是否有效:无效
- 对测试程序是否有效:有效
- 是否参与打包:不参与
- 典型的例子:junit
-
provided范围依赖
- 对主程序是否有效:有效
- 对测试程序是否有效:有效
- 是否参与打包:不参与
- 是否参与部署:不参与
- 典型的例子:servlet-api.jar
-
13:生命周期
-
各个构建环节执行的顺序:不能打乱顺序,必须按照既定的正确顺序来执行
-
Maven的核心程序定义了抽象的生命周期,生命周期中各个阶段的具体任务是由插件来完成的。
-
Maven核心程序为了更好的实现自动化构建,按照这一特点执行生命周期的各个阶段:不论现在要执行生命周期中的哪一个阶段,都是从这个生命周期最初的位置开始执行
$mvn compile maven-resources-plugin:2.6:resources maven-compiler-plugin:3.1:compile
$mvn test maven-resources-plugin:2.6:resources maven-compiler-plugin:3.1:compile # maven-resources-plugin:2.6:testResources maven-compiler-plugin:3.1:testCompile maven-surefire-plugin:2.12.4:test ############测试报告 ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.zdww.maven.HelloFriendTest Hello lbs!I am John Hello lbs!I am John Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.088 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ################# #
$mvn package maven-resources-plugin:2.6:resources maven-compiler-plugin:3.1:compile maven-resources-plugin:2.6:testResources maven-compiler-plugin:3.1:testCompile maven-surefire-plugin:2.12.4:test ############测试报告 ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.zdww.maven.HelloFriendTest Hello lbs!I am John Hello lbs!I am John Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.088 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ################# # maven-jar-plugin:2.4:jar #
-
插件和目标
-
生命周期的各个阶段仅仅定义了要执行的任务是什么
-
各个阶段和插件的目标是对应的
-
相似的目标由特定的插件来完成
生命周期阶段 插件目标 插件 compile compile maven-compiler-plugin test-compile testCompile maven-compiler-plugin
-
-
可以将插件目标看作”调用插件功能的命令“
14:在Eclipse中使用Maven
-
Maven插件:Eclipse内置
-
Maven插件的设置
- installations:指定Maven核心程序的位置。不建议使用插件自带的Maven程序,而应该使用我们自己解压的那个
- user settings:指定conf/settings.xml的位置,进而获取本地仓库的位置
-
基本操作
-
创建Maven版的java工程
- 可以在settings.xml中找到标签修改,来改变Maven创建的项目jre版本
<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>
-
创建Maven版的Web工程
- 先按照Maven的Java创建方式创建,然后右键项目properties
- 先按照Maven的Java创建方式创建,然后右键项目properties
-
执行Maven命令
-
15:依赖【高级】
-
依赖的传递性
- 好处:可以传递的依赖不必在每个模块中都重复声明,在最基础的工程中依赖一次即可
- 注意:非compile范围的依赖不能传递,所以在各个工程模块中需要重复声明
-
依赖的排除
-
需要设置依赖排除的场合
-
依赖排除的设置方式
<exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions>
-
-
依赖的原则
-
作用:解决模块工程之间的jar包冲突问题
-
情景设定1:验证路径最短者优先原则
-
情景设定2:验证路径相同时先声明者优先原则(先声明:指dependency标签声明顺序)
-
-
统一管理依赖的版本
-
情景举例
这里对spring各个jar包的依赖版本都是4.0.0,如果需要统一升级为4.1.1,怎么办?手动修改容易出错 -
建议配置方式
-
properties标签内使用自定义标签统一声明版本号
<properties> <zdww.spring.version>4.0.0.RELEASE</zdww.spring.version> </properties>
-
在需要统一版本的位置,使用$(自定义标签名)引用声明的版本号
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${zdww.spring.version}</version> </dependency>
-
-
properties标签配合自定义标签声明数据的配置并不是只能用于声明依赖的版本号,凡是需要统一声明后再引用都可以使用
<properties> <zdww.spring.version>4.0.0.RELEASE</zdww.spring.version> <project.sourceEncoding>UTF-8</project.sourceEncoding> <lbs>test</lbs> </properties>
-
16:继承
-
现状
- Hello依赖的junit:4.0
- HelloFriend依赖的junit:4.0
- MakeFriend依赖的junit:4.9
- 由于test范围的依赖不能传递,所以必然会分散在各个模块工程中,很容易造成版本不一致
-
需求:统一管理各个模块工程对junit依赖的版本
-
解决思路:将junit依赖版本统一提取到“父”工程中,在子工程中声明junit依赖时不指定版本,以父工程中统一设定的为准,同时也便于修改
-
操作步骤
-
创建一个Maven工程为父工程。注意:打包的方式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> <groupId>com.zdww.maven</groupId> <artifactId>Parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> </project>
-
在子工程中声明对父工程的引用
<!-- 子工程中声明父工程 --> <parent> <groupId>com.zdww.maven</groupId> <artifactId>Parent</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 以当前文件为基准的父工程pom.xml文件的相对路径 --> <relativePath>../Parent/pom.xml</relativePath> </parent>
-
将子工程的坐标中与父工程坐标中重复的内容删除
-
在父工程中统一junit的依赖
<!-- 配置依赖的管理 --> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.0</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement>
-
在子工程中删除junit依赖的版本号部分
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency>
-
-
注意:配置继承后,执行安装命令时先安装父工程
17:聚合
-
作用:一键安装各个模块工程
-
配置方式:在一个“总的聚合工程”中配置各个参与聚合的模块,可以自建,也可以在父工程中
<!-- 配置聚合 --> <modules> <!-- 指定各个子工程的相对路径 --> <module>../Hello</module> <module>../HelloFriend</module> <module>../MakeFriends</module> </modules>
-
使用方式:在聚合工程的pom.xml文件上右键---->run as —>maven install
18:部署
<!-- 配置当前工程构建过程中的特殊设置 -->
<build>
<finalName>xyWeb</finalName>
<!-- 配置构建过程中需要的插件 -->
<plugins>
<plugin>
<!-- cargo是一家专门从事“启动servlet容器”的组织 -->
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.2.3</version>
<configuration>
<!-- 配置当前系统中容器的位置 -->
<container>
<containerId>tomcat7x</containerId>
<home>C:\tomact\apache-tomcat-7.0.63</home>
</container>
<configuration>
<type>existing</type>
<home>C:\tomact\apache-tomcat-7.0.63</home>
<!-- 如果tomcat端口默认值8080则不必配置该属性 -->
<!-- <properties>
<cargo.servlet.port>8083</cargo.servlet.port>
</properties>
-->
</configuration>
</configuration>
<!-- 配置插件在什么情况下执行 -->
<executions>
<execution>
<id>cargo-run</id>
<!-- 生命周期的阶段 -->
<phase>install</phase>
<goals>
<!-- 插件的目标 -->
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>