一、Maven加载原理
Maven工具会根据pom模型(pom.xml)加载当前项目需要使用的资源。
每次加载都是从本机某个指定的文件夹去加载。如果本机文件夹中没有这个资源,会从Maven远程服务器中下载到本机文件夹,Maven再去加载本机文件夹中资源。
专业概念: 中央仓库(Central Repository):Maven官方服务器。里面存放了绝大多数市面上流行的jar。也允许用户注册后,上传自己的项目到官方服务器。
本地仓库(Local Repository): 本机的文件夹。
镜像仓库(Mirror Repository):对于国内来说,访问国外的Maven仓库会特别慢。镜像仓库就是另一台备份/复制了中央仓库的服务器。平时使用时国内开发者多使用阿里云镜像或华为云镜像,这样可以大大提升从中央仓库下载资源的速度。
资源坐标:每个Maven需要使用的资源都有一个坐标,通过坐标可以精确告诉服务器需要的是哪个资源由三部分组成:
- GroupId:一般是逆向公司域名 com.zqwl。同一个公司的GroupId都是相同的。
- ArtifactId:一般是项目(jar)名 mysql-connector-java。
- Version:版本号 8.0.28。
二、Maven项目结构
三、pom.xml文件
<?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>com.gsy</groupId> <artifactId>mybatis-study</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> </project>
其中:
<project>
是根标签,必须得有的。
<modelVersion>
自动生成,指定pom默认版本。对于Maven 2.x、Maven 3.x中modelVersion必须是4.0.0。
<groupId>
、<artifactId>
、<version>
表示当前项目的坐标,里面信息都是在新建项目时填写的信息。
<packaging>是打包方式,默认为jar,如果是web项目应该指定war
四、Maven编译项目
执行comlpile(编译)后
会将编译后的项目输出到target目录,此时会存在一个问题:在src下的java包中java文件被编译成了字节码文件,但是存放一些其他类型的文件 例如xml文件并没有输出到target目录,
而在resources目录中的xml文件被输出到target目录中了且resources文件夹消失了。
这是由于Maven对于src中的java中只编译java文件,若需要编译输出其他类型文件,需要配置 深度资源拷贝 插件
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.txt</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build>
<build> <!-- 只要配置资源拷贝插件必须得配置的标签,里面可以有多个resource标签 --> <!-- 每个resource希望编译哪个目录--> <resources> <resource> <!-- 希望编译的目录 --> <directory>src/main/java</directory> <!-- Maven在这个目录原有功能不变,额外再添加其他的类型 --> <includes> <!-- 告诉Maven还需要编译什么类型的文件 --> <!-- ** 目录及目录,理解成任意子目录--> <!-- *.txt 中 * 任意名称文件,.txt 扩展名类型--> <include>**/*.txt</include> <!-- 如果还希望编译其他类型时再写个include标签 --> <!-- <include>**/*.xml</include>--> </includes> <!-- 是否在编译文件过程中,对文件内容进行过滤处理。是否对文件中内容进行操作 --> <filtering>true</filtering> </resource> <!-- 如果不配置,resources中内容不再进行编译 --> <!-- 只要配置上,把原有约定生效--> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build>解析
<build>
里面可以配置一些插件信息。
<directory>
配置的目录。
<includes>
标签明确配置哪些文件也需要被编译。**/*.txt
中**
表示任意目录及子目录。*.txt
表示任意名称的txt文件。如果希望编译其他类型的文件,例如xml文件,需要在<includes>
里面再配置<include>**/*.xml</include>
就可以了。
<filtering>
表示是否对拷贝的资源进行过滤。简单理解:对资源内容进行处理。例如:在文件中有{占位}编译后希望被解析,就需要设置为true。
五、Maven项目类型
1.项目类型介绍
Maven的项目类型有三种:
jar:相当于我们之前使用idea创建的java项目。打包主要打包.class文件。
war:web项目类型。打包时除了src中内容,还会包含webapp目录,要比jar类型文件打包的内容更多。
pom:聚合项目中使用。聚合项目中如果一个项目为父项目,项目类型应该为pom类型。当项目类型为pom类型时,表示该项目除了会配置pom.xml以外不会有任何其它类或资源文件。
2.修改项目类型
在pom.xml文件中通过<packaging>
设置项目类型。
小提示:
pom.xml中默认没有配置
<packaging>
标签。当没有配置<packaging>
时等效于<packging>jar<packaging>
。
六、pom模型中的几种关系
在POM模型中定义了三种关系:依赖、继承、聚合。
Maven基于POM模型的项目管理工具,所以这三种关系在Maven中都存在。
其中依赖关系可以说从学习完Maven每天都使用的,继承关系会在学习完Spring Boot后经常使用,聚合关系一般都出现在分布式、微服务架构的项目中。
1.依赖关系
当一个项目需要使用到其他项目的内容时,就可以使用依赖。
只要依赖的项目(可以是自己的项目,也可以是开源项目)存在于本地仓库,就可以通过pom.xml的<dependency>
标签填写坐标实现依赖关系。
1.1 依赖的传递性
假设项目A依赖项目B,项目B依赖项目C,这时会发现项目A中包含了项目C的依赖,这就是依赖的传递性。
1.2 重复依赖问题
当项目中依赖内容比较多时,可能出现重复依赖的问题,尤其依赖传递性导致的重复依赖。
2.继承关系
继承下项目分为父子关系。父项目的<packing>
打包方式可以为jar|pom,无论是jar还是pom,子项目只能继承父项目的pom.xml,并不能继承src/main下的内容,所以通常使用pom。
<packing></packing>
的选项:
-
pom:往往是作为父项目的角色,在父项目的pom.xml中统一管理子项目的依赖,插件,并不会将代码放到pom工程中。
-
jar:jar就是我们经常引入的jar包或引入的依赖,本质就是java项目中字节码文件,我们是调用它里面的类,一般的jar包只包含类,配置文件,依赖,插件,不会存在静态资源等。
-
war:本质就是web项目,跟jar不同的是它可以有静态资源的存在,比如Html,css,图片等等。
-
如果想要使用另一个项目的类,这种关系在Maven中叫做依赖。
-
如果想要使用另一个项目的依赖,插件,这种关系在Maven中叫做继承。
2.1 依赖和插件管理
在父项目中可以通过<dependencyManagement>
管理父项目中的依赖,子项目则可以指定继承那些依赖,当子项目需要这个依赖时坐标<version>
可以省略。
在父项目中可以通过<pluginManagement>
管理父项目中的插件,子项目则可以选择继承哪些插件。
在项目规模比较大,依赖或插件比较多时使用依赖管理、插件管理很有必要。
子类可以选择性的继承依赖,并且子项目继承了父项目中依赖的版本,只需要在父项目中修改一下版本,其他所有子项目的依赖版本全部变化,大大缩短工作量。
2.2 统一版本管理
<properties>
是<project>
的子标签。
<mysql-version>
名称是自定义的,里面的8.0.27是自己填写的。
可以在<dependency>
标签的<version>
中通过${属性标签名}获取到定义的属性值。
小提示:
好处是:项目中依赖特别多时,还需要由父项目进行版本管理。可以把所有依赖的版本号都定义到
<properties>
里面,以后想要修改某个依赖版本时,找起来比较方便。因为很多开源项目中涉及到父项目进行版本管理时,都使用的是
<properties>
这种方式。
3. 聚合关系
聚合关系的前提:继承。
聚合主要用在分布式架构或微服务架构的项目,对于单体架构项目来说很少使用聚合项目。
聚合项目最大的好处:在一个父项目中创建多个模块,所有的模块都是独立的,可以独立运行。且父项目不需要install,子模块就可以继承父项目的pom中的依赖。
七、Maven生命周期(面)
Maven有三套相互独立的生命周期(Lifecycle ):
-
Clean Lifecycle:做一些清理工作;
-
Default Lifecycle:构建的核心部分、编译、测试、打包、部署等;
-
Site Lifecycle:生成项目报告、站点、发布站点;
其中Default Lifecycle包含如下阶段:
-
validate
- 验证项目是否正确并且所有必要的信息都可用 -
compile
- 编译项目的源代码 -
test
- 使用合适的单元测试框架测试编译的源代码。这些测试不应该要求打包或部署代码 -
package
- 将编译后的代码打包成可分发的格式,例如 JAR。 -
verify
- 对集成测试的结果进行任何检查,以确保满足质量标准 -
install
- 将包安装到本地存储库中,作为本地其他项目的依赖项 -
deploy
- 在构建环境中完成,将最终包复制到远程存储库以与其他开发人员和项目共享
生命周期的每个阶段必须按照严格的执行顺序,当然我们可以执行任意一个阶段,但是每个阶段都会从第一个阶段开始执行。
八、scope (面)
1.scope介绍
在pom.xml中<dependency>
标签有一个<scope>
子标签,表示当前依赖的域(域:有效范围)。
scope可取值:
取值 | 解释 |
---|---|
compile | 默认值,不配置scope时的取值,表示依赖参与整个项目的编译、打包、测试、发布。也就是说:编译时需要使用、测试时需要使用、最终打包时会包含。属于一种强依赖。 |
provided | 仅编译时生效,项目最终被打包时不会包含该依赖。常见servlet的依赖时需要配置。 |
runtime | 运行时生效。表示编译时不参与,但是参与项目的测试、打包。该依赖被打包时会被包含。 |
test | 仅测试时生效,这个包中的类只能在src/main/test中使用。常用在junit依赖时需要被配置。 |
system | 类似provided,但是需要结合systemPath属性,表示依赖不是来源于本地库,而是来源于其他目录。使用较少,在一些特殊项目中才可能被使用。 |
使用:
在pom.xml中配置依赖时添加<scope>
标签就可以了。
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> </dependencies>
2. Maven的Web项目引用servlet依赖时的注意事项
问题:
项目中需要导入servlet-api和jsp-api作为编译时使用,使用Maven的Tomcat插件时,插件本身已经包含了servlet-api和jsp-api。
如果这两个依赖设置scope为compile,打包后在插件的tomcat中就出现了两个servlet-api和jsp-api,访问servlet时会报错。
所以在导入servlet-api和jsp-api时一定要设置scope为provided,表示只在编译时生效,而不会被打包到项目中。
标签:xml,依赖,项目,Maven,编译,pom From: https://www.cnblogs.com/giaogiaoyang/p/17753169.html