1. 插件仓库:
与依赖构件一样,插件构件同样基于坐标存储在Maven仓库中。值得一提的是,Maven会区别对待依赖的远程仓库与插件的远程仓库。当Maven需要的依赖在本地仓库不存在时,它会去所配置的远程仓库寻找。可是当Maven需要的插件在本地仓库不存在时,它就不会去这些远程仓库查找。
插件的远程仓库使用pluginRepositories和pluginRepository配置。例如Maven内置了如下的插件远程仓库配置:
<pluginREpositories>
<pluginREpository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>http://repol.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginREpository>
</pluginREpositories>
可以看到这个默认插件仓库的地址就是中央仓库,它关闭了对SNAPSHOT的支持,以防止引入SNAPSHOT版本的插件而导致不稳定的构建。
2. 插件的默认groupId:
在POM中配置插件的时候,如果该插件是Maven的官方插件(groupId为org.apache.maven.plugins),就可以省略groupId配置。不过这种做法不推荐。
3. 解析插件版本:
为了简化插件的配置和使用,在用户没有提供插件版本的情况下,Maven会自动解析插件版本。
首先,Maven在超级POM中为所有的核心插件设定了版本,超级POM是所有Maven项目的父POM,所有项目都继承了这个超级POM的配置,因此即使用户不加任何配置,Maven使用核心插件的时候,它们的版本就已经确定了。这些插件包括maven-clean-plugin、maven-compiler-plugin、maven-surefire-plugin等。
对于Maven3,当插件没有声明版本的时候,会解析至release。依赖Maven解析插件版本是不推荐的做法。在使用插件的时候,应该一直显式地设定版本。
4. 解析插件前缀:
插件前缀与groupId:artifactId是一一对应的,这种匹配关系存储在仓库元数据中。这里的仓库元数据为groupId/maven-metadata.xml,那么这里的groupId是什么呢?我们已经知道,主要的插件都是Apache和Codehaus提供,相应地,Maven在解析插件仓库元数据的时候,会默认使用org.apache.maven.plugins和org.codehaus.mojo两个groupId。也可以通过配置settings.xml让Maven检查其他groupId上的插件仓库元数据:
<settings>
<pluginGroups>
<pluginGroup>com.your.plugins</pluginGroup>
</pluginGroups>
</settings>
基于该配置,Maven就不仅仅会检查org/apache/maven/plugins/maven-metadata.xml和org/codehaus/mojo/maven-metadata.xml,还会检查com/your/plugins/maven-metadata.xml。
下面看一下插件仓库元数据的内容:
<metadata>
<plugins>
<plugin>
<name>Maven Clean Plugin</name>
<prefix>clean</prefix>
<artfactId>maven-clean-plugin</artfactId>
</plugin>
<plugin>
<name>Maven Compiler Plugin</name>
<prefix>compiler</prefix>
<artfactId>maven-compiler-plugin</artfactId>
</plugin>
<plugin>
<name>Maven Dependency Plugin</name>
<prefix>dependency</prefix>
<artfactId>maven-dependency-plugin</artfactId>
</plugin>
</plugins>
</metadata>
当Maven解析到dependency:tree这样命令后,它首先基于默认的groupId归并所有插件仓库的元数据org/apache/maven/plugins/maven-metadata.xml;其次检查归并后的元数据,找到对应的artifactId为maven-dependency-plugin;然后结合当前元数据的groupId为org.apache.maven.plugins;最后使用xx方法解析得到version,这时就得到了完整的插件坐标。如果org/apache/maven/plugins/maven-metadata.xml没有记录该插件前缀,则接着检查其他groupId下的元数据,如org/codehaus/mojo/maven-metadata.xml,以及用户自定义的插件组。如果所有元数据都不包含该前缀,则报错。