Maven
1.约定的目录文件
约定大于配置
我们要遵守Maven的规定的目录结构,因为Maven负责项目的自动化的构建,以编译为例,Maven想要自动编译,那么它肯定得知道我们的Java源文件的位置
目录概述:
src: 源码
---------main
-----------java :Java文件
-----------resources :配置文件
---------test :测试程序
pom.xml :依赖配置文件
示意图
2.常用命令
项目周期包括 编译——>测试——>打包——>安装,执行一个命令都是自动的从头开始执行的,比如运行打包命令时,自动的先运行编译测试
注意:运行下面的命令必须在POM.xml目录下
①-------编译----------------------------
mvn compile 会下载所有的依赖,并编译src/main下的所有源文件,生成一个target目 录
mvn test-compile 编译src/test/java下的测试类,也放在target目录下
②-------测试----------------------------
mvn test 测试程序 运行src/test/java下的所有程序 (先编译在测试)
③--------打包--------------------
mvn package 对项目进行打包生成一个jar或者war包(先编译在测试在打包),放在target 目录下
mvn package -DMaven.test.skip=true 跳过测试打包
④---------安装-------------
mvn install 将打成的jar/war包安装到本地仓库中,便于其他的项目进行依赖
坐标就是按照pom文件中配置的GAV
mvn install -Dmaven.test.skip=true:跳过测试安装
⑥-------清理--------
mvn clean 清理target目录下的文件
3.POM文件
当你在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>
<!--关于本模块的一些描述信息-->
<description>xxx</description>
<!--指明项目的打包方式-->
<packing>jar</packing>
<!--本项目的GAV-->
<groupId>org.example</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<!--抽取一些配置信息-->
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!--导入依赖的位置-->
<dependencies>
<!--导入依赖的GAV-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>
</project>
4.坐标
Maven使用三个向量唯一定位一个Maven工程(Jar包)
groupid :公司或者组织的域名倒序
artifactId : 一般都是项目名
version : 版本号
实例
<!--Mybatis依赖(Maven工程)-->
<dependency>
<!--网站名称倒写-->
<groupId>org.mybatis</groupId>
<!--模块名称 一般都是工程名-->
<artifactId>mybatis</artifactId>
<!--版本号-->
<version>3.4.1</version>
</dependency>
Maven工程的坐标(GAV)与仓库中路径的关系
groupid+artifactId+version
代表的就是在仓库中的路径
artifactId+version
代表的就是项目名称
所以以上面的Mybatis为例,它在仓库中的路径就是
org/mybatis/mybatis/3.4.1/mybatis-3.4.1.xxx
5.依赖的范围
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
<!-- 默认是compile
<scope>compile</scope>
<scope>test</scope>
<scope>provided</scope> -->
</dependency>
compile范围的依赖
对主程序和测试程序有效,参与打包(主程序参与打包,测试程序不参与打包) 参与部署
test范围的依赖
只对测试程序有效,对于主程序无效,不参与打包 (典型的就是Junit)不参与部署
provided范围的依赖
对于主程序和测试程序都有效,不参与打包, 不参与部署 (典型的就是Servlet-api.jar ,在运行时Tomcat服务器可以给你提供)
6.仓库
本地仓库和远程仓库
-
本地仓库
本机的Maven仓库
-
远程仓库
1、私服(一种私服:Nexus) : 搭建在
局域网
环境中,为局域网内的Maven工程服务2、中央仓库 : 架设在Internet上,为全世界所有的Maven工程服务
3、中央仓库镜像(阿里云镜像等):架设在各个大洲,为中央仓库分担流量,减轻中央仓库的压力,同时有更快的访问速度
仓库中保存的内容
- Maven自身所需要的插件
- 第三方框架或工具的jar包
- 我们自己开发的Maven工程
(Maven install)
7.构建/生命周期/插件/目标
项目构建
- 清理 : 将以前编译得到的旧的class文件删除,为下一次编译做准备
- 编译 : 将Java源文件编译成class字节码文件
- 测试 : 自动测试,自动调用Junit程序
- 报告 : 测试程序执行的结果分析
- 打包 : Web工程打War包,Java工程打jar包
- 安装 : Maven中的概念—>将打包完成的jar或war包安装到仓库中 以便其他的工程使用
- 部署 :将动态Web工程生成的war包复制到Servlet容器的指定目录下,使其可以运行
Maven的生命周期
大体上分为 -编译 -测试 -打包 -安装 -部署
- 各个构建环节执行的顺序,不能打乱顺序,必须按照指定的顺序
- Maven的核心程序中定义了抽象的声明周期,
生命周期中各个阶段的具体任务是由插件来完成的
- Maven核心程序为了更好的实现自动化构建,按照这一特点执行生命周期中的各个阶段,
不论现在要执行生命周期中的那一阶段,都是从这个生命周期最初的位置开始执行
例如我现在执行安装命令,那么maven从编译开始一直运行到安装
插件和目标
- 生命周期的各个阶段仅仅定义了要执行的任务是什么
- 各个阶段和插件的目标是对应的
- 相似的目标由特定的插件来完成
可以将目标看做"调用插件功能的命令"
生命周期阶段 | 插件目标 | 插件 |
---|---|---|
compile | complie | maven-compiler-plugin |
test-compile | testCompile | maven-compiler-plugin |
。。。 |
8.依赖的传递
- 我们在开发时可能有很多的模块,比如在电商项目中的购物车模块,后台模块,商品模块等,这些模块可能都需要Spring的依赖 Mybatis的依赖 等等,那么就可以单独的抽取一个公共模块让它去导入这些依赖,然后在我们的购物车模块,后台模块,商品模块等依赖这个公共模块,然后公共模块的这些依赖就可以传递到我们的各个模块中。
依赖的传递是多层的,就像Java的继承一样
注意:非compile范围的依赖不能传递
好处
每个模块都使用的依赖不必在每个模块中重复的声明。
<?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>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--导入我们自己的公共模块,本模块也就有了公共模块的依赖-->
<dependency>
<groupId>com.shwsh</groupId>
<artifactId>common</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
9.依赖的排除
当我们导入了某个依赖A时,这个依赖A可能依赖了某个依赖B,但是我们的工程不能导入依赖B,可能会导致某些问题,就需要使用依赖的排除
<?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>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--导入我们自己的公共模块,本模块也就有了公共模块的依赖-->
<dependency>
<groupId>com.shwsh</groupId>
<artifactId>common</artifactId>
<version>1.0</version>
<!--排除这个依赖中的某些依赖 比如我想排除Mybatis的依赖-->
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
.....排除多个
<exclusion>
<groupId></groupId>
<artifactId></artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
10.依赖原则与冲突
依赖冲突遵循这两种原则:路径短者优先和声明优先
路径短者优先
A依赖了Spring4.1,还依赖了B,但是B中依赖了Spring4.2,那么按照路径短者优先,(即A要得到Spring的依赖需要一步,而得到B中的Spring依赖需要两步)那么A中只会依赖Spring4.1,(所以不必排除B中的Spring4.2这个依赖)
路径相同按照声明优先
A同时依赖了B和C,B中有Spring4.1,C中有Spring4.2,那么按照声明优先,如果在A的pom.xml文件中先声明了B,那么A就依赖B的Spring4.1,反之就依赖C的Spring4.2
11.统一管理依赖的版本号(本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>mybatis_sourcecode</artifactId>
<version>1.0-SNAPSHOT</version>
<!--第一步:在properties中自定义标签-->
<properties>
<spring.version>4.0</spring.version>
</properties>
<dependencies>
<!--第二步:在version中使用${自定义标签}-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
.....
</dependencies>
</project>
12.继承
使用父工程指定依赖的版本,子工程继承父工程,在子工程中导入依赖时就不必指明版本号了,一般在父工程中配合properties使用管理所有模块的依赖版本
注意:父工程由于只做版本的控制,所以此打包方式必须指定为pom
一般配合properties标签使用管理整个项目的依赖版本
注意:做了继承之后,要执行install操作,先对父工程进行install
父工程中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>dad</artifactId>
<version>1.0-SNAPSHOT</version>
<!--必须指定为pom-->
<packaging>pom</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<!--使用标签统一管理版本-->
<mysql-connector.version>5.1.47</mysql-connector.version>
</properties>
<!--使用dependencyManagement标签进行管理具体的依赖,dependencyManagement标签下配置的依赖仅仅作为管理,不会导入到本工程(即父工程)的运行环境中-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
子工程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>
<!--使用parent标签指定父工程的坐标 relativePath指定父工程的相对路径 可写可不写-->
<parent>
<artifactId>dad</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../dad/pom.xml</relativePath>
</parent>
<groupId>org.example</groupId>
<artifactId>son1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--因为父工程中指明了这个依赖的版本,所以子工程导入依赖时就不需要指明版本了-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
13.聚合
聚合就是将所有的模块一起进行操作在聚合工程的pom文件下执行的命令,所有聚合的模块一起执行 并且Maven会自动的分析各个模块之间的依赖关系 按照依赖关系执行
聚合工程也可以是父工程
聚合模块的packaging标签也必须指定为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>org.example</groupId>
<artifactId>dad</artifactId>
<version>1.0-SNAPSHOT</version>
<!--使用modules标签聚合各个模块,会自动分析其中的依赖关系-->
<modules>
<module>../son1</module>
<module>../son2</module>
</modules>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<mysql-connector.version>5.1.47</mysql-connector.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
</modules>