Maven聚合与继承实例详解


概述

在javaweb高速发展的今天,我们软件设计人员往往会用很多种方式对软件划分模块,目的就是为了能有清晰的设计和低耦合性的,高重用性的软件。Maven有很好的依赖管理系统(Dependency Management System)和项目生命周期的管理(Project Leftcycle),而其中的依赖管理是本文阐述和做出实例的重点。

实例背景

利用一个教程的上面的例子,给大家做讲解。Maven安装有两种方式,一种是直接到Maven官网下载自己电脑的操作系统相应的版本安装,不管是window,linux还是Max os同时官网安装教程也是挺不错的。另外一种是安装eclipse的maven插件,这个很多人都用过,eclipse上面的plugin也是琳琅满目,具体教程网上很多哈。我们今天讲解主要针对后面一种方式,在eclipse进行的搭建Maven项目的操作。对于刚刚接触Maven和不熟悉command行的同学来说,可以是直观的操作,很好。

Maven是apache的一个项目,所以也是源于服务java项目的一个开源工具。所以很多概念也是和java中的基本概念很是相似,比如说继承。我们说java中的父类和子类的关系,子类可以引用父类中非private的变量和方法。反映到Maven项目的搭建也是一样的。Maven中的parent定义的dependency,其中继承者是可以直接使用parent中的Maven Dependencies的。

被继承的Maven项目中的POM的部分定义是

<groupId>com.company</groupId>
<artifactId>company-project-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

继承的Maven项目中的POM的关键部分就是

<parent>
<groupId>com.taotao</groupId>
<artifactId>company-project-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>company-project-children</artifactId>

操作步骤

  1. 建立Maven的parent项目

填写group Id和artifact Id和选择Packaging

编辑web-parent中项目的pom文件
其中是创建Maven项目的时候有了,但是中的内容是后面添加的。是定义一个虚拟的资源,这个部分并不直接使用,而中的,它的会直接引用到中的各个resource的版本号。由于中的资源不会直接使用,我们会发现,即使我们定义完这些具体的资源,项目中也没有具体的Maven Dependencies的jar包出现。

<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>web-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 集中定义依赖版本号 -->
<properties>
<junit.version>4.12</junit.version>
<spring.version>4.1.3.RELEASE</spring.version>
<mybatis.version>3.2.8</mybatis.version>
<mybatis.spring.version>1.2.2</mybatis.spring.version>
<mybatis.paginator.version>1.2.15</mybatis.paginator.version>
<mysql.version>5.1.32</mysql.version>
<slf4j.version>1.6.4</slf4j.version>
<jackson.version>2.4.2</jackson.version>
<druid.version>1.0.9</druid.version>
<httpclient.version>4.3.5</httpclient.version>
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<jsp-api.version>2.0</jsp-api.version>
<joda-time.version>2.5</joda-time.version>
<commons-lang3.version>3.3.2</commons-lang3.version>
<commons-io.version>1.3.2</commons-io.version>
<commons-net.version>3.3</commons-net.version>
<pagehelper.version>3.4.2-fix</pagehelper.version>
<jsqlparser.version>0.9.1</jsqlparser.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<jedis.version>2.7.2</jedis.version>
<solrj.version>4.10.3</solrj.version>
</properties>
<!-- 只定义依赖的版本,并不实际依赖 -->
<dependencyManagement>
<dependencies>
<!-- 时间操作组件 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time.version}</version>
</dependency>
<!-- Apache工具组件 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>${mybatis.paginator.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<!-- Redis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<!-- solr客户端 -->
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>${solrj.version}</version>
</dependency>
</dependencies>
</dependencyManagemen>
<build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <!-- 资源文件拷贝插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.7</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!-- java编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <!-- 配置Tomcat插件 -->
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>t>
</project>

这个现象有点像java中interface,定义了变量和方法,但是不会直接使用,得有具体的class来实现。所以我们发现继承了的Maven项目如果在“实现”了parent maven的,就会直接的出现改jar包。

当然,如果第一次建立Maven项目,要等待很长时间去maven的网上资源库下载到相应的文件,所以不要着急。

2.创建子项目web-common

** 创建一个子项目,packagin要选择jar,parent project要选择要继承的maven project。packaging中有三种选项,一种是pom,一种是jar,一种是war。无论选择哪一种,最后都是maven项目,所有都带有pom配置文件。但是jar和war是会有其他一些文件(jar中有libraries, resources and accessories files like property files,而war将会被部署在一些服务容器上面,所以war有jsp, html, javascript** and other files necessary )

  • web-common的pom的文件会如下
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>web-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>web-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>


但是我们要添加部分内容


<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<!-- Apache工具组件 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
</dependencies>
  • Finish后,我们会看pom和war的Maven项目的不同

  • 到这里我们就会讲完了继承的关系了,继续讲解聚合。

现在我们新建一些工程来测试Maven聚合:


一、建立以pom为packaging的项目为,然后再以这一个项目为parent project来聚合其他子项目

  • 新建立一个以pom的项目

改写pom文件,依赖web-common,这样就可以将web-common中的jar包都实现过来,这个有点像 java中implement了一个接口后,在实现了吧。我们是packaging为pom的项目,所以也是给准备实现了该maven的project,做好铺垫吧。

<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>web-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

所以我们会看到项目的初始文件目录,很简单

二、我们接下来要根据上面建立的项目实现聚合的例子

  • 点击web-test这个项目,右键,新建一个maven的module

  • 创建一个来存放pojo的module部分,packaging为jar(不要选择pom或者war,具体看上一篇)

  • 点击finish

  • 这个时候,我们会发现web-test中的pom文件多了下面的内容
<modules>
<module>web-test-pojo</module>
</modules>
  • 说明我们把web-test-pojo已经聚合到web-test中去了。
  • 同时web-test-pojo的内容是继承了web-common中的部分内容,而web-test-pojo的pom其实是不用修改的。

三、同时我们再建立以web-test为基础的web-test-mapper和web-test- service的module,这个和步骤二是一模一样的,唯一有区别的地方就是建立完后要在pom文件中加入每个模块自己单独需要的dependencies。另外一个就是web- test-mapper是依赖于web-test-pojo,所以web-test-mapper中的dependencies是含有web-test- pojo的dependency,而web-test-service则是依赖于web-test-mapper。所以下面将展示web-test- mapper和web-test-service的pom文件。

web-test-mapper的pom文件如下:

<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web-test-mapper</artifactId>
<!-- 依赖管理 -->
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-test-pojo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>
</project>

web-test-service的pom文件

<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web-test-service</artifactId>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-test-mapper</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
</dependencies>
</project>

四、建立以war为基础的Maven项目,我们之前已经建立了三个以web- test为parent的Maven的jar的模块,但是要发布一个web项目,必须是有war包,war中才含有文件夹来存放前端的js,jsp等文件啦。和上面一样,在web- test上面创建module,不同的是,创建的packaging是war

  • 创建一个module

  • 选择war

  • 在pom文件中加入自己想要的dependency

<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web-test-web</artifactId>
<packaging>war</packaging>
<!-- 依赖管理 -->
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-test-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
</dependencies>
</project>

五、此时,我们可以看到web-test其实已经聚合四个module,四个module在web- test的基础建立起来,但是他们又是一个整体,所以,当项目发布的时候,其实以web-test为单位的。

<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>web-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<modules>
<module>web-test-pojo</module>
<module>web-test-mapper</module>
<module>web-test-service</module>
<module>web-test-web</module>
</modules>
</project>

六、其实到了这里,我们就把一个项目的聚合和模块被聚合的例子讲完了,但是如果要跑这个项目也是可以的。

  • 在web-test中pom的文件加入以下内容,将tomcat的插件配置到web-test中去
<build>
<!-- 配置插件 -->
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
  • 另外在,web-parent和web-common安装到本地的仓库中去
    在web-parent项目上面右键,然后run as

  • 然后在goal 填入install

  • 同样的步骤在web-common项目执行

  • 执行后,在web-test这个主项目中run下面的代码 clean tomcat7:run

最后就可以登陆看web-test中的首页了,继承与聚合实例测试完成。


原文链接:https://blog.csdn.net/gyshun/article/details/82052280