美文网首页推文上热门(千万赞三)spring boot
SpringBoot实战1:maven多模块应用精讲

SpringBoot实战1:maven多模块应用精讲

作者: 学知 | 来源:发表于2020-09-06 21:48 被阅读0次

各位读者朋友,大家好,本文是《SpringBoot实战》专题的第一篇:多模块应用精讲,本系列文章将以实际的业务需求为落脚点,逐个攻破开发工作中的技术难点,全面提升你的技术能力、业务能力。

本系列文章将涉及到但不限于推荐系统、分布式文件存储、缓存、权限控制等业务场景以及Hadoop、Spark、Redis、Elasticsearch搜索引擎、Redis等技术热点,如果你有意深耕Java技术 ,提升竞争力,欢迎你订阅本专题。


一、本文主题

本文中讲涉及到如下问题:

  • 什么是maven多模块应用?
  • 什么业务场景下使用多模块?
  • 如何搭多模块应用?
  • 多模块应用中配置文件没有生效,如何解决?
  • 多模块应用打包时如何配置,如何打包?

二、开发环境

  • Jdk1.8
  • maven3.6.3
  • Eclipse2018
  • SpringBoot2.1.16
    上述开发环境仅作为参考,具体的编辑器、Java版本或者SpringBoot版本可根据个人喜好设置。

三、实战

01 什么是多模块应用?

多模块应用有一个比较严谨的名字:maven聚合工程,当然,开发过程中也有的人称之为SpringBoot多模块应用,总之,能理解就好。但这里要强调的是,将应用切割成多个模块并管理起来,是依托于maven这个项目管理工具,和SpringBoot并没有关系。

02 什么场景下可以使用多模块应用?有什么优点?

关于多模块应用的优点,很多人说多模块应用结构清晰,可以加快开发快速。我并不这样认为:首先,单体应用也可以把项目结构划分的很清晰;其次,开发速度一方面取决于工作量,另一方面取决于业务的复杂度,不是简单的搭建一个多模块应用就可以加快速度的。

多模块应用的核心在于将中大型的应用按照业务逻辑切割开,提高代码复用度以及服务器资源利用率。

  • 通过父工程管理公共的依赖,子模块直接引用,将诸如数据库交互模块,工具类模块,公共业务方法模块隔离成独立模块,其它模块可以直接引用,这样便提高了代码的复用度。
  • 单体应用时,只有一个进程在使用服务器资源,加大了应用内部的资源压力,也限制了资源利用率的提高。多模块应用时,可以有多个启动入口,如面向管理员的后台、面向用户的前台单独启动,多个进程使用服务器资源,既提高了资源利用率,也降低了应用内部的压力。

所以,如果项目体量小,仅涉及简单的增删改查,那么就没必要使用多模块应用。如果项目体量中等,一个业务模块都可以单独抽取为一个应用的时候,就可以使用多模块应用。当然,如果继续增大项目体量以及业务复杂度,就可以使用微服务开发,将各模块分布式部署。

03 如何搭建多模块应用(以Eclispe为例讲解)?
031 构建父模块

https://start.spring.io/网站上快速构建一个SpringBoot应用,下载解压后导入Eclipse作为父工程(仅起到管理子模块的应用,不在父工程中写代码,可以删除src目录),打开pom.xml文件,配置打包方式,结果如下

<groupId>cn.zk</groupId>
<artifactId>multimodule</artifactId>
<version>1.0</version>
<!-- 配置打包方式 -->
<packaging>pom</packaging>
<name>multimodule</name>
<description>This is multi-module springboot project!</description>
032 删除父模块中不需要的文件夹
  • 右键src目录,删除该目录,对于JRE System Library和Maven Dependencies,需要右键-->build path-->remove移除
033 新建数据库交互模块
  • 右键父工程,new project-->maven module,简单填写dao模块信息后,点击确定

此时,父工程pom文件中会多出一个模块的配置信息。

034 新建数据库交互模块
  • 配置子模块的jre版本为1.8
  • 打开dao模块pom文件,配置dao模块信息,添加依赖
<!-- 子模块的基本信息 -->
<groupId>com.xz.multimodule</groupId>
<artifactId>dao</artifactId>
<!-- 配置打包方式 -->
<packaging>pom</packaging>
<name>dao</name>
<description>This is multi-module springboot project!</description>

<!-- 父模块的基本信息 -->
<parent>
    <groupId>com.xz</groupId>
    <artifactId>multimodule</artifactId>
    <version>1.0</version>
</parent>

<!-- 配置Java版本 -->
<properties>
    <java.version>1.8</java.version>
</properties>

<!-- 添加相关依赖 -->
<dependencies>
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.1.3</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>
</dependencies>
  • 在独立的dao模块中新建需要的package以及配置文件(父模块下的dao文件夹不用处理)
  • 配置MySQ连接信息、druid以及mybatis连接信息
spring:
  datasource: 
   # 配置MySQL基本连接信息
    name: search
    url: jdbc:mysql://localhost:3306/search?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
   #配置druid连接池
    driverClassName: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
#下划线自动转驼峰
mybatis:
  configuration:
    map-underscore-to-camel-case: true
  table:
    auto: update

到此,dao模块配置完毕,在其他模块直接引用即可。

035 新建service模块,并引用dao模块
  • 接下来,依照建立dao模块的方法建立处理公共业务方法的service模块,在service模块的配置文件中添加如下信息,引用dao模块
<!-- 子模块的基本信息 -->
<groupId>com.xz.multimodule</groupId>
<artifactId>service</artifactId>
<!-- 配置打包方式 -->
<packaging>pom</packaging>
<name>service</name>
<description>This is multi-module springboot project!</description>

<parent>
    <groupId>com.xz</groupId>
    <artifactId>multimodule</artifactId>
    <version>1.0</version>
    </parent>

<!-- 添加相关依赖 -->
<dependencies>
    <!-- 引用dao模块 -->
    <dependency>
       <groupId>com.xz.multimodule</groupId>
        <artifactId>dao</artifactId>
        <version>1.0</version>
    </dependency>
    <!-- commons-lang3 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
</dependencies>
036 新建面向用户的home模块,作为启动入口
  • home模块的建立方法和其它子模块一样,除了配置home模块本身的信息,还需要引用dao模块和service模块,由于home是启动模块,需要引入web依赖,过程中我们使用了thymeleaf作为模板引擎,所以thymeleaf的依赖也一并引入
<dependencies>
   <!-- 引入dao模块 -->
    <dependency>
        <groupId>com.xz.multimodule</groupId>
        <artifactId>dao</artifactId>
        <version>1.0</version>
    </dependency
      <!-- 引入service模块 -->>
    <dependency>
       <groupId>com.xz.multimodule</groupId>
        <artifactId>service</artifactId>
        <version>1.0</version>
    </dependency>
     <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
  • 接下来就是给home模块建立必要的package以及文件夹,如下所示

由于我们使用了mybatis,可以在启动类中统一配置MapperScan的扫描路径,相当于在该路径下每个类上都添加了@Mapper注解,如果MapperScan的扫描路径有多个,则添加{}后,各路径间用逗号隔开。

@SpringBootApplication
@MapperScan({"com.xz.dao.base.mysql.repo","com.xz.dao.base.es.repo"})
public class HomeApplication {
    public static void main(String[] args) {
        SpringApplication.run(HomeApplication.class, args);
    }
}
037 启动SpringBoot

第一次启动该项目时,会提示如下内容,提示配置的数据源无效

Failed to configure a DataSource: 'url' attribute ...
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
    If you want an embedded database (H2, HSQL or Derby)...
    If you have database settings to be loaded from a ....

你是否会感到疑惑呢,明明在dao模块配置了数据源,并且home模块也引入了dao模块的依赖,为何数据源无效?到此,你应该想到,当SpringBoot中有多个配置文件时,可以再启动入口的配置文件中配置激活哪一个配置文件:

#home模块的application.yml配置文件中添加如下配置
spring:
  profiles:
    active:  dev

再次启动,还是会遇到相同的错误提示,难道我们的配置文件写错了吗?其实你不用疑惑,spring.profiles.active不生效的原因是dao模块和home模块的配置文件重名了,spring.profiles.active=dev激活的是home模块下的配置文件,并没有激活dao模块的配置文件。
此时,将dao模块下的配置文件改为application-dao_dev.yml,用spring.profiles.active=dao_dev即可激活dao中的配置文件,再次启动即可。

spring:
  profiles:
    active:  dev,dao_dev
038 项目打包

项目打包前,需要在父模块和启动模块中配置打包信息,

  • 打开父模块pom文件,新增如下配置信息
 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <!--跳过单元测试 -->
                    <skipTests>true</skipTests>    
                </configuration>
            </plugin>
        </plugins>
    </build>

在home模块的pom.xml中配置启动类入口

 <build>
    <finalName>home</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <fork>true</fork>
                <executable>true</executable>
                <nainClass>com.xz.multimodule.home.HomeApplication</nainClass>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target> 
            </configuration>
        </plugin>
    </plugins>
</build>

最后进入命令行界面,切换到该项目的根目录

#打包命令
mvn clean package
#在home模块的target目录下找到打包形成的jar文件
#启动jar文件
java -jar home.jar

04 总结

上文中介绍了什么是多模块应用,如何构建多模块应用,以及多模块应用的坑点,大家在实战的过程中要注意如下两点

  • 父工程中也可以看到子模块的目录,配置文件等,但父工程中仅起到管理模块的作用,不要通过父工程为子模块新建package或者书写子模块代码。
  • 多个配置文件重名时,有必要改名,并在启动模块的application.yml中通过后缀激活。

相关文章

网友评论

    本文标题:SpringBoot实战1:maven多模块应用精讲

    本文链接:https://www.haomeiwen.com/subject/nxfxektx.html