目录
- 聚合的意义:
- 创建聚合工程的要点(重点理解):
- 继承的意义:
- 继承(要点):
- 总结:
- 我们就用如下图来演示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层(数据访问层、持久层),
可以理解为将一个功能模块的不同调用过程(三层的调用)进行了水平方向的拆分。
- 纵向拆分
所谓的纵向拆分就是将一个项目根据多个功能模块进行拆分,可以理解为,为了完成一个系统,深度(纵向)分析需要有哪些功能,然后将这些功能独立出来(独立为模块),进行了(纵向)拆分。
- 横向和纵向拆分后,对每层架构和功能模块进行单独的开发,项目整合的时候就需要有一个能够整合这些架构或者模块的工程,这就是所谓聚合工程的意义。
创建聚合工程的要点(重点理解):
- 该聚合项目(父级项目、顶级项目)本身也是一个maven项目,它必须有自己的pom
- 它的打包方式必须是:pom
- 引入新的元素:modules—module(模块:每个模块其实也是一个项目)
- 版本:聚合模块的版本要和被聚合模块的版本一致
- relative path:每个module名称都是一个当前pom的相对目录
- 目录名称:为了方便快速定位,模块所处的目录应当与其artifactId一致(maven约定而不是硬性要求),总之,模块所处的目录必须要和聚合模块中的模块目录保持一致。
- 聚合模块减少的内容:聚合模块的内容仅仅是一个pom.xml文件,它不包含src/main/java和src/test/java等目录,因为他只是用来将其他模块整合构建成一个整体的工具,本身并没有实质的内容。
- 聚合模块和子模块的目录:它们可以是父子级,也可以是平行结构(推荐)。默认是父子级结构,但是不建议使用,因为父子级是一种嵌套关系,子模块要建在父模块里面,维护起来很容易紊乱;推荐使用平行结构,是因为维护起来一目了然,条理比较清晰,当然同时要在pom文件的中修改相应的目录路径配置。
- 如果聚合模块对某一个子模块进行了删除操作,那么一定要在聚合模块的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聚合工程:
1、创建聚合工程整体架构
1.1、首先在idea创建一个空项目
1.2、创建ebuy-parent模块(管理项目所需依赖)
- 然后在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>
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、简单测试
- 首先在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>
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服务器
- 然后启动个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的聚合特性可以帮助我们把项目的多个模块聚合在一起,使用一条命令完成构建。