⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://www.iocoder.cn/Fight/Spring-Boot-multi-module-project-practice/ 「芋道源码」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

序言: 比起传统复杂的单体工程,使用Maven的多模块配置,可以帮助项目划分模块,鼓励重用,防止POM变得过于庞大,方便某个模块的构建,而不用每次都构建整个项目,并且使得针对某个模块的特殊控制更为方便。接下来,本文将重点阐述SpringBoot在Maven环境的多模块构建过程。本项目传送门: SpringBoot-Integration

一、创建聚合父工程

  • 1.首先使用 Spring Initializr 来快速创建好一个Maven工程。然后删除无关的文件,只需保留pom.xml 文件。

聚合父工程

    1. 然后在 pom.xml 里面声明该父工程包含的子模块。(其它信息就不逐一讲述了,诸如继承SpringBoot官方父工程以及统一依赖管理 请查看下面的注释说明)

<?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">

<!-- 基本信息 -->
<description>SpringBoot 多模块构建示例</description>
<modelVersion>4.0.0</modelVersion>
<name>springboot-integration</name>
<packaging>pom</packaging>

<!-- 项目说明:这里作为聚合工程的父工程 -->
<groupId>com.hehe</groupId>
<artifactId>springboot-integration</artifactId>
<version>1.0.0.RELEASE</version>

<!-- 继承说明:这里继承SpringBoot提供的父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/>
</parent>

<!-- 模块说明:这里声明多个子模块 -->
<modules>
<module>mm-web</module>
<module>mm-service</module>
<module>mm-repo</module>
<module>mm-entity</module>
</modules>

<!-- 版本说明:这里统一管理依赖的版本号 -->
<dependencyManagement>
<dependencies>

<dependency>
<groupId>com.hehe</groupId>
<artifactId>mm-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.hehe</groupId>
<artifactId>mm-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.hehe</groupId>
<artifactId>mm-repo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.hehe</groupId>
<artifactId>mm-entity</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>
</dependencies>
</dependencyManagement>

</project>

二、创建子模块(module)

注:这里是使用IDEA来创建子模块,使用Eclipse的小伙伴可通过 Spring Initializr 构建,然后复制去进去父工程根目录即可。

  • 1.对着父工程右键 - New - Module - > 输入 mm-web
  • 2.对着父工程右键 - New - Module - > 输入 mm-service
  • 3.对着父工程右键 - New - Module - > 输入 mm-repo
  • 4.对着父工程右键 - New - Module - > 输入 mm-entity
  • 1~4 步骤完成后,分别调整它们的pom.xml 以继承上面的父工程。 例如mm-web模块的pom.xml 需要改造成这样:

<?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.hehe</groupId>
<artifactId>mm-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mm-web</name>

<!-- 继承本项目的父工程 -->
<parent>
<groupId>com.hehe</groupId>
<artifactId>springboot-integration</artifactId>
<version>1.0.0.RELEASE</version>
</parent>

<!-- Web模块相关依赖 -->
<dependencies>
<dependency>
<groupId>com.hehe</groupId>
<artifactId>mm-service</artifactId>
</dependency>
<dependency>
<groupId>com.hehe</groupId>
<artifactId>mm-entity</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>

三、编写子模块代码

  • 1. 控制层(mm-web)

结构图

启动类 :MmWebApplication.java (mm-web)

@SpringBootApplication
public class MmWebApplication {

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

控制器:UserController.java (mm-web )

@RestController
@RequestMapping("/user/*")
public class UserController {

@Autowired
UserService userService;

@GetMapping("list")
public R list() {
try {
return R.isOk().data(userService.list());
} catch (Exception e) {
return R.isFail(e);
}

}

}

配置文件:application.yml (mm-web)

spring:
datasource:
url: jdbc:mysql://localhost:3306/socks?useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver

  • 2. 业务层(mm-service)

结构图

实现类:UserServiceImpl.java (mm-service)

@Service
public class UserServiceImpl implements UserService {

@Autowired
UserRepository userRepository;

@Override
public List<User> list() {
return userRepository.findAll();
}
}

  • 3. 数据层(mm-repo)

结构图

数据层代码:UserRepository.java (mm-repo)

public interface UserRepository extends JpaRepository<User,String> {
}

  • 4. mm-entity (实体模型层)

结构图

R.java 作为统一返回的Bean对象

package com.hehe.integration.common;

import java.io.Serializable;

public class R<T> implements Serializable {

private static final long serialVersionUID = -4577255781088498763L;
private static final int OK = 0;
private static final int FAIL = 1;
private static final int UNAUTHORIZED = 2;

private T data; //服务端数据
private int status = OK; //状态码
private String msg = ""; //描述信息

//APIS
public static R isOk(){
return new R();
}
public static R isFail(){
return new R().status(FAIL);
}
public static R isFail(Throwable e){
return isFail().msg(e);
}
public R msg(Throwable e){
this.setMsg(e.toString());
return this;
}
public R data(T data){
this.setData(data);
return this;
}
public R status(int status){
this.setStatus(status);
return this;
}


//Constructors
public R() {

}

//Getter&Setters

}

@Entity
@Table(name = "T_USER")
public class User {

@Id
@Column(name = "USERID")
private String userId;
@Column(name = "USERNAME")
private String username;
@Column(name = "PASSWORD")
private String password;

//Getter&Setters
}

三、运行项目

为了更好的学习效果,建议先下载本项目,在IDE运行成功之后,然后再由自己手工敲一遍。

具体步骤:

  • 1.首先下载好 springboot-socks,然后打开springboot-integration 工程。

  • 2.安装Mysql数据库,然后创建数据库socks,并添加表t_user,插入数据如图:

sock.t_user.PNG

    1. 配置好整个项目之后,这里只需要运行mm-web模块下的MmWebApplication的启动类就可以了,如正常启动后,访问http://localhost:8080 可查询到用户列表信息。如下图:

四、运维部署(多模块打包)

1. 添加打包插件

注意:多模块项目仅仅需要在启动类所在的模块添加打包插件即可!!不要在父类添加打包插件,因为那样会导致全部子模块都使用spring-boot-maven-plugin的方式来打包(例如BOOT-INF/com/hehe/xx),而mm-web模块引入mm-xx 的jar 需要的是裸露的类文件,即目录格式为(/com/hehe/xx)。

本案例的启动模块是 mm-web , 只需在它的pom.xml 添加打包插件(spring-boot-maven-plugin):

<!--多模块打包:只需在启动类所在模块的POM文件:指定打包插件 -->
<build>
<plugins>
<plugin>
<!--该插件主要用途:构建可执行的JAR -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

2. 打包工程

首先在IDE打开Maven插件,然后在聚合父工程spring-boot-integration中点击 clean ,然后点击 package 进行打包。如图:

打包效果如下:

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] spring-boot-integration ............................ SUCCESS [ 0.000 s]
[INFO] mm-entity .......................................... SUCCESS [ 1.915 s]
[INFO] mm-repo ............................................ SUCCESS [ 0.235 s]
[INFO] mm-service ......................................... SUCCESS [ 0.218 s]
[INFO] mm-web ............................................. SUCCESS [ 0.891 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.798 s
[INFO] Finished at: 2017-10-18T17:17:02+08:00
[INFO] Final Memory: 35M/300M
[INFO] ------------------------------------------------------------------------

打包地址默认在Target目录:

3. 启动项目

通过命令行启动项目:

xx\mm-web\target>java -jar mm-web-0.0.1-SNAPSHOT.jar

启动效果如下:

文章目录
  1. 1. 一、创建聚合父工程
  2. 2. 二、创建子模块(module)
  3. 3. 三、编写子模块代码
  4. 4. 1. 控制层(mm-web)
  5. 5. 2. 业务层(mm-service)
  6. 6. 3. 数据层(mm-repo)
  7. 7. 4. mm-entity (实体模型层)
  8. 8. 三、运行项目
  9. 9. 四、运维部署(多模块打包)
    1. 9.1. 1. 添加打包插件
    2. 9.2. 2. 打包工程
    3. 9.3. 3. 启动项目