聚合
所以这里的一个maven的解决方案,聚合功能,就是可以将各个模块,聚合成一个大的模块,给它一个父工程,父模块,那个父模块里面呢配置聚合了哪些子模块
只要对父模块运行一次构建命令,此时maven会自动对这个父模块下面的所有子模块都运行相应的构建命令,这样就可以保证一键自动化构建所有的模块,不要一个一个依次去构建。
如果要一次性构建多个模块的工程,那么就需要创建一个父工程,我们可以创建一个os-parent工程,在其pom.xml中加入以下内容:
<groupId>com.zhss.oa</groupId> <artifactId>oa-parent</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>oa parent project</name> <modules> <module>oa-organ</module> <module>oa-auth</module> <module>oa-flow</module> </modules>
一般来说会将模块统一放在父工程的目录下,这样就可以用上述形式,否则如果多个工程平级,则要用类似于../oa-organ的相对路径。
接着对oa-parent运行mvn clean install,此时就会对oa-parent中所有的工程都进行统一的构建
跟大家说,对于一个大型的工程来说,特别是你去看一些其他开源项目的源码,比如说知名的大数据开源计算框架,spark,它其实就是这种组织方式,源码外面就是一层,展开以后就是各个子模块。
前几天,有一个学员跟我说的一个问题
(1)他依赖了其他项目组的一个jar包
(2)他声明了对那个jar包的依赖,但是那个jar包也是有一个parent工程的
(3)本地的maven可以下载到那个jar包的依赖,但是下载不到对应的parent工程的东西
(4)当时他们那个项目组的同事,我觉得对maven也不是很精通,半吊子,仅仅部署了子工程的jar包到私服,但是父工程没有部署到私服
(5)所以那个学员当时说maven报错,下载不到parent一个依赖17294159
继承
maven里面提供了一个功能,叫做继承,也就是说,我们可以将一个项目中所有模块通用的一些配置,比如依赖和插件,全部放在一个父工程中,oa-parent,然后所有的子工程,声明一下从父工程中去继承
如果直接将所有的依赖放入父工程,然后子工程用<parent>元素声明继承,然后此时会强制性继承父工程中所有的依赖和插件。
但是实际的场景下,不同的工程需要的依赖是不一样的,可能有的工程需要从父工程继承20个依赖和3个插件;有的工程需要从父工程继承10个依赖和2个插件。如果按照上面那种最low最普通的做法,会导致每个子工程都强制性从父工程继承所有的依赖。
那么这就导致,本来某个子工程只要10个依赖,现在导致每次打包,assembly的大包,可能导致每个工程的jar包打包速度变慢,打完以后的包比较大。这种做法是很不好的,不推荐。
推荐的一个做法,是在父工程中,使用<depdendencyManagement>和<pluginManagement>两个元素,来声明要被子工程继承的依赖和插件
有一个好处,就是,如果子工程用<parent>元素声明继承父工程,此时不会强制性继承所有的依赖和插件,子工程需要同时声明,自己要继承哪些依赖和插件,但是只要声明groupId和artifactId即可,不需要声明version版本号,因为version全部放在父工程中统一声明,强制约束所有子工程的相同依赖的版本要一样。
将oa-organ、oa-auth、oa-flow三个工程的pom.xml中加入以下配置
<parent>
<groupId>com.zhss.oa</groupId>
<artifactId>oa-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
然后将所有工程相同的依赖和插件的配置,全部放入父工程中,此时子工程就会继承父工程的依赖和插件,不需要每个工程都重复定义,而且可以在父工程中统一约束所有依赖和插件的版本。
但是这里有个问题,如果直接将所有依赖和插件直接放入父工程,会导致子工程强制性继承,也许子工程并不需要某些依赖呢?
此时最好的做法,就是在父工程中,使用<dependencyManagement>元素和<pluginManagement>元素,来声明所有的依赖和插件。
此时在子工程中,就可以对自己需要的依赖进行声明,但是不用定义版本号,只要groupId和artifactId即可。这样声明之后才会继承依赖,而且版本由父工程约束。
提一点,这里很关键的一个知识点,是你要搞清楚,dependencyManagement和pluginManagement的意义在哪儿?一般来说,很多人都没搞清楚用上面说的那两个元素来进行继承,以及直接在parent里面放dependencies和plugins里面放依赖和插件来继承,他们俩的区别在哪儿?
如果在父工程中,直接用dependencies和plugins来声明依赖和插件,子工程会强制全部继承;如果用dependencyManagemnent和pluginManagement来声明依赖和插件,默认情况下,子工程什么都不继承,只有当子工程声明了某个依赖或者插件的groupId+artifactId,但是不指定版本时,才会从父工程继承那个依赖。在规范的工程管理中,肯定都是用dependencyManagement和pluginManagemnent的。