maven知识总结

maven知识总结

1、repository

也就是我们说的仓库,分为本地仓库和远程仓库。

本地仓库这个想必大家都知道这个就不说了。

远程仓库是什么呢?

所谓远程仓库,就是我们本地仓库没有对应的jar(maven从仓库中下载的不单单是jar,还有其他如pom等等其他文件,这里就简单用jar表示maven下载的所有文件)时,maven就会从远程仓库去下载,并存储到本地仓库中。

下面我们具体看下是怎么配置的。

<repository>   <id>spring</id>   <url>https://maven.aliyun.com/repository/spring</url>   <releases>     <enabled>true</enabled>   </releases>   <snapshots>     <enabled>true</enabled>   </snapshots> </repository> 

上面的是阿里云仓库中的一个repository配置。具体位置在https://developer.aliyun.com/mvn/guide

具体在settings.xml中配置如下图。

repository不仅可以配置到settings.xml中,也可以配置到maven工程的pom.xml

maven知识总结


2、mirror

也就是我们说的镜像,在https://developer.aliyun.com/mvn/guide也能看到有个mirror配置。

<mirror>   <id>aliyunmaven</id>   <mirrorOf>*</mirrorOf>   <name>阿里云公共仓库</name>   <url>https://maven.aliyun.com/repository/public</url> </mirror> 

我们需要的文件maven也会从这个mirror中去下载。

既然mirrorrepository都可以下载jar,那它们的区别是什么呢。

一般来说,maven在本地仓库找不到jar时,就会通过repository指定的地址去远端下载。

但是当我们配置了mirror后,如果mirrorOf中的内容和repository中的id匹配,这时,就不会从repository指定的url下载。会从mirror指定的url去下载。

具体mirrorOf的匹配规则有下面几种。

  • *匹配所有 repo id。
  • external:* 匹配所有存储库,除了那些使用 localhost 或基于文件的存储库。 当您要排除为集成测试定义的重定向存储库时使用此选项。
  • 从 Maven 3.8.0 开始,external:http:* 匹配所有使用 HTTP 的存储库,但使用 localhost 的存储库除外。
  • 使用逗号作为分隔符指定多个存储库
  • 感叹号可以与上述通配符之一结合使用以排除存储库 ID。

下面看个例子:

<mirror>   <id>aliyunmaven</id>   <mirrorOf>*,!repo1</mirrorOf>   <name>阿里云公共仓库</name>   <url>https://maven.aliyun.com/repository/public</url> </mirror> 

上面的<mirrorOf>*,!repo1</mirrorOf>就表示除了idrepo1的仓库外,其他都会从https://maven.aliyun.com/repository/public这个路径中去下载。

换句话说也就是所有的jar包只会在mirror指定的urlidrepo1的仓库指定的url中去下载。


下面我们具体看个例子。

1.先看下settings.xml的设置。

<?xml version="1.0" encoding="UTF-8"?>  <settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd"> <localRepository>/Users/xxx/Documents/software/repo</localRepository>  <mirrors>    <mirror>       <id>aliyunmaven</id>       <mirrorOf>!jcenter,*</mirrorOf>       <name>阿里云公共仓库</name>       <url>https://maven.aliyun.com/repository/public</url>     </mirror>   </mirrors>      <profiles>       <profile>       <id>jdk</id>       <repositories>           <repository>               <id>jcenter</id>               <url>https://maven.aliyun.com/repository/jcenter</url>               <releases>                 <enabled>true</enabled>               </releases>               <snapshots>                 <enabled>true</enabled>               </snapshots>           </repository>       </repositories>   </profile> </profiles>      <activeProfiles>     <activeProfile>jdk</activeProfile>   </activeProfiles> </settings>  

settings.xml中``mirrorOf设置的是!jcenter,*,表示所有jar都会从仓库idjcenter设置的url中和mirror设置的url`中查找。


下面我再新建个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>org.example</groupId>     <artifactId>mavendemo</artifactId>     <version>1.0-SNAPSHOT</version>      <properties>         <maven.compiler.source>11</maven.compiler.source>         <maven.compiler.target>11</maven.compiler.target>     </properties>     <dependencies>         <dependency>             <groupId>org.yaml</groupId>             <artifactId>snakeyaml</artifactId>             <version>1.28</version>         </dependency>     </dependencies> </project> 

我们在maven工程目录下,执行mvn package打包命令,就会发现jar包优先会从仓库idjcenter设置的url下载。

maven知识总结


如果我们把上面的settings.xmlmirrorOf标签内容顺序做个调整,改成<mirrorOf>*,!jcenter</mirrorOf>。从本地仓库中删除刚才下载的jar,重新执行mvn package,就会发现优先从mirror中指定的url中去下载。

再比如,我把pom.xml中需要下载的jar修改为一个不存在的jar,可以看到maven会按照mirrorOf中指定的顺序依次去查找,如果全都找不到,就会提示失败。

    <dependencies>         <dependency>             <groupId>org.mytest</groupId>             <artifactId>mytestmvn</artifactId>             <version>1.28</version>         </dependency>     </dependencies> 

我把我本地pom.xml中依赖的jar改成了上面这样,再去重新执行mvn package.

maven知识总结

从上面红框处就能确认下载顺序是和我们mirrorOf指定的顺序是一致的。

从上面也能发现当我们配置了多个仓库时,maven是如何知道jar存在于哪个仓库的。就是简单粗暴的按照配置的先后顺序依次尝试去下载。

3、profile

我们可以通过设置多个profile标签来定义各种不同的配置。

可以通过activeProfile标签来激活配置。也可以在profile标签内通过activeByDefault标签设置配置默认是否激活,同时也可以设置条件,具体就不展开了。这部分内容可以查看官方文档profile章节

4、dependencyManagement

当我们一个项目的模块比较多时,为了避免不同模块引入jar版本混乱的问题,这时就需要通过dependencyManagement来解决。

这时我们就可以在项目顶级pom中使用dependencyManagement标签定义好所有子模块依赖的jar的版本。这样子模块需要对应的jar时,就不需要指定版本号。避免了不同子模块引入同一个jar不同版本的问题。同时如果jar的版本升级,直接在顶级pom中修改版本号就可以了,子模块根本不需要感知版本号的修改。

dependencyManagement标签内定义的只是管理依赖,并不会将里面的定义的jar作为工程依赖。

下面我们看个例子。

首先我们定义一个maven工程(工程名mavendemo),再定一个子模块(工程名childdemo)。

父工程mavendemopom.xml

maven知识总结

子工程childdemopom.xml

maven知识总结

5、Importing Dependencies

通过上面都知道maven工程可以通过父子关系来管理依赖。但是由于maven工程只能单继承。不能让一个maven工程同时依赖两个不同的父工程。这时就可以使用.Importing Dependencies来完成。

maven知识总结

6、超级POM

maven目录lib下,会有个maven-model-builder-3.x.x.jarjar。在这个jar里面会有个pom-4.0.0.xml的文件。这个就是超级pom。虽然我们的pom.xml中没有指定,但是所有的pom.xml都会直接或者间接继承这个超级pom。‘

maven知识总结

点看就能看到,这里面定义了默认的仓库地址、maven工程的目录结构、等等其他内容。

maven知识总结

这个目录结构是不是正好和我们idea生成的目录结构一致呢。

更多内容,查看官方文档

发表评论

相关文章