目录

  • 聚合的意义:
  • 创建聚合工程的要点(重点理解):
  • 继承的意义:
  • 继承(要点):
  • 总结:
  • 我们就用如下图来演示maven聚合工程:
  • 1、创建聚合工程整体架构
  • 1.1、首先在idea创建一个空项目
  • 1.2、创建ebuy-parent模块(管理项目所需依赖)
  • 1.3、创建ebuy-main模块(聚合工程的父级项目)
  • 1.4、分层创建模块(横向拆分)
  • 1.4.1、创建ebuy-pojo模块
  • 1.4.2、创建ebuy-dao模块
  • 1.4.3、创建ebuy-service模块
  • 1.4.4、创建ebuy-servlet模块(maven-web项目)
  • 1.5、查看ebuy-main模块中pom.xml文件
  • 2、测试聚合工程
  • 2.1、首先是dao层引用pojo层
  • 2.2、service层引用dao层
  • 2.3、servlet层引用service层
  • 2.4、简单测试
  • 3、maven聚合工程的优点


聚合的意义:

  • 对于一个大型的项目,如果我们直接作为一个工程开发,由于相互之间的依赖我们只能从头到尾由一组人开发,否则就会出现一个类好多人开发,相互更改的混乱局面,这个时候我们就将项目进行了横向纵向的拆分。
  • 横向拆分

所谓的横向的拆分就是我们平常说的三层架构,将每个功能模块分成三层去开发
即web层(表现层),service层(业务逻辑层)、dao层(数据访问层、持久层),
可以理解为将一个功能模块的不同调用过程(三层的调用)进行了水平方向的拆分。

  • 纵向拆分

所谓的纵向拆分就是将一个项目根据多个功能模块进行拆分,可以理解为,为了完成一个系统,深度(纵向)分析需要有哪些功能,然后将这些功能独立出来(独立为模块),进行了(纵向)拆分。

  • 横向和纵向拆分后,对每层架构和功能模块进行单独的开发,项目整合的时候就需要有一个能够整合这些架构或者模块的工程,这就是所谓聚合工程的意义。

创建聚合工程的要点(重点理解):

  1. 该聚合项目(父级项目、顶级项目)本身也是一个maven项目,它必须有自己的pom
  2. 它的打包方式必须是:pom
  3. 引入新的元素:modules—module(模块:每个模块其实也是一个项目
  4. 版本:聚合模块的版本要和被聚合模块的版本一致
  5. relative path:每个module名称都是一个当前pom的相对目录
  6. 目录名称:为了方便快速定位,模块所处的目录应当与其artifactId一致(maven约定而不是硬性要求),总之,模块所处的目录必须要和聚合模块中的模块目录保持一致。
  7. 聚合模块减少的内容:聚合模块的内容仅仅是一个pom.xml文件,它不包含src/main/java和src/test/java等目录,因为他只是用来将其他模块整合构建成一个整体的工具,本身并没有实质的内容。
  8. 聚合模块和子模块的目录:它们可以是父子级,也可以是平行结构(推荐)。默认是父子级结构,但是不建议使用,因为父子级是一种嵌套关系,子模块要建在父模块里面,维护起来很容易紊乱;推荐使用平行结构,是因为维护起来一目了然,条理比较清晰,当然同时要在pom文件的中修改相应的目录路径配置。
  9. 如果聚合模块对某一个子模块进行了删除操作,那么一定要在聚合模块的pom.xml文件中的modules选项中将对应的子模块删除掉。

继承的意义:

  • 我们知道 maven工程之间可以完成依赖的传递性,实际上就是各个jar包和war包之间存在依赖的传递性,但是必须是compile范围的依赖才具有传递性,才可以根据传递性统一管理一个依赖的版本。
  • 而对于test范围的依赖,只是孤零零的存在于某个项目中,各个项目中的依赖版本可能不同,容易造成问题,所以test范围依赖的统一版本的问题,通过依赖的传递性是无法解决的,所以我们使用继承这个概念来处理。

继承(要点):

1、说到继承肯定是一个父子结构,首先要创建一个parent project;
2、<packaging>:作为父模块的pom,其打包类型必须是pom;
3、结构:父模块本身就是为了消除子模块中依赖的冗余性,所以不需要src/main/java和src/test/java等目录;
4、新的元素:<parent>,是在子模块中用来继承父模块的;
5、<parent>元素的属性:<relativePath>表示父模块中pom的相对路径,在构建的时候maven会先根据<relativePath>检查父模块pom,如果找不到,再从本地仓库中查找;
6、<relativePath>的默认值:../pom.xml;
7、子模块省略groupId和version:在子模块中可以不声明groupId和version两个元素,子模块将隐式的继承父模块中的groupId和version元素。
8、继承能够提高代码的复用性,还可以让项目更加安全。

总结:

  • 对于聚合模块来说,它知道有哪些被聚合的模块,而对于被聚合的模块来说,它们不知道被谁聚合了,也不知道它的存在
  • 对于继承关系的父POM来说,它不知道自己被哪些子模块继承了,对于子POM来说,它必须知道自己的父POM是谁
  • 在一些最佳实践中我们会发现:一个POM既是聚合POM,又是父POM,这么做主要是为了方便。

我们就用如下图来演示maven聚合工程:

maven聚合工程引入pom依赖_maven依赖管理

1、创建聚合工程整体架构

1.1、首先在idea创建一个空项目

maven聚合工程引入pom依赖_maven聚合工程_02

maven聚合工程引入pom依赖_maven_03

1.2、创建ebuy-parent模块(管理项目所需依赖)

maven聚合工程引入pom依赖_maven继承特性_04


maven聚合工程引入pom依赖_maven聚合工程引入pom依赖_05


maven聚合工程引入pom依赖_maven_06


maven聚合工程引入pom依赖_maven继承特性_07

  • 然后在ebuy-parent模块中添加如下版本控制和相关依赖
<!-- properties:统一管理版本号 -->
    <properties>
        <junit.version>4.12</junit.version>
        <jstl.version>1.2</jstl.version>
        <servlet-api.version>2.5</servlet-api.version>
        <jsp-api.version>2.0</jsp-api.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- 单元测试 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <!-- version:引用上面properties中配置的版本号 -->
                <version>${junit.version}</version>
                <scope>test</scope>
            </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>
        </dependencies>
    </dependencyManagement>

maven聚合工程引入pom依赖_maven聚合工程_08

1.3、创建ebuy-main模块(聚合工程的父级项目)

maven聚合工程引入pom依赖_maven依赖管理_09


maven聚合工程引入pom依赖_maven继承特性_10


maven聚合工程引入pom依赖_maven聚合工程引入pom依赖_11

1.4、分层创建模块(横向拆分)

1.4.1、创建ebuy-pojo模块

maven聚合工程引入pom依赖_maven聚合工程_12


maven聚合工程引入pom依赖_maven继承特性_13

1.4.2、创建ebuy-dao模块

maven聚合工程引入pom依赖_maven聚合工程引入pom依赖_14


maven聚合工程引入pom依赖_maven继承特性_15

1.4.3、创建ebuy-service模块

maven聚合工程引入pom依赖_maven_16


maven聚合工程引入pom依赖_maven继承特性_17

1.4.4、创建ebuy-servlet模块(maven-web项目)

maven聚合工程引入pom依赖_maven依赖管理_18


maven聚合工程引入pom依赖_maven聚合工程引入pom依赖_19


maven聚合工程引入pom依赖_maven依赖管理_20

1.5、查看ebuy-main模块中pom.xml文件

maven聚合工程引入pom依赖_maven依赖管理_21

2、测试聚合工程

  • 首先分析多层依赖关系:

2.1、首先是dao层引用pojo层

maven聚合工程引入pom依赖_maven聚合工程引入pom依赖_22

2.2、service层引用dao层

maven聚合工程引入pom依赖_maven聚合工程引入pom依赖_23

2.3、servlet层引用service层

maven聚合工程引入pom依赖_maven_24

2.4、简单测试

  • 首先在ebuy-pojo模块中创建com.ebuy.pojo包,其次创建UsersInfo类
    -
package com.ebuy.pojo;

/**
 * @author 一宿君(CSDN:qq_52596258)
 * @date 2021年05月23日 16时40分04秒
 * 用户信息实体类
 */
public class UsersInfo {
    private int userid;
    private String username;
    private String userpwd;

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserpwd() {
        return userpwd;
    }

    public void setUserpwd(String userpwd) {
        this.userpwd = userpwd;
    }

    @Override
    public String toString() {
        return "UsersInfo{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                ", userpwd='" + userpwd + '\'' +
                '}';
    }
}
  • 然后在ebuy-dao模块中创建com.ebuy.dao包,在下面创UsersInfoDao接口,在接口定义方法getUsers()
package com.ebuy.dao;

import com.ebuy.pojo.UsersInfo;

/**
 * @author 一宿君(CSDN : qq_52596258)
 * @date 2021-05-23 16:52:20
 */
public interface UsersInfoDao {
    /*用于获取UsersInfo用户信息*/
    public UsersInfo getUsers();
}
  • 然后在ebuy-service模块中创建com.ebuy.service包,然后在下面创建UsersInfoDao接口的实现类UsersInfoService,然后重写方法getUsers()
package com.ebuy.service;

import com.ebuy.dao.UsersInfoDao;
import com.ebuy.pojo.UsersInfo;

/**
 * @author 一宿君(CSDN : qq_52596258)
 * @date 2021-05-23 16:55:09
 */
public class UsersInfoService implements UsersInfoDao {

    public UsersInfo getUsers() {
            UsersInfo usersInfo = new UsersInfo();
            usersInfo.setUserid(1001);
            usersInfo.setUsername("张三");
            usersInfo.setUserpwd("123456");
            return usersInfo;
    }
}
  • 然后在ebuy-servlet模块中创建com.ebuy.servlet包,继承HttpServlet类,重写doGet()和doPost()方法。
  • 首先要将有关jsp的相关依赖引入到ebuy-servlet的pom.xml文件中,在此处引用的全是ebuy-parent中的依赖,version版本是通过jstl标签的形式获取的。
<dependencies>
        <!--servlet层依赖service层-->
        <dependency>
            <groupId>com.ebuy</groupId>
            <artifactId>ebuy-service</artifactId>
            <version>1.0-SNAPSHOT</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>junit</groupId>
            <artifactId>junit</artifactId>
            <!-- version:引用上面properties中配置的版本号 -->
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

maven聚合工程引入pom依赖_maven_25

package com.ebuy.servlet;

import com.ebuy.service.UsersInfoService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 一宿君(CSDN : qq_52596258)
 * @date 2021-05-23 16:57:11
 */
public class UsersInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        UsersInfoService usersInfoService = new UsersInfoService();
        System.out.println(usersInfoService.getUsers());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}
  • 最后还需在web.xml文件中配置下servlet
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  
  <servlet>
    <servlet-name>usersinfo</servlet-name>
    <servlet-class>com.ebuy.servlet.UsersInfoServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>usersinfo</servlet-name>
    <url-pattern>/usersinfoServlet</url-pattern>
  </servlet-mapping>
  
</web-app>
  • 配置tomcat服务器
  • maven聚合工程引入pom依赖_maven继承特性_26

maven聚合工程引入pom依赖_maven_27

  • 然后启动个tomcat发现报如下错误(版本问题):
  • 将如下版本控制代码写入到所有模块项目的pom.xml文件中:
<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.9</maven.compiler.source>
        <maven.compiler.target>1.9</maven.compiler.target>
</properties>
  • 然后在启动tomcat服务器:
  • 最后测试usersInfoServlet:

3、maven聚合工程的优点

在项目中使用Maven可以大大简化开发及构建的过程,一旦产品线庞大,包含的项目及模块繁多时,各模块间版本管理就会产生不一致现象,从而给维护及开发带来了不少难题。Maven的聚合特性可以帮助我们把项目的多个模块聚合在一起,使用一条命令完成构建。