《maven实战》学习笔记6——maven聚合和继承

maven聚合

为什么要用maven聚合

随着互联网的发展,一个项目的业务复杂度越来越高,整个项目的业务代码也会越来越庞大,因此便有了把一个项目拆分成若干个子项目的需求。
根据之前的知识,clean、test、package、install等都是针对单独的项目,那么对于上边若干个子项目可能就需要执行若干次的clean、test、package、install等操作,而这些操作具有很高的重复性。
介于这样的前提,便需要使用到maven聚合,经过一定的配置后,可以让我们每一次clean或者test或者package等都同时对所有子模块生效,大大减少了重复工作。

maven聚合怎么用

根据上边的前提可以知道,属于同一个项目的子项目,或者说子模块,规范性的配置应该是他们groupId都一样,version也一样,只有artifactId不同。
例如有这样两个子项目mytest-project1、mytest-project2,他们的pom.xml的必要配置分别如下:
myporject1的pom.xml:

  <modelVersion>4.0.0</modelVersion>
  <groupId>my.maven.test</groupId>
  <artifactId>mytest-project1</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>mytest-project1 Maven Webapp</name>

myporject2的pom.xml:

  <modelVersion>4.0.0</modelVersion>
  <groupId>my.maven.test</groupId>
  <artifactId>mytest-project2</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>mytest-project2 Maven Webapp</name>

那么就可以再创建一个只有pom.xml的项目作为聚合这两个子项目的父项目,这个父项目的pom.xml的必要配置如下:

  <modelVersion>4.0.0</modelVersion>
  <groupId>my.maven.test</groupId>
  <artifactId>mytest-project0</artifactId>
  <packaging>pom</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>mytest-project0 Maven Webapp</name>
  <modules>
     <module>mytest-project1</module>
     <module>mytest-project2</module>
  </modules>

对比之下可以知道看到,这个父项目的配置中modelVersion、groupId、version都和子项目的一模一样。其他除开artifactId、name本身每个maven项目都应该不一样之外,还有packaging的值不一样,并且还多了一个modules属性,而packagingmodules这两个属性就是maven聚合最重要的属性了。
首先,用来作为聚合其他子项目的父级项目的packaging的值必须是pom,也只能是pom
然后modules中配置了需要聚合的子项目的列表。
如上边例子中配置的子项目列表是什么意思呢?比如<module>mytest-project1</module>,这个其实指像的是一个pom.xml文件,也就是工作空间/mytest-project0/mytest-project1/pom.xml,说的更简单点,就是需要把子项目mytest-project1放到mytest-project0里边。
那么如果mytest-project1和mytest-project0位于同级目录怎么办呢?这个聚合的modules里的配置就要该成这样:

<module>../mytest-project1</module>

由此其实可以看到,这个module里边的配置实际上就是一个相对路径,是相对于当前这个pom.xml(聚合项目的pom.xml)的相对路径。
例如<module>mytest-project1</module>,其实就是mytest-project0/pom.xml所在目录下的mytest-project1,而<module>../mytest-project1</module>,其实就是mytest-project0/pom.xml所在目录的上一级目录中的mytest-project1,../代表上一级目录,这个应该能来学maven的人都知道。
经过上边这样配置之后,那么我们只需要对这个聚合父项目进行clean等操作,就会同时对配置的各子模块生效,例如执行clean,那么mytest-project1和mytest-project2下边的target就都会被清理掉,执行package,那么mytest-project1和mytest-project2就都会执行package操作,然后在各自的target目录下生成各自的输出文件,这些结果在执行操作的时候就可以再控制台看到信息输出,例如执行clean,就会如下:

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] mytest-project1 Maven Webapp
[INFO] mytest-project2 Maven Webapp
[INFO] mytest-project0 Maven Webapp
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building mytest-project1 Maven Webapp 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mytest-project1 ---
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building mytest-project2 Maven Webapp 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mytest-project2 ---
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building mytest-project0 Maven Webapp 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mytest-project0 ---
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] mytest-project1 Maven Webapp ....................... SUCCESS [  0.164 s]
[INFO] mytest-project2 Maven Webapp ....................... SUCCESS [  0.004 s]
[INFO] mytest-project0 Maven Webapp ....................... SUCCESS [  0.003 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.272 s
[INFO] Finished at: 2017-11-14T15:07:59+08:00
[INFO] Final Memory: 6M/123M
[INFO] ------------------------------------------------------------------------

maven继承

maven继承的作用其实和java中继承的作用是类似的,基本上都是主要为了实现重用,java中类的继承,减少了重复的代码,而maven中的继承则减少了pom.xml的配置。
因此显而易见的是,这里所说的maven继承更确切的说,应该指的是pom.xml配置的继承。
说到继承,自然是需要有父类和子类,那么引申到这里,就需要有父的pom.xml和子pom.xml,例如我这里有一个父项目pom.xml的必要内容如下:

  <modelVersion>4.0.0</modelVersion>
  <groupId>my.maven.test1</groupId>
  <artifactId>mytest-project00</artifactId>
  <packaging>pom</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>mytest-project00 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-webmvc</artifactId>
         <version>4.3.9.RELEASE</version>
     </dependency>
  </dependencies>
  <build>
    mytest-project00</finalName>
  </build>

这个配置只显示的引用了spring-webmvc的依赖,所以会导入spring-webmvc及它所依赖的所有jar包,这个项目看起来和一个普通的maven项目几乎没有区别,唯一不同的就是,他的packaging和聚合一样也是pom才行。
那么如果我们有一个子项目也需要使用spring-webmvc,就可以继承这个项目的pom.xml,而不需要再另行配置spring-webmvc的依赖,例如子项目的pom.xml如下:

  <modelVersion>4.0.0</modelVersion>
  <groupId>my.maven.test1</groupId>
  <artifactId>mytest-project01</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT<
  <name>mytest-project01 Maven Webapp</name>
  <parent>
     <groupId>my.maven.test1</groupId>
     <artifactId>mytest-project00</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <relativePath>../mytest-project00/pom.xml</relativePath>
  </parent>
  <url>http://maven.apache.org
  <dependencies>
  </dependencies>
  <build>
    <finalName>mytest-project01</finalName>
  </build>

很明显的可以看到,上边的配置中并没有显示的配置任何依赖,但是多了一个parent的配置,而这个配置就是继承父项目的关键配置。
在parent中,groupId、artifactId、version这几个坐标的配置相信不用多说,关键在于relativePath,这个属性指定了maven父项目的pom.xml的路径,当然了,这里也是配置的相对于当前pom.xml的相对路径。
有了这个配置之后,mytest-project01不需要显示的配置对spring-webmvc的依赖,就会导入相应的依赖,也就是继承了mytest-project00的pom.xml的配置。

pom.xml中有很多的属性,这些属性并非都能继承,根据我目前的工作状况,我觉得需要知道有这么回事就好了,因此暂时便不做更深入的了解。
maven聚合和maven继承可以让我们的maven开发过程更加简洁,两个可以结合在一起使用,既然知道了怎么聚合,也知道了怎么继承,那么结合在一起使用应该就不用多说了。

推荐文章