采用模板(archetype)的Maven项目加载慢的原因以及解决方案
是不是经常有人告诉你用模板(archetype)创建Maven项目的时候,要添加一个archetypeCatalog的属性(如下所示)
如果你也很懵逼,那么不妨继续看下去,或许会得到一些启发。
前言
首先需要说明的是,我并没有过多了解过Maven该怎么使用。目前我只是在用Intelli J 开发项目时用到了pom.xml来解决包依赖的问题,一些命令 如 mvn install ,mvn clean 我压根没用过。
先谈谈我的思路,首先我会试着写一下archetypeCatalog到底干嘛的,以及给出相应可能的解决办法。
archetypeCatalog?
archetypeCatalog是什么?
见名知意 模板目录。我们打开基于Maven创建项目的模板,如下所示,发现有很多种模板。
那我们可以猜想 archetypeCatalog必然与一个个模板有关。那internal是什么意思?为什么要给archetypeCatalog设置internal?
事实上,archetypeCatalog 对应三个值。分别是local,internal,remote。先记住有着三个值。
现在我们要搞清楚一件事情,就是Intelli J 是通过什么方式知道要创建的项目到底是什么样? 通过查找官方文档,我看到了这样一句话:
Knowledge about archetypes is stored in catalogs.
The catalogs are xml files: see the reference documentation.
The Archetype Plugin comes bundled with an internal catalog. This one is used by default.
The Archetype Plugin can use catalogs from local filesystem and from HTTP connections.
也就是说,属性archtypeCatalog实际上是对应了一份关于模板目录的xml文件 ,这份xml文件说明了应该创造什么样的模板。我截取这份文件的部分截图。
你会发现这个文件挺大的
而值internal 指的是 archetype插件内置有一份catalog。local指的是从本地文件系统去取xml文件,remote是从网上(也就是远端)获取。
进一步查找资料
The Archetype Plugin knows by default about its internal catalog. It also knows about the local and remote catalogs.
local represents the ~/.m2/archetype-catalog.xml catalog file.
remote represents the https://repo.maven.apache.org/maven2/archetype-catalog.xml catalog file.
The Archetype Plugin can also read catalogs from filesystem/HTTP by providing the path/URL of a catalog file or of a directory containing an archetype-catalog.xml file。
如上所示,archetype plugin 也就是 模板插件默认知道一份内部的模板目录。这个插件也能通过读取文件夹下的~/.m2/archetype-catalog.xml来知道模板目录,或是从中央仓库下读取catalog.xml来知道模板目录。
总之,archetype plugin 可以通过三种方式来获取模板目录,只有获取了模板目录,然后根据你自己提供的项目信息(如你的项目的artifact ID等等),才能创建一个基于模板结构的项目。
为什么Maven项目创建时很慢?
因为默认情况下,Intelli J 是从https://repo.maven.apache.org/maven2/archetype-catalog.xml去找catalog.xml ,而这个地址是哪里呢?就是大名鼎鼎的中央仓库,当然就很慢啦!
那为什么要设置archetypeCatalog的属性为internal?其实这里我不是很理解,因为我不知道那个plugin插件是什么东西(因为没用过)。但是我在Settings 里面看到了这个东西
除此以外,我还在官方文档看到如下信息
那我估计创建一个带模板的Maven项目 ,必然用到了archetype plugin ,而设置archetypeCatalog 的值为internal 的意思应该是直接获取archetype plugin内置的模板目录。当然,这里网上有人说是元数据,我不是很清楚,我就不乱说了。但是,这样的方式理论上是比从中央仓库直接获取模板目录要快。
那么local值就好解释了,我们只要把那份catalog.xml下载下来放在本地呗,然后将archetypeCatalog的值设置为local就行了(这样应该最快)。
解决方案
初步分析了这些情况,解决方案无非就是两种,一种是把那份catalog.xml下载到本地,然后每一次创建项目时设置archtypeCatalog 的值为local 或是通过一次设置将未来所有项目的archtypeCatalog都设置成为local。另一种办法无非就是每一次创建项目时将archtypeCatalog的值为internal ,或是通过一次设置将未来所有项目的archtypeCatalog都设置成为internal,当然这种方法不需要下载catalog.xml。
但是,我发现已经有大神用n种花式解法解决了问题,我贴个链接,大家自行去看
https://www.cnblogs.com/yachao1120/p/10847889.html
https://www.cnblogs.com/yachao1120/p/12354668.html
最后附录上官方的链接
https://maven.apache.org/archetype/index.html
https://maven.apache.org/archetype/maven-archetype-plugin/specification/archetype-catalog.html
http://maven.apache.org/archetype/maven-archetype-plugin/specification/generate.html
http://maven.apache.org/archetype/archetype-models/archetype-catalog/archetype-catalog.html