【SpringBoot 2学习笔记】《三》基于Maven多模块项目搭建

公司以前遗留的项目都属于单应用,其缺点是每次修改,都要整体打包,随着项目越来越大,代码比较臃肿,编译时间较长,难以维护。所以公司近期旨在重构,将原来的项目基于SpringBoot的Maven多模块应用来搭建新的架构,比较适用于前后端分离的提供接口服务的项目。这里主要记述一下使用Eclipse来进行多模块项目搭建的过程。便于后续参考和查阅。

基础前提:Eclipse已安装对应的STS插件(或者直接使用STS)

3.1 Maven的继承和聚合

3.1.1 基本概念

Maven多模块项目中的聚合与继承其实是两个概念,其目的是完全不同的。Maven聚合是为了方便快速构建项目,Maven集成主要是为了减少重复配置。对于聚合工程来说,它知道有哪些聚合的模块,但是被聚合的模块并不知道聚合工程的存在。对于继承关系的父POM来说,它不知道有那些子模块来继承它,但是子模块必须知道自己继承的父POM。 所以没有必要为了聚合而继承同一个父POM,也不必为了继承父POM而设计成多模块,根据自身项目特点来进行必要的取舍。

  • 聚合工程POM与继承关系的父POM的packaging都必须是POM类型

  • 聚合模块与继承关系中的父模块除了POM之外都没有实际的内容

3.1.2 Maven继承

继承是为了消除重复,可以使得子POM可以获得父POM中的各项配置,可以对子POM进行统一的配置和依赖管理,父POM中的大多数元素都能被子POM继承。 对于不同工程中的POM文件中的重复内容(编译版本、SpringBoot版本),可以提取出来在父工程的POM中定义。可被集成的POM元素参考如下:

groupId:项目坐标的核心元素
version:项目坐标的核心元素
description:描述信息
organization:组织信息
inceptionYear:创始年份
developers:开发者信息
contributors:贡献者信息
distributionManagement:部署配置信息
ciManagement:持续集成系统信息
scm:版本控制系统信息
mailingLists:邮件列表信息
properties:自定义的Maven属性
dependencies:项目的依赖配置
dependencyManagment:项目的依赖管理配置
repositories:项目仓库配置
build:包含源码配置、输出配置、插件配置、插件管理等
reporting:项目的报告输出配置、报告插件配置等
profiles:动态选择配置文件

3.1.3 Maven聚合

项目开发通常是分组分模块开发,每个模块开发完成要运行整个工程需要将每个模块聚合在一起运行,通过一个POM打包的项目可以将它们列为模块来聚合成一组项目进行构建。在列出模块工程时,不需要我们考虑模块间依赖关系,也就是说POM文件中列出的模块排序并不重要,实际使用过程中Maven会对所有模块进行拓扑排序,使得依赖关系始终在依赖模块之前构建。

3.1.4 Maven示例工程说明

应用场景,我们目前有两个Maven项目gavinbj-psbigdata以及gavinbj-robot(甚至更多),当我们要一次编译这两个项目,但是并不想分别针对两个项目各自执行mvn命令,所以Maven的聚合特性就有了用武之地。为了能够一次执行同时编译两个模块项目,我们需要添加一个编译整个项目所有模块的模块gavinbj-mp。

聚合模块(gavinbj-mp)的POM文件的第一个特点是packaging,其值为pom,对于聚合项目来说,其packaging的值必须是pom,否则就无法正常编译。而gavinbj-psbigdata和gavinbj-robot都没有声明packaging,默认值为jar。

聚合模块的第二个特点就是modules元素,这其实是实现聚合的核心配置。我们可以在该Maven项目中声明多个module元素来实现模块聚合,每个module值都是一个当前POM的相对路径。

通过创建聚合模块解决了同时编译的问题,但是我们的SpringBoot微服务工程里面同时使用spring-core、spring-beans和junit等依赖,以及相同的插件的配置(spring-boot-maven-plugin),这样重复的配置往往就意味着更多劳动和更多的潜在问题。在Maven的世界中,也有类似面向对象的继承机制让我们抽取出重复的配置,这就是POM的继承。

扫描二维码关注公众号,回复: 8869268 查看本文章

基于上面创建的模块,我们可以在子模块的POM中使用parent元素声明父模块,parent下的子元素groupId、artifactId和version指定了父模块的坐标,这三个元素是必须的。元素relativePath表示父模块POM的相对路径。若指定relativePath,当项目构建时,Maven会先根据relativePath检查父POM,如果找不到,再从本地仓库查找。另外,子模块(gavinbj-psbigdata)的POM文件中会发现没有声明groupId和version,不过这并不是代表gavinbj-psbigdata没有groupId和version,而是该子模块隐式从父模块中继承了这两个元素。按照继承的方式可以消除一些不必要的配置。对于artifactId元素来说,子模块需要显示声明,否则因为GAV坐标相同会导致模块间的坐标冲突;另外就是防止类似的artifactId造成混淆问题。

3.2 创建父工程

一般直接使用【File】-【New】-【Maven】-【Maven Project】来创建父工程,同时承担聚合模块的功能,该工程没有具体代码和资源文件(创建后可以删除src和resource文件夹),其最主要的就是POM文件的配置,父工程的打包方式为POM。

创建Maven Project
在这里插入图片描述
在这里插入图片描述

3.3 创建子工程

在父工程【gavinbj-mp】上右键选择【Maven】-【New Maven Module】来创建其关联的子工程。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
同理创建另外一个业务用的Module工程:这里我们举例建立一个调用大数据接口取得数据,并提供服务的例子。
在这里插入图片描述
在这里插入图片描述

另外,再创建一个机器人模块,利用华为云的一些公开API来进行一些智能化的工作,创建过程参考如上,不再赘述。
在这里插入图片描述

3.4 按照SpringBoot应用修改各自POM文件

根据3.1中集成和聚合的特性对父工程POM文件修改(该父工程同时也是聚合工程)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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.gavinbj</groupId>
  <artifactId>gavinbj-mp</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>gavinbj-mp</name>
  <description>父工程</description>
  
  <!-- 添加父工程的属性开始 -->
  <parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.2.1.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
  </parent>
  
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <!-- 添加父工程的属性结束 -->
  
  <modules>
    <module>gavinbj-common</module>
    <module>gavinbj-psbigdata</module>
    <module>gavinbj-robot</module>
  </modules>
</project>

子工程POM文件修改:gavinbj-common

去掉自身冗余的groupId和version,以及添加JAR的打包方式。

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.gavinbj</groupId>
    <artifactId>gavinbj-mp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>gavinbj-psbigdata</artifactId>
  <name>gavinbj-psbigdata</name>
  <url>http://maven.apache.org</url>
  
  <!-- 添加打包jar的打包方式  -->
  <packaging>jar</packaging>
  
  <!-- 可以继承父模块中的配置,此处可以删除,也可以进行单独模块的设置 -->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

gavinbj-psbigdata子模块POM文件修改。

去掉自身冗余的groupId和version,以及添加JAR的打包方式,以及需要引用common的依赖关系。同时可以删除Junit创建的测试的关联文件夹。注意:gavinbj-robot子模块和gavinbj-psbigdata等同处理

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.gavinbj</groupId>
    <artifactId>gavinbj-mp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>gavinbj-psbigdata</artifactId>
  <name>gavinbj-psbigdata</name>
  <url>http://maven.apache.org</url>
  
  <!-- 添加打包jar的打包方式  -->
  <packaging>jar</packaging>
  
  <!-- 可以继承父模块中的配置,此处可以删除,也可以进行单独模块的设置 -->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <!-- 添加对gavinbj-common的依赖-->
    <dependency>
      <groupId>com.gavinbj</groupId>
      <artifactId>gavinbj-common</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>
  </dependencies>
</project>

在这里插入图片描述
在这里插入图片描述

添加测试用的启动类

@SpringBootApplication

package com.gavinbj.psbigdata;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 *  @SpringBootApplication 标注这是SpringBoot项目的主程序类
 */
@SpringBootApplication
public class PSBigDataApplication {

	public static void main(String[] args) {
		SpringApplication.run(PSBigDataApplication.class, args);
	}

}

创建用测试的Controller

package com.gavinbj.psbigdata.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class HelloController {

    @GetMapping("/hello/{userName}")
    public String hello(@PathVariable("userName") String userName) {
        return "Welcome To SpringBoot 2 : " + userName;
    }
}

在这里插入图片描述
在这里插入图片描述

[INFO] gavinbj-mp ......................................... SUCCESS [  0.328 s]
[INFO] gavinbj-common ..................................... SUCCESS [  2.913 s]
[INFO] gavinbj-psbigdata .................................. SUCCESS [  1.033 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.570 s
[INFO] Finished at: 2019-11-18T10:23:28+08:00
[INFO] ------------------------------------------------------------------------

在这里插入图片描述

访问我们的测试地址,出现如上结果。代表多模块可行。后续是根据项目需要可以在共通模块中添加系统的共通处理。例如:公共工具、日志服务、安全工具等。业务模块根据自身项目,添加适合自己的业务模块。

发布了24 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/gavinbj/article/details/103169110