在《Maven权威指南》部分I中,第6、7章介绍了多模块项目及多模块企业级项目的构建思想。对于多模块的情况,无论是简单的或是企业级的,对于POM来说,重点就是分析处理好父POM与子POM之间的关系,包括依赖管理(DependencyManagement)、插件管理(PluginManagement)、兄弟模块直接的依赖关系。
对于多模块项目,首先要注意的就是在POM中标明父子关系。在父POM中,标明项目的坐标,包括artifactId,groupId及version信息;用<modules><module></module></modules>标签声明包括的子模块,module中的名称应与子POM中的artifcatId相对应。在子POM中除了定义本模块的<artifactId>,也要通过<parent>指明关联的父POM是哪一个。其次,对于父POM的packaging属性已不像之前章节中介绍的为jar,或war、ear等,而是pom。对于子模块生成的包,由子模块的packaging属性说明本模块要打包的类型。
上面的部分是为了说明多模块项目的父子关系,子模块中要用到的插件,依赖与前面章节说明的没有什么区别,所以这里就说一下对于多模块项目,尤其是有子模块相互依赖的情况下,POM的优化管理。
随着功能的不断壮大,一个模块牵扯的依赖、插件会越来越多,再有插件和依赖的版本也会发生变化,随之而来的问题就是POM中可能有重复使用的插件和依赖,或需要修改插件和依赖的版本,同一个插件用到的地方越多需要修改的地方也就越多,往往会遗漏,就会导致之后执行某一步的时候发生错误,这时候检查起来就比较费时费力且低效了。
对于依赖(Dependency),我们可以优化的情况有依赖重复、兄弟依赖。Maven提供了DependencyManagement的方式,将重复的部分上提至父POM中的dependencyManagement片段进行统一管理以预防依赖重复的发生。首先,找出在模块间被用于一个以上模块的依赖,上移植后需要为每个子POM移除这些依赖的版本,否则子模块中的version会覆盖父POM中声明的版本。如果依赖中包含了排除配置,在子POM中可忽略排除配置了。再有依赖重复的情况就是两个不同的依赖所用的版本是相同的,例如hibernate-annotation和hibernate-common-annotations,这两个依赖的版本都为3.3.0.ga。我们可以将版本提取出来以property变量的形式定义,在dependency中引用,从而达到减少修改次数的目的。对于兄弟依赖,即一个子模块可能依赖其他一个或一个以上的子模块,子模块版本的变化也会影响依赖于此模块的模块构建。为了统一,且由于子模块的groupId及version是统一的,所以对于兄弟模块之间的依赖,通过引用内建的groupId和version进行定义,即${project.groupId}和${project.version}。
对于插件(Plugin),与dependency有类似的情况。同一插件在多个模块中重复使用时,可用PluginManagement标签在父POM中统一管理。由于插件中可能包含对依赖的引用,若依赖被多次引用。例如hibernate3插件依赖了hsqldb,并在simple-command和simple-webapp中引用,但在上面提到的DependencyManagement中不支持对插件依赖的管理。我们使用属性定义的方式来固化hsqldb的version,就像在java中定义一个静态常量,直接引用,需要修改的时候只修改一次。
最后指南中又说明了如何通过dependency插件分析是否所有的依赖、插件被显示的声明,以防止在发生版本变化的时候发生编译或安装错误。
写的有点儿乱,我总结一下吧。基本的思想分为3点吧。
1. 把在多个地方用到的同一东西抽取出来放入父POM进行管理;
2. 对于相同version的依赖,用property属性进行统一定义,在插件、依赖中进行引用;
3. 经常通过Dependency插件对POM进行分析,做到POM的更新与项目实际情况保持一致,才能达到提高生产效率的目的。:)
这次先写到这里,由于指南中的代码很全,我就没有贴上来,建议大家对照着看,很清楚的。谢谢观赏,之后进入Maven具体参考部分,敬请期待,呵呵。