1: maven是什么?
maven是Apache公司的开源项目,是一个服务于Java项目的自动化构建工具,用来管理依赖与项目。
2: 好处
- 与传统项目相比,使用maven工程只会有自己编写的文件,不再项目中直接依赖本地jar,项目占用内存会很小。
- maven的两大核心:依赖管理->对Jar包的管理, 项目构建->
3:maven项目构建
原始的我们使用IDE给我们的界面进行项目的构建,编译,与发布,maven可以不依赖与IDE,通过命令在编码完成后就可以对项目进行编译,测试,打包,部署,
3.1: maven项目标准目录结构
eg: 以简单的helloworld为例,在没有IDE文件生成的情况下目录结构是这样的
- helloworld
- ---- src 项目的源码
- ---- main 我们主要的编写的源代码
- ---- Java Java源代码目录
- ---- resource 项目资源目录,配置文件等
- ---- webapp web项目的网页资源目录
- ---- main 我们主要的编写的源代码
- ---- test 做单元测试的源代码
- ---- Java 测试Java源代码目录
- ---- resource 测试的资源目录, 一般不使用。
- ---- pom.xml maven项目的核心配置文件
注:在没有配置的情况下,一般目录下都会有一个target目录,这个目录是项目编译后生成的目录,用于保存编译生成的文件,我们不需要考虑,他不是maven标准目录结构,
- ---- src 项目的源码
3.2: pom.xml文件
pom->Project Object Model项目对象模型 , 为xml文件,以各个节点定义约束maven的项目管理,是maven项目的核心配置文件,与构建过程相关的配置都在这个文件中。eg:
<?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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--自己工程的配置,组,模块,版本 名字,描述-->
<groupId>com.tian.learn</groupId>
<artifactId>SpringBoot-Learn</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot-Learn</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4. maven 依赖包的实现(依赖管理)
maven并不是不再使用所以依赖的jar包,而是做了远程依赖管理,
4.1: maven的远程实现
maven存在一个远程仓库,这个仓库中包含着各种各样的jar包,以供我们下载使用,我们可以
直接通过浏览器访问公共maven`仓库,直接下载自己需要的jar包,在maven中,可以通过配置
maven文件,在编译项目时,maven就会自动帮我们下载这些jar包,并添加到项目中,是项目
编译完成,但这些jar包并不会出现在我们的项目中,他会缓存在你的电脑的其他目录,所以你的
项目看起来仍旧没有任何jar包,在Linux中下载的jar包一般存在用户目录的.m2文件夹中。
4.2: maven中jar的定位
maven仓库中每个jar包都有其坐标,就像我们的一样,我们的地理位置是一步一步缩小
的,eg:北京市朝阳区xx大街,我们的jar坐标也是这样的,例如fastjson包,在
maven中配置为:
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
可以看到引入一个包需要三个值确定,一般我们命名时是,groupId(com.公司名+项目名),artifactId(模块名), version(模块的版本号)。通过这三个坐标我们就能引入一个jar包。
5: 仓库
5.1: 仓库保存的文件
- Maven自身所需要的插件
- 第三方矿建或者工具的jar包
- 我们自己开发的maven工程
5.2: 仓库类型
maven为了项目构建的方便,实现了三种仓库,
- 本地仓库:程序员自己电脑上的仓库,一般你通过maven配置过的jar都会存在这里,也是maven自己首先要找的地方。
- 私有仓库:公司为了保存公司使用的全部的jar而建立的自己的仓库,一般都是存在与公司局域网内,也可以保存公司自己的不方便方便发布到中央仓库的jar。
- 中央仓库:存在与互联网,几乎多有的公共的jar都存在与这里,我们需要的jar一般也在这里下载到私有仓库或者我们的本地仓库。
- 中央仓库的镜像:与中央仓库一样,只是不同的网络地址,是中央仓库的另一份。
jar加载顺序:每次我们配置我们需要的jar时,maven都会由小及大的寻找我们的jar,先从本地仓库,再到私有仓库,最后才从中央仓库寻找,那个仓库先寻到就从那个仓库下载。
6:maven的常用命令
- mvn clean: 清理某个项目编译生成的文件,一般会删除target目录 。
- mvn compile: 编译,将项目中的Java文件编译为.class文件。
- mvn test : 执行单元测试方法,
- mvn test-compile: 编译单元测试程序
- mvn package: 项目打包操作,项目不同打包生成不同的包,分web项目war包,Java项目jar包
- mvn install : 同样是打包操作,但是打包后会将打包的文件同步到程序员的本地仓库。
7:maven项目的声明周期
在执行maven项目的install命令时就会完全执行maven的生命周期,但maven的各个生命周期又相互独立,可以单独执行。
- CleanLifeCycle:清理生命周期,就是clean命令周期
- pre-clean: 执行一些需要在clean之前完成的工作
- clean: 移除所有上一次构建生成的文件
- post-clean:执行一些需要在clean之后马上完成的工作。
- defaultListCycle: 默认的生命周期
编译(compile)、测试(test)、打包(package)、下载(install)、部署(deploy) - siteLifeCycle:站点声明周期
- pre-site:执行一些需要在生成站点文档之前完成的工作。
- site:命令,生成一个HTML文档,来描述这个项目使用了那些jar包
- post-site:执行一些需要在site之后马上完成的工作。
- site-deploy:将生成的站点文档部署到特定的服务器上。
8:maven的pom.xml
maven每个项目中的pom.xml是最核心的项目配置文件,它可以确定项目的jdk版本,项目名字,项目版本,依赖包等内容,
eg :添加一个依赖包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
eg: 配置项目的默认jdk版本
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
9: 依赖范围
当引入jar包时,给他指定依赖的范围,就能确定他在什么程序的什么时间,地点出现,例如在web
开发中,我们引入了servlet-api包,但我们的tomcat自己就有这个包,这时就不需要我们引入这个包时在运行是这个包也存在,所以指定这个引入范围为provided,这个项目打包的时候,servlet-api包就不会打包到项目包中。
依赖范围 | 对编译有效 | 对测试有效 | 对运行有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | N | Y | N | Junit,无法进行依赖传递 |
provided | Y | Y | N | servlet-api |
runtime | N | Y | Y | JDBC驱动 |
system | Y | Y | N | 本地maven仓库之外的类库 |
jar的引入默认的依赖范围为compile,指定jar的依赖范围方式为
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
<scope>provided</scope> <!--scope为指定jar的依赖范围-->
</dependency>
10: maven概念模型
maven概念模型就是对上面所有内容的总结,包含两大核心依赖管理和项目管理,依赖管理包含
三种仓库信息,项目管理包含项目构建build,项目构建的命令,其实都是由maven的插件提供的,从而产出各种项目文件。
二:maven提高
1: maven依赖的传递性
### 1.1: 传递性
假设有maven项目A,项目B依赖项目A,项目C依赖项目B,那么我们就说项目C依赖项目A,也就是说项目依赖关系为C--->B--->A,项目C也可以使用项目A中的类,这就是依赖的传递性。
1.2: 传递依赖冲突的解决
依赖冲突:导入项目依赖jar时,maven会自动导入依赖jar所依赖的jar,这就是maven的优势,但有时,两个jar会同时依赖同一个jar,这就会有两个相同的jar被依赖,这就造成项目中的依赖冲突。
-
maven对依赖冲突的自己解决
- 第一声明优先原则:即如果出现冲突,谁在pom.xml中自上而下优先声明的添加到依赖中,其他的自动废弃。
- 路径近着优先:这里的路径指的是项目直接依赖路劲或者是因为传递依赖而添加的依赖,这样算下来,直接依赖的路径更近,所以当有依赖冲突时,我们可以把某一个传递依赖的jar提取歘来,自己添加直接依赖,这样maven会优先选择路径近的添加依赖。
-
排除依赖
- 通过使用exclusions标签将传递依赖中的jar包排除掉
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.24</version> <exclusions> <!--在这里排除传递依赖中的jar包--> <exclusion> <groupId>org.spring.framework</groupId> <artifactId>spring.beansd</artifactId> </exclusion> </exclusions> </dependency>
- 版本的锁定(推荐使用):就是指定项目中依赖项的版本,统一管理依赖的版本
需要pom.xml中添加一个节点dependencyManagerment,这里指定的jar版本为依赖的最终版本,这里可以管理导入的直接依赖,也可以管理传递依赖。<!--需要添加的节点--> <dependencyManagerment> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> </dependencies> </dependencyManaggerment>
- 通过使用exclusions标签将传递依赖中的jar包排除掉
2:定义常量
可以在pom.xml中添加节点properties来定义常量,在pom.xml中使用时是${常量名字}, 因为xml文件是从上而下的,所以常量一般都定义在使用前面。
<!--定义,添加properties节点-->
<properties>
<version>1.8</version>
<user.name>tian</name>
<age>23</age>
</properties>
<!--使用-->
<dependency>
<groupId>${user.name}</groupId>
<version>${version}</version>
</dependency>
3:聚合
多个maven模块聚集在一起,一起操作就叫做聚合
- 在父模块中引用子模块
<!--使用modules标签引入子模块--> <modules> <module>../childPath</module> <!--指定子模块的相对路径--> </modules>