今天工作中遇到一个问题,开发中需要对公司研发的框架源码进行少量修改,想单独对变动的模块进行版本号修改,方便本地项目引用测试,原pom文件中<dependency>从父节点的 <dependencyManagement>中引用公共的依赖版本,现在使用<version></version>单独引用变动版本竟然没有覆盖<dependencyManagement>中声明的版本,怪哉怪哉,对maven依赖管理原则再次挖一挖学习记录下。
上面的问题,与springboot框架构建项目的时候有相似之处,都是使用<dependencyManagement>管理多个模块间的公共依赖,以构建springboot项目为例,平时使用springboot的时候其他pom依赖都没有配置version版本号,maven会默认到<dependencyManagement>找依赖包声明的版本,自动进行获取,如下图:
自动引包如果想自己指定版本号,常用方式一:在模块中用dependency 声明version,则 dependencyManagement 中的声会被覆盖,如下图查看可以确定引入的spring-boot-starter-freemarker版本一致:
指定版本号 指定版本引入成功常用方式二:使用<peoperties>指定版本号覆盖parent中的版本,前提是依赖需要在dependencies指定的列表中,指定引入依赖也生效了。
peoperties指定版本号网上查阅到,说依赖传递中<dependencyManagement>优先于传递依赖,也只是对于声明的版本号相同时,并不适用我遇到的不同版本号的场景。
再把问题点放到依赖范围上,进行排查,maven的常用6种依赖范围:
compile,默认范围,编译依赖对项目所有的classpath都可用。
provided,和compile范围很类似,但provided范围表明你希望由JDK或者某个容器提供运行时依赖。
runtime,runtime范围表明编译时不需要依赖,而只在运行时依赖。
test,test范围表明使用此依赖范围的依赖,只在编译测试代码和运行测试的时候需要,应用的正常运行不需要此类依赖。
system,系统范围与provided类似,不过你必须显式指定一个本地系统路径的jar,此类依赖应该一直有效,Maven也不会去仓库中寻找它。
上面6种都是单独作用一个依赖,我想引入的包使用的是默认compile作用范围,观察不出任何异常,
最后关注到Maven2.0.9以后引入的import作用域,该scope是为了解决maven不能多继承的问题,避免层层依赖下来,父模块中包含大量不需要的依赖。
使用import,把dependencyManagement放到单独的专门用来管理依赖的pom中,然后在需要使用依赖的模块中通过import scope依赖,就可以引入dependencyManagement,与我当前开发的项目设计完全相同,使用import可以使用非继承的方式引入自定义的dependencyManagement依赖管理配置,在我的项目中发现,既使用了这种非继承的方式引用了公共依赖,又使用了继承父模块中也重复引了一次公共依赖,导致了本文开头描述问题,前人挖坑,后人乘凉,感谢前辈们又小子学习了新知识,内牛满面。
网友评论