Maven使用
Maven的作用
1. 自动构建标准化的java项目结构
(1) 项目结构
① 约定目录结构的意义
Maven为了让构建过程能够尽可能自动化完成,所以必须约定目录结构的作用。例如:Maven执行编译操作,必须先去Java源程序目录读取Java源代码,然后执行编译,最后把编译结果存放在target目录。
② 约定大于配置
Mave对于目录结构这个问题,没有采用配置的方式,而是基于约定。这样会让我们在开发过程中非常方便。如果每次创建Maven工程后,还需要针对各个目录的位置进行详细的配置,那肯定非常麻烦。
目前开发领域的技术发展趋势就是:约定大于配置,配置大于编码。
(2)项目创建
选择Maven(使用的版本是Idea 2020.1.1)
输入项目名,选择项目的存储文件夹
选择maven的相关信息
坐标
坐标对于一个maven项目是唯一的
<groupId>org.example</groupId>
<artifactId>learingmaven</artifactId>
<version>1.0-SNAPSHOT</version>
坐标的命名方法(约定)
<!--
对于一个工程就是一个项目的情况
groupId: 域名反过来 如 com.baidu
artifactId:项目的名字 如 baiduwenku
version: 版本号,这一般由运维人员指定, 1.0-SNAPSHOT 是最初的快照版本的意思,还有1.0-RELEASE(发布版本)
对于一个工程项目中的一个模块的情况 (如百度文库这个项目有前端,后端,公共模块)
groupId: 域名反过来,后面再加上模块名 如 com.baidu.qianduan
artifactId:模块的名字 如 qianduan
version: 版本号,这一般由运维人员指定, 1.0-SNAPSHOT 是最初的快照版本的意思,还有1.0-RELEASE(发布版本)
-->
2. 帮助管理java中jar包的依赖
利用远程仓库管理所有jar包。 解决jar包依赖中版本冲突的问题(利用依赖传递的特性)
(1) 配置使用
依赖引入
引入依赖时会首先查看本地仓库是否存在对应的jar包,存在直接使用,不存在则从网上下载到本地仓库中,如果网上也不存在则报错
java中的jar包是通过在配置文件中配置相关依赖引入的,配置需要的信息就是坐标信息(groupId, artifactId,version)。
查询地址 maven查询官网,搜索对应的包,选择版本,复制对应的依赖到配置文件即可。
依赖标签<dependency>需要被大标签<dependencies>包裹,如下
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
刷新可以更新配置的依赖,进入对应的jar包
下载的jar包可以在本地仓库找到
属性配置
通过properties里面加入变量标签引入属性,这样可以便于版本信息的复用和更改
(2) maven指令
指令 | 作用 |
---|---|
clean | 清楚生成的target文件 |
validate | 校验 |
compile | 编译 |
test | 执行测试单元(Test开头的类) |
package | 项目打包(jar,war等) |
install | 把项目安装到本地仓库中 |
maven指令执行时是安装顺序执行的,比如要执行compile指令,则会先执行clean和validate指令,执行install指令则会执行他前面的那些指令。
(3) 依赖的范围
依赖的范围注意是依赖中<scope> </scope>指定
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api}</version>
<scope>provided</scope>
</dependency>
这个依赖的范围一般在中央仓库( maven查询官网)处就会有说明。
依赖范围有
- 编译(main/java)
- 测试 (main/test)
- 运行/打包
范围指定的关键词
编译 | 测试 | 打包 | 例子 | |
---|---|---|---|---|
test | × | √ | × | junit 测试 |
provided | √ | √ | × | servlet(因为tomcat上有servlet所以不需要打包) |
compile | √ | √ | √ | 默认的依赖范围 |
runtime | × | √ | √ | 反射方法,如数据库驱动 class.forName() |
system | √ | √ | × | 功能类似provided,不会依赖仓库中的jar包,而是引用本地物理路径的jar包,路径由<sysyemPath>\指定 |
(4) 依赖传递
如图,意思就是A项目引用B,B项目的依赖会条加到A中。但是,如果B项目中的依赖范围限定为test或者provided(说白了就是不被打包)的话,依赖就不会传递给A。
当然依赖中也有一个标签<optional>用于说明是否进行传递(默认值为false,进行传递)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>false</optional>
</dependency>
(5) 依赖的排除和覆盖
如果不想要引用项目上传的相关依赖包的话,可以使用上面说到的限制依赖范围和使用标签<optional>,但是这两种方法都是修改到了被引用项目B的源码。如果源码B不可更改的情况下可以使用下面两个方法
- 使用<exclusions>标签
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>false</optional>
<exclusions>
<exclusion>
<groupId> 排除包1 </groupId>
<artifactId> 排除包1 </artifactId>
</exclusion>
<exclusion>
<groupId> 排除包2 </groupId>
<artifactId> 排除包2 </artifactId>
</exclusion>
</exclusions>
</dependency>
- 直接在自己的项目里面指定需要的包
这种方法只需要正常写就行,指定包的groupId, artifactId, version。就可以覆盖掉依赖传递上来的包。
(6) 项目聚合
项目聚合就是通过一个项目管理多个模块,这样如果A依赖与B,B发生改变的时候就不需要对A和B进行重新编译,会自动进行。
而且这样可以使用项目各个模块在同一个文件中,方便编码。
①创建管理项目
② 删除maven自动构建的src文件(因为这个项目只是作为管理用的,不进行代码编写)
③ 在管理文件夹下右键点击model,创建模块
创建前端模块
创建后端模块
创建完成的目录
在聚合项目parent的配置文件中加入<modules>标签,告知聚合的模型名
十分重要: 在聚合项目中一定一定要把打包方式改变为pom,不然会报错
<?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>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>frontend</module>
<module>backend</module>
</modules>
</project>
完成上面的配置后,直接对聚合项目执行maven指令,他的子项目也会执行对应的操作。
(7) 项目继承
继承主要是用于各个模块可能没有联系,但是需要进行部分依赖的版本统一,如各个模块mysql驱动版本要一致。继承和聚合是可以同时存在的。
- 继承可以在创建模块时选择需要继承的父配置
- 可以在子配置中添加<parent>标签
这样子模块就会继承父模块的依赖。
如果存在子模块不想继承父模块中某些依赖的情况时(父模块中的模块并不是子模块都需要的模块)
父模块中的模块并不是子模块都需要的模块,这种情况下就需要把非必须依赖放在父模块配置文件的<dependencyManagement>标签中。
<?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>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>frontend</module>
<module>backend</module>
</modules>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
在使用时则只需要在子模块中正常加入依赖即可,只不过是省略了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>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>frontend</module>
<module>backend</module>
</modules>
<!-- 管理所有jar包的版本号-->
<properties>
<mysql-connector-java.version>8.0.23</mysql-connector-java.version>
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
</properties>
<!-- 模块公共依赖放这-->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
</dependencies>
<!-- 模块非必须依赖放这-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
3. 实现项目的快速部署
这里说明了功能,过程可自行查找。