这里给大家详细说一下Maven的运行机制,让大家不仅知其然,更知其所以然。
1.插件保存在哪里?
与我们所依赖的构件一样,插件也是基于坐标保存在我们的Maven仓库当中的。在用到插件的时候会先从本地仓库查找插件,如果本地仓库没有则从远程仓库查找插件并下载到本地仓库。
与普通的依赖构件不同的是,Maven会区别对待普通依赖的远程仓库与插件的远程仓库。前面提到的配置远程仓库只会对普通的依赖有效果。当Maven需要的插件在本地仓库不存在时是不会去我们以前配置的远程仓库查找插件的,而是需要有专门的插件远程仓库,我们来看看怎么配置插件远程仓库,在pom.xml加入如下内容:
12 3 13nexus 4nexus 5http://192.168.0.70:8081/content/groups/public/ 67 9true 810 12true 11
大家可以发现,除了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项目都继承该配置。
我们来看看默认的远程插件仓库配置的是啥:12 3 14central 4Central Repository 5http://repo.maven.apache.org/maven2 6default 78 10false 911 13never 12
默认插件仓库的地址就是中央仓库咯,它关闭了对snapshots的支持,防止引入snapshots版本的插件而导致不稳定的构件。一般来说,中央仓库所包含的插件完全能够满足我们的需要,只有在少数情况下才要配置,比如项目的插件无法在中央仓库找到,或者自己编写了插件才会配置自己的远程插件仓库。
2.插件命令运行解析
我们来看这样一个命令:
mvn compiler:compiler
这个命令会调用maven-compiler-plugin插件并执行compiler目标,大家有木有觉得很神奇?我们在pom.xml中配置插件往往是这样:
12 org.apache.maven.plugins 3maven-compiler-plugin 43.1 56 9
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下:
12 6 com.your.plugins 7
不过说实在的,没必要动他就别去动他了,我们用Maven只是解决一些刚需的问题,没必要的设置就尽量不去动他,别把Maven搞得太复杂,虽然Maven的却有点小复杂,跟大家扯这些只是希望大家能够对maven理解的更深入那么一点点,并不是建议大家一定要去使用某些东西,大家在平时的开发中要谨记这一点。
②我们来看看Maven插件远程仓库的元数据org/apache/maven/plugins/maven-metadata.xml,Maven默认的远程仓库是,所有插件元数据路径则是:,我们找到compiler插件的元数据,如图:
这里会根据prefix指定的前缀找到对应的artifactId,到这里我们的命令应该长成了这样:
mvn org.apache.maven.plugins:maven-compiler-plugin:compiler
③我们再根据groupId和artifactId找到maven-compiler-plugin插件单个的元数据,路径为,如图:
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项目都继承该配置。
1 2 3 21 22 2324 1504.0.0 25 2627 37 3828 36central 29Central Repository 30http://repo.maven.apache.org/maven2 31default 3233 35false 3439 52 5340 51central 41Central Repository 42http://repo.maven.apache.org/maven2 43default 4445 47false 4648 50never 4954 94 95${project.basedir}/target 55${project.build.directory}/classes 56${project.artifactId}-${project.version} 57${project.build.directory}/test-classes 58${project.basedir}/src/main/java 59src/main/scripts 60${project.basedir}/src/test/java 6162 6663 65${project.basedir}/src/main/resources 6467 7168 70${project.basedir}/src/test/resources 6972 73 74 9375 9276 79maven-antrun-plugin 771.3 7880 83maven-assembly-plugin 812.2-beta-5 8284 87maven-dependency-plugin 852.1 8688 91maven-release-plugin 892.0 9096 98 99${project.build.directory}/site 97100 101 148 149102 147release-profile 103 104105 110 111106 109performRelease 107true 108112 146113 145114 125true 115maven-source-plugin 116117 124118 123attach-sources 119120 122jar 121126 137true 127maven-javadoc-plugin 128129 136130 135attach-javadocs 131132 134jar 133138 144true 139maven-deploy-plugin 140141 143true 142
很多插件是超级父POM当中并没有配置的,如果用户使用某个插件时没有设定版本,那么则会根据我上述所说的规则去仓库中查找可用的版本,然后做出选择。在Maven2中,插件的版本会被解析至latest。也就是说,当用户使用某个非核心插件且没有声明版本的时候,Maven会将版本解析为所有可用仓库中的最新版本,latest表示的就是最新版本,而这个版本很有可能是快照版本。
当插件为快照版本时,就会出现潜在的问题。昨天还好好的,可能今天就出错了,其原因是这个快照版本发生了变化导致的。为了防止这类问题,Maven3调整了解析机制,当插件没有声明版本的时候,不再解析至latest,而是使用release。这样就避免了由于快照频繁更新而导致的不稳定问题。但是这样就好了吗?不写版本号其实是不推荐的做法,例如,我使用的插件发布了一个新版本,而这个release版本与之前的版本的行为发生了变化,这种变化依然可能导致我们项目的瘫痪。所以使用插件的时候,应该一直显式的设定版本,这也解释了Maven为什么要在超级父POM中为核心插件设定版本咯。
结束语:当你感到悲哀痛苦时,最好是去学些什么东西,学习会使你从悲哀痛苦中走出来,学习会使你永远立于不败之地。说实在的,不要太在意眼前所发生的一切,更重要的是培养自己的个人能力,如今待在公司亦或者跳槽,决定你能不能继续走下去的一定是你的个人能力,作为年轻人,在公司更看重的不应该是薪水的高低,而是公司能给你带来多大的成长环境。找个好的公司其实不比找个合适的女朋友简单,作为年轻人我们一定要不断的提升个人能力,就跟找女朋友似的,往往就是你越有本事就越能够不将就,你个人能力越强则越有选择公司的资本。
可爱博主:AlanLee
博客地址:
本文出自博客园,欢迎大家加入博客园。