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
中
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
中去下载。
既然mirror
和repository
都可以下载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>
就表示除了id
为repo1
的仓库外,其他都会从https://maven.aliyun.com/repository/public
这个路径中去下载。
换句话说也就是所有的jar
包只会在mirror
指定的url
和id
为repo1
的仓库指定的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都会从仓库
id为
jcenter设置的
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
包优先会从仓库id
为jcenter
设置的url
下载。
如果我们把上面的settings.xml
中mirrorOf
标签内容顺序做个调整,改成<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
.
从上面红框处就能确认下载顺序是和我们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
)。
父工程mavendemo
的pom.xml
。
子工程childdemo
的pom.xml
5、Importing Dependencies
通过上面都知道maven
工程可以通过父子关系来管理依赖。但是由于maven
工程只能单继承。不能让一个maven
工程同时依赖两个不同的父工程。这时就可以使用.Importing Dependencies来完成。
6、超级POM
在maven
目录lib
下,会有个maven-model-builder-3.x.x.jar
的jar
。在这个jar
里面会有个pom-4.0.0.xml
的文件。这个就是超级pom。虽然我们的pom.xml
中没有指定,但是所有的pom.xml
都会直接或者间接继承这个超级pom。‘
点看就能看到,这里面定义了默认的仓库地址、maven
工程的目录结构、等等其他内容。
这个目录结构是不是正好和我们idea
生成的目录结构一致呢。
更多内容,查看官方文档