For investors
股价:
5.36 美元 %For investors
股价:
5.36 美元 %认真做教育 专心促就业
Maven插件解析运行机制
这里昆明达内培训的老师给大家详细说一下Maven的运行机制,让大家不仅知其然,更知其所以然。
1.插件保存在哪里?
与我们所依赖的构件一样,插件也是基于坐标保存在我们的Maven仓库当中的。在用到插件的时候会先从本地仓库查找插件,如果本地仓库没有则从远程仓库查找插件并下载到本地仓库。
与普通的依赖构件不同的是,Maven会区别对待普通依赖的远程仓库与插件的远程仓库。前面提到的配置远程仓库只会对普通的依赖有效果。当Maven需要的插件在本地仓库不存在时是不会去我们以前配置的远程仓库查找插件的,而是需要有专门的插件远程仓库,我们来看看怎么配置插件远程仓库,在pom.xml加入如下内容:
1 <pluginRepositories>
2 <pluginRepository>
3 <id>nexus</id>
4 <name>nexus</name>
5 <url>http://192.168.0.70:8081/content/groups/public/</url>
6 <releases>
7 <enabled>true</enabled>
8 </releases>
9 <snapshots>
10 <enabled>true</enabled>
11 </snapshots>
12 </pluginRepository>
13 </pluginRepositories>
大家可以发现,除了pluginRepositories和pluginRepository与以前配置远程仓库不同以外,其他的都是一样的,所代表的含义也是一样的。Maven的父POM中也是有内置一个插件仓库的,我现在用的电脑安装的是Maven 3.0.4版本,我们可以找到这个文件:${M2_HOME}/lib/maven-model-builder-3.0.4.jar,打开该文件,能找到超级父POM:\org\apache\maven\model\pom-4.0.0.xml,它是所有Maven POM的父POM,所有Maven项目都继承该配置。
我们来看看默认的远程插件仓库配置的是啥:
1 <pluginRepositories>
2 <pluginRepository>
3 <id>central</id>
4 <name>Central Repository</name>
5 <url>#/maven2</url>
6 <layout>default</layout>
7 <snapshots>
8 <enabled>false</enabled>
9 </snapshots>
10 <releases>
11 <updatePolicy>never</updatePolicy>
12 </releases>
13 </pluginRepository>
14 </pluginRepositories>
默认插件仓库的地址就是中央仓库咯,它关闭了对snapshots的支持,防止引入snapshots版本的插件而导致不稳定的构件。一般来说,中央仓库所包含的插件完全能够满足我们的需要,只有在少数情况下才要配置,比如项目的插件无法在中央仓库找到,或者自己编写了插件才会配置自己的远程插件仓库。
2.插件命令运行解析
我们来看这样一个命令:
mvn compiler:compiler
这个命令会调用maven-compiler-plugin插件并执行compiler目标,大家有木有觉得很神奇?我们在pom.xml中配置插件往往是这样:
1 <plugin>
2 <groupId>org.apache.maven.plugins</groupId>
3 <artifactId>maven-compiler-plugin</artifactId>
4 <version>3.1</version>
5 <configuration>
6 <source>1.7</source> <!--源代码使用的开发版本-->
7 <target>1.7</target> <!--需要生成的目标class文件的编译版本-->
8 </configuration>
9 </plugin>
maven-compiler-plugin插件默认执行的目标为compiler,那么命令的完整写法应该是:mvn org.apache.maven.plugins:maven-compiler-plugin:3.1:compiler才对啊,为什么mvn compiler:compiler也能完美的执行?
我们来看看Maven到底干了些神马来做到如此牛逼的功能:
①插件默认groupId
Maven默认以org.apache.maven.plugins作为groupId,到这里我们的命令应该是长这样的:
mvn org.apache.maven.plugins:compiler:compiler
我们也可以配置自己默认的groupId,在Maven的settings.xml中添加如下内容,前面提过最好将settings.xml放在用户目录的.m2下:
1 <pluginGroups>
2 <!-- pluginGroup
3 | Specifies a further group identifier to use for plugin lookup.
4 <pluginGroup>com.your.plugins</pluginGroup>
5 -->
6 <pluginGroup>com.your.plugins</pluginGroup>
7 </pluginGroups>
不过说实在的,没必要动他就别去动他了,我们用Maven只是解决一些刚需的问题,没必要的设置就尽量不去动他,别把Maven搞得太复杂,虽然Maven的却有点小复杂,跟大家扯这些只是希望大家能够对maven理解的更深入那么一点点,并不是建议大家一定要去使用某些东西,大家在平时的开发中要谨记这一点。
②我们来看看Maven插件远程仓库的元数据org/apache/maven/plugins/maven-metadata.xml,Maven默认的远程仓库是#/maven2/,所有插件元数据路径则是:#/maven2/org/apache/maven/plugins/maven-metadata.xml,我们找到compiler插件的元数据,
这里会根据prefix指定的前缀找到对应的artifactId,到这里我们的命令应该长成了这样:
mvn org.apache.maven.plugins:maven-compiler-plugin:compiler
③我们再根据groupId和artifactId找到maven-compiler-plugin插件单个的元数据,路径为#/maven2/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml,
maven将所有的远程插件仓库及本地仓库元数据归并后,就能找到release的版本(maven3后为了保证项目构建的稳定性默认使用release版本),到这里命令就被扩展成为这样:
mvn org.apache.maven.plugins:maven-compiler-plugin:3.6.0:compiler
如果执行的是mvn compiler:compiler命令,由于maven-compiler-plugin的最新版本已经到了3.6.0,则默认会使用此版本。最后的compiler则是插件要执行的目标咯,看到这里大家应该明白mvn compiler:compiler命令为什么能够得到完美的运行了吧。
3.Maven超级POM
最后给大家把超级父POM贴出来,再次强调,如果我们没有在自己的pom.xml中配置相应的内容,则默认会使用超级父POM配置的内容。我现在用的电脑安装的是Maven 3.0.4版本,我们可以找到这个文件:${M2_HOME}/lib/maven-model-builder-3.0.4.jar,打开该文件,能找到超级父POM:\org\apache\maven\model\pom-4.0.0.xml,它是所有Maven POM的父POM,所有Maven项目都继承该配置。
很多插件是超级父POM当中并没有配置的,如果用户使用某个插件时没有设定版本,那么则会根据我上述所说的规则去仓库中查找可用的版本,然后做出选择。在Maven2中,插件的版本会被解析至latest。也就是说,当用户使用某个非核心插件且没有声明版本的时候,Maven会将版本解析为所有可用仓库中的最新版本,latest表示的就是最新版本,而这个版本很有可能是快照版本。
当插件为快照版本时,就会出现潜在的问题。昨天还好好的,可能今天就出错了,其原因是这个快照版本发生了变化导致的。为了防止这类问题,Maven3调整了解析机制,当插件没有声明版本的时候,不再解析至latest,而是使用release。这样就避免了由于快照频繁更新而导致的不稳定问题。但是这样就好了吗?不写版本号其实是不推荐的做法,例如,我使用的插件发布了一个新版本,而这个release版本与之前的版本的行为发生了变化,这种变化依然可能导致我们项目的瘫痪。所以使用插件的时候,应该一直显式的设定版本,这也解释了Maven为什么要在超级父POM中为核心插件设定版本咯。
了解详情请登陆昆明达内IT培训官网(km.tedu.cn)!