专栏首页SpringBoot图文教程SpringBoot图文教程16—SpringBoot 多模块开发「web」「打包」

SpringBoot图文教程16—SpringBoot 多模块开发「web」「打包」

前言

本文已经收录码云仓库:https://gitee.com/bingqilinpeishenme/Java-Tutorials 本文涉及源码下载地址:https://gitee.com/bingqilinpeishenme/multi-module-demo

什么是多模块开发?如图所示,项目中每一个包对应都是一个完整的项目,在IDEA中称之为模块,每一个模块都有完整的项目结构:独立的pom文件,独立的配置文件,独立的编译文件输出模块等等。

那么这样项目结构的项目是如何设计出来的呢?

SpringBoot 多模块开发

技术选型:

父级工程开发

父级工程可以用来统一管理所有项目的依赖,如图,如果在父级项目中有一个mysql依赖,那么所有继承这个父级项目的子项目中也会继承到mysql的依赖

1.创建一个Project

2.对IDEA做一些项目基本的配置

  • 字符编码配置
  • 注解生效激活
  • Java编译版本选择

3.写父级项目的pom文件

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>
<!--    配置SpringBoot的父级项目-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lby</groupId>
    <artifactId>multi-module-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--  packaging 父级项目的类型是pom  -->
    <packaging>pom</packaging>

    <!--   properties 定义pom的全局变量 一般用于定义依赖的版本号
 -->
    <properties>
        <java.version>1.8</java.version>
        <!--        lombok-version 这个标签是自定义的可以随便写
                本质上就是一个变量
        -->
        <lombok-version>1.18.4</lombok-version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <!--            版本号通过$获取properties中定义的版本号-->
            <version>${lombok-version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <!--    dependencyManagement
        在 dependencyManagement 中配置的依赖 只是一种声明 声明了版本号
        不会被项目继承下来【相关的jar包不会被子项目下载到项目中】

        子项目如果想要继承到dependencyManagement中的依赖  需要单独在配置
        只不过子项目如果继承 dependencyManagement 中的依赖 可以不写版本号【子项目中依赖版本
        按照父项目中dependencyManagement 中配置下载】
    -->
    <dependencyManagement>
        <dependencies>
            <!--如果是Mybatis写成Mybatis即可-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.3.1.tmp</version>
            </dependency>

            <!--数据源-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.0.19</version>
            </dependency>

            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.38</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

</project>

注意:

  • 父级项目的packing必须设置为 pom
  • dependencies 和 DependencyManagement 的区别
    • 如果在子项目中声明依赖,是不会从父项目中继承下来的,只有在子项目中写了该依赖项,并且没有执行具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom
    • 如果子项目指定了版本号,那么会使用子项目中指定的jar版本
    • dependencies 在当前项目中引入依赖,如果子项目继承了该项目,也会在子项目中引入依赖
    • DependencyManagement 只是声明依赖,并不实际引入,因此子项目需要显式声明需要用到的依赖

子项目开发

子项目开发的步骤如下:

  1. 基于Project创建module
  2. 修改pom
  3. 写配置,没有可以不写
  4. 写代码

1.创建multi-entity

1.基于Project创建module

创建完multi-entity后打开pom可以看到

此时打开父级项目的pom 会看到

2.修改pom

完整的multi-entity项目的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">
    <!--
       子项目继承父项目的配置 parent
    -->
    <parent>
        <artifactId>multi-module-demo</artifactId>
        <groupId>com.lby</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>multi-entity</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
    </dependencies>

</project>

3.在项目中写入实体类

package com.lby.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@TableName("cmfz_admin")
@Data
public class Admin {
    /**
     * 主键属性  @TableId
     *
     * value 该属性对应的数据库表中的字段名
     * type 主键自增的类型 AUTO 代表自动递增
     */
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    /**
     * 非主键属性  @TableField
     *  @TableField("username")  参数为该属性对应的数据库表中的字段名
     *
     */
    private String username;

    private String password;

    private String salt;

}

2.按照上述步骤创建 multi-dao

对于dao模块而言,不同的地方在于,在multi-dao中需要使用到 multi-entity中的实体类,但是怎么在dao模块中使用到另一个项目中的实体类呢?

将multi-entity像依赖一样导入 multi-dao中

multi-dao完整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">
    <parent>
        <artifactId>multi-module-demo</artifactId>
        <groupId>com.lby</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>multi-dao</artifactId>

    <dependencies>
<!--        在dao中引用entity
        可以在dao的代码中直接导入entity中的类和方法
    -->
        <dependency>
            <groupId>com.lby</groupId>
            <artifactId>multi-entity</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--        如果配置依赖在父项目的 dependencyManagement 有-->
        <!--        可以不写版本号 版本号继承父项目中的-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>


    </dependencies>
</project>

在multi-dao写入dao接口

package com.lby.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lby.entity.Admin;

public interface AdminDao extends BaseMapper<Admin> {
}

3.创建 multi-service 模块

完整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">
    <parent>
        <artifactId>multi-module-demo</artifactId>
        <groupId>com.lby</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>multi-service</artifactId>

    <dependencies>
<!--        multi-service中需要引入 dao模块-->
        <dependency>
            <groupId>com.lby</groupId>
            <artifactId>multi-dao</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

写入业务类

package com.lby.service;

import com.lby.dao.AdminDao;
import com.lby.entity.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 之所以能够直接使用@Service注解
 * 是因为 multi-service 模块 依赖了 multi-dao
 * multi-dao 依赖了 multi-entity
 * multi-entity 中的 MybatisPlus 依赖在项目中导入了Spring的jar包
 */
@Service
public class AdminService {
    @Autowired
    private AdminDao adminDao;

    public List<Admin> adminList(){
        return adminDao.selectList(null);
    }

}

4.创建 multi-controller 模块

multi-controller 模块是启动类所在的模块 所以我们把配置文件 启动类以及SpringBoot集成maven的插件都放在这个项目中

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">
    <parent>
        <artifactId>multi-module-demo</artifactId>
        <groupId>com.lby</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>multi-controller</artifactId>

    <dependencies>
<!--        controller中需要引入service-->
        <dependency>
            <groupId>com.lby</groupId>
            <artifactId>multi-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

<!--        web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--            spring-boot-maven-plugin 插件配置在启动类所在的模块-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.application配置文件配置

#配置端口号
server:
  port: 8802
#数据源的配置
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cmfz?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource

#mybatis-plus
mybatis-plus:
  mapper-locations: classpath:mapper/*Mapper.xml

# root 全局日志等级 默认是info 可以修改 debug warn error
logging:
  level:
    root: info
    com.baizhi: debug

3.启动类代码

package com.lby;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan("com.lby.dao")
@SpringBootApplication
public class AppRun {

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

4.controller代码

package com.lby.controller;

import com.lby.entity.Admin;
import com.lby.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class AdminController {
    @Autowired
    private AdminService adminService;

    @RequestMapping("adminList")
    public List<Admin> adminList(){
        return adminService.adminList();
    }
}

5.启动项目

通过启动类启动项目

访问地址:http://localhost:8802/adminList 可以看到如下效果

如果要使用插件启动 需要先对父项目进行 clean 和 install操作

6.测试

编写测试类

运行测试方法 效果如下

7.打包项目

注意:启动类在哪个模块,就通过哪个模块打包

通过maven打包项目

找到打包好的项目 通过java -jar运行项目

访问地址:http://localhost:8802/adminList 可以看到如下效果

常见问题处理

1.循环依赖问题

image.png

错误信息提示:

Error:java: Annotation processing is not supported for module cycles. Please ensure that all modules from cycle [qrcode-common,qrcode-manager-pojo] are excluded from annotation processing

原因分析:循环依赖 死循环了

解决方案:修改模块中的依赖

2.IDEA修改pom不生效问题

在使用IDEA开发多项目的时候发现这样一个问题:修改pom文件之后,不管怎么刷新都不生效

解决方案:重启 IDEA 即可

总结

本文涉及源码下载地址:https://gitee.com/bingqilinpeishenme/multi-module-demo

恭喜你完成了本章的学习,为你鼓掌!如果本文对你有帮助,请帮忙点赞,评论,转发,这对作者很重要,谢谢。

让我们再次回顾本文的学习目标

  • 掌握SpringBoot中多模块开发

要掌握SpringBoot更多的用法,请持续关注本系列教程。

本文分享自微信公众号 - 鹿小洋的Java笔记(lulaoshiJava),作者:鹿老师

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • F版本SpringCloud 4—Eureka注册中心开发和客户端开发

    通过前三篇文章,用大白话介绍了微服务和SpringCloud以及服务治理相关的概念,从这篇开始SpringCloud代码的开发。

    鹿老师的Java笔记
  • 最适合新手入门的SpringCloud教程 7—OpenFeign「F版本」

    上一篇使用了RestTemplate的服务调用,但是有一些问题:通过RestTemplate发送请求时候,携带参数比较的繁琐,另外RestTemplate中需要...

    鹿老师的Java笔记
  • SpringBoot图文教程12—SpringData Jpa的基本使用

    在之前的文章中介绍过了Mybatis,MBG 和 MybatisPlus 等一系列Mybatis相关的技术,有朋友在评论区提到了Jpa,也评论了SpringDa...

    鹿老师的Java笔记
  • 独立使用zuul网关分发不同服务的请求、权限控制,非SpringCloud

    网关api Gateway的重要性不言而喻,网关负责统一接收所有请求,然后根据不同的规则进行转发到不同的服务。使用网关能够统一的管理请求日志、进行权限控制、过滤...

    天涯泪小武
  • 『高级篇』docker之APIGateway(17)

    PS:就像跟陌生人交朋友,不可能上来直接详细的自我介绍,一般都是先聊点其他的,或者从大家都感兴趣的一个话题作为切入点,一点点增加彼此的了解,其实学习也是一样的,...

    IT故事会
  • 『高级篇』docker之APIGateway(17)

    PS:就像跟陌生人交朋友,不可能上来直接详细的自我介绍,一般都是先聊点其他的,或者从大家都感兴趣的一个话题作为切入点,一点点增加彼此的了解,其实学习也是一样的,...

    IT故事会
  • ShapeFile数据到mongodb的导入

    开发环境为: 系统环境 Linux 4.4.0-36-generic #55~14.04.1-Ubuntu x86_64 x86_64 x86_64 GNU...

    卡尔曼和玻尔兹曼谁曼
  • 经纬度坐标和投影坐标的转换

    昨天,有朋友要我帮忙看看一个将经纬度坐标转换成墨卡托投影(墨卡托投影有很多变种,我也不知道他说的是哪一种)的程序,他说转换以后的坐标精度太差。当时,他的程序没怎...

    卡尔曼和玻尔兹曼谁曼
  • MapStruct 爬坑指南

    第一步当然是引入pom依赖,目前1.3版本还是beta所以选择引入1.2版本,使用IDEA的小伙伴推荐去插件商店搜索MapStruct,下载插件可以获得更好的体...

    tanoak
  • 【AI核心技术】课程五:BP反向传播简介

    UAI与PaddlePaddle联合推出的【AI核心技术掌握】系列课程持续更新中!

    用户1386409

扫码关注云+社区

领取腾讯云代金券