Spring Boot模块划分

Posted 小小本科生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot模块划分相关的知识,希望对你有一定的参考价值。

模块划分

一、创建工程

首先通过Spring Initializr新建一个普通的spring boot项目,就命名为moduledemo吧

二、精简目录(不必须)

我们利用这个项目作为整个系统的父模块,也就是说我们刚刚建立的这个项目现在只起一个盒子的作用,因此我们可以直接把src和其他用不到的目录都删了。

三、创建模块

右键点击目录名,选择new->Module...根据第一步的方式在此工程中建立几个spring boot的module,也就是我们分模块最终分出来的各模块。注意推荐做法是每个子模块的groupId要相同,创建的时候注意一下。

比如我这里建立了以下4个模块,每个模块的groupId都是com.bupt

每个模块的功能及依赖关系,如下表所示。其中依赖关系中括号的意思是选择性依赖,如果有需要就依赖commons,如果没有需要就不加。

序号模块名功能依赖关系
1api相当于三层架构中的controller层,用于处理和前端的交互依赖于service(commons)
2service相当于三层架构中的service层,逻辑代码主要写在这里依赖于dao(commons)
3dao相当于三层架构中的dao层,主要用来操作数据库依赖于(commons)
4commons封装了一些供其他模块调用的一些工具类 

四、修改pom

注意看代码中的注释,每个配置的解释都在注释中

1.修改父模块的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bupt</groupId>
    <artifactId>moduledemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!--1.在此添加packaging,并将打包方式设置为pom-->
    <!--如果之前就存在此标签就直接将其修改为pom-->
    <packaging>pom</packaging>
    <name>moduledemo</name>
    <description>Demo project for Spring Boot</description>

    <!--2.加入子模块信息,也就是maven中的聚合-->
    <modules>
        <module>api</module>
        <module>service</module>
        <module>dao</module>
        <module>commons</module>
    </modules>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <!--3.所有的子模块默认都会继承父模块的依赖-->
    <!--将所有模块几乎都会使用的依赖加在父模块中就不用在每个子模块中逐一添加了,管理起来也方便很多-->
    <dependencies>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.修改commons模块中的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

<!--    <parent>-->
<!--        <groupId>org.springframework.boot</groupId>-->
<!--        <artifactId>spring-boot-starter-parent</artifactId>-->
<!--        <version>2.2.2.RELEASE</version>-->
<!--        <relativePath/> &lt;!&ndash; lookup parent from repository &ndash;&gt;-->
<!--    </parent>-->

    <!--1.将这里的父模块由springframework改为我们的moduledemo-->
    <parent>
        <groupId>com.bupt</groupId>
        <artifactId>moduledemo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- 父pom路径 -->
    </parent>

    <!--2.groupId和version继承父模块,可以删除。当然name和description也不是必须的-->
    <!--<groupId>com.bupt</groupId>-->
    <artifactId>commons</artifactId>
<!--    <version>0.0.1-SNAPSHOT</version>-->
    <name>commons</name>
    <description>Demo project for Spring Boot</description>

    <!--3.properties会继承父模块中的配置,这里也可以删除-->
<!--    <properties>-->
<!--        <java.version>1.8</java.version>-->
<!--    </properties>-->

<!--4.由于可以继承父模块中的依赖,因此我们可以将这里的基础依赖都删除-->
    <dependencies>

    </dependencies>

    <!--4.如果没有使用特殊的插件,这里直接继承父pom中的插件就可以了-->
    <build>
        <plugins>
<!--            <plugin>-->
<!--                <groupId>org.springframework.boot</groupId>-->
<!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
<!--            </plugin>-->
        </plugins>
    </build>

</project>

3.dao模块中的pom.xml和commons模块中的pom.xml类似,大家如法炮制就好

4.service模块中的pom.xml和api模块中的pom.xml也类似,大家参考下面api模块中pom.xml中的配置进行修改

5.修改api模块中的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.bupt</groupId>
        <artifactId>moduledemo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
    </parent>

    <artifactId>api</artifactId>
    <name>api</name>
    <description>Demo project for Spring Boot</description>

    <!--1.加入对其他模块的依赖-->
    <dependencies>
        <dependency>
            <groupId>com.bupt</groupId>
            <artifactId>service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--2.当所依赖的其他模块,有启动类的时候,需要以下配置,指定唯一启动类-->
                <!--由于本模块中依赖的service模块中也有启动类,因此在这里需要配置唯一启动类-->
                <!--commons模块和dao模块没有依赖的模块,因此无需配置-->
                <configuration>
                    <!-- 指定该Main Class为全局的唯一入口 -->
                    <mainClass>com.bupt.api.ApiApplication</mainClass>
                    <layout>ZIP</layout>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

如果你不需要在某个模块中编写测试代码或者此模块不需要启动则可删除这个模块中src目录下的test文件夹和启动类,比如我将commons模块下的test文件夹、启动类和dao模块下的test文件夹、启动类都删了。

注意不要忘记在service模块中的pom.xml依赖dao模块

五、测试

在api模块中随便写一个controller,肯定是能访问到的

package com.bupt.api.controller;

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

/**
 * @Author huang xin
 * @Date 2020/1/6 21:24
 * @Version 1.0
 */
@RestController
public class TestController 
    @RequestMapping("/test")
    public String test() 
        return "spring boot模块划分测试";
    

有的小伙伴就呵呵了,我随便新建一个spring boot项目,随便写一个controller肯定能访问成功。你怎么证明你的模块划分和模块间的相互依赖成功了,而不是仅仅一个api模块运行成功了呢(api模块只依赖service模块就能正常运行,已经说明了子模块可以继承父模块中的依赖了;而且项目能够成功运行起来也说明了我们的配置没有毛病)。那我们下面就真正连接数据库,建立一个数据库查询试试呗。刚好给小伙伴们普及一下分模块的项目如何集成和配置druid,mybatis等好用的库。

常用依赖库集成

注意所有的xml配置和yml配置都只能放在最外层模块中,比如我们这个项目的依赖关系是api->service->dao->(commons),因此api就是最外层的模块,所有配置都要放在这个模块中,否则程序是找不到这个配置的。但是java config即使用java代码进行的配置放在任何模块中都行。

1.druid集成(扩展:使用druid进行监控)

(1) 导入依赖

把dao层独立出来为的就是将数据库相关处理逻辑放在这一层中,因此我们在dao模块的pom.xml中加入druid依赖

        <!--druid数据库连接池-->
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

数据库连接相关依赖自然必不可少,这里的mysql-connector根据自己的数据库版本选择

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
     <!--jdbc-->
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

注意yml配置一定要在api模块中写,否则会报找不到数据库配置。不明白的看上面的(注意)。由于api层依赖service层,service层依赖dao层,dao层依赖了druid和mysql等,因此在api模块中就可以获取其他模块中的各依赖,虽然我也想把数据库配置放到dao层,使分层的效果更加明显。

(2)api模块中application.yml配置


server:
  port: 8888
  servlet:
    context-path: /coolvideo

spring:
  datasource:
    url: jdbc:mysql://www.huangxin388.top:3306/coolvideo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
    username: 
    password: 
    driver-class-name: com.mysql.cj.jdbc.Driver
    platform: mysql
    # 下面为连接池的补充设置,应用到上面所有数据源中
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      # 初始化大小,最小,最大
      initialSize: 1
      minIdle: 3
      maxActive: 20
      # 获取连接等待超时时间
      maxWait: 60000
      # 设置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一个连接池中最小生存的时间,单位是毫秒
      minEvictableIdleTimeMillis: 30000
      validationQuery: select 'x'
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      # 打开PSCache,并且指定每个连接上PSCache的大小
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20
      # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      filters: stat,wall,slf4j
      # 通过connectionProperties属性来打开mergeSql功能;打开sql记录
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

由于是线上的数据库,用户名和密码我就不贴了。

tips:

(a)5.0以下的数据库驱动要用com.mysql.jdbc.Driver

(b)如果你复制了我的配置,然后报配置有错误,可能是中文编码问题,可以尝试把注释中的中文全部去掉加以解决

(3) java config进行druid监控配置(如果不使用druid监控,则此步可以跳过)

既然java config不要求必须写在最外层模块中,我们就在dao模块中新建一个config包,在此包下建立DruidConfiguration.java来配置druid监控。

目录结构如上所示,解释写在注释中

package com.bupt.dao.config;

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

/**
 * druid监控配置类
 * @Author huang xin
 * @Date 2020/1/9 12:02
 * @Version 1.0
 */
@Configuration
public class DruidConfiguration 
    private static final Logger logger = LoggerFactory.getLogger(DruidConfiguration.class);

    @Bean
    public ServletRegistrationBean druidServlet() 
        logger.info("init Druid Servlet Configuration ");
        // Spring boot 默认是不支持 JSP 的,所以想用使用 Servlet 功能,就必须要借用 Spring Boot 提供的 ServletRegistrationBean 接口
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // IP白名单
//        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
        // IP黑名单(共同存在时,deny优先于allow)
//        servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
        //控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername", "admin");
        servletRegistrationBean.addInitParameter("loginPassword", "admin");
        //是否能够重置数据 禁用html页面上的“Reset All”功能
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    

    /**
     * 使用WebStatFilter过滤器配置druid的url统计
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() 
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        // 排除对以下url的统计
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    

    /**
     * @Bean 声明其为Bean实例
     * @Primary 在同样的DataSource中,首先使用被标注的DataSource
     * @return
     */
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource datasource()
        return DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();
    

(4)访问测试

运行项目,访问http://你的ip:你的端口号/项目url前缀/druid,会自动跳转至druid监控登录界面,用户名和密码是DruidConfiguration.java中配置的admin,登录后就会看到如下画面。关于各项监控数据的含义在此不详述

端口号8888和url前缀moduledemo是在api模块中的appilcation.yml中配置的。url中的druid是在DruidConfiguration.java中配置的。

2.mybatis集成

(1)在dao模块的pom.xml中加入mybatis依赖

        <!--mybatis-->
        <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>

(2)在api模块中的application.yml中配置“mybatis配置文件”路径和“mybatis的mapper路径”

为了怕小白不注意yml缩进,我把application.yml中的所有内容放下下边。同样,用的时候最好把中文注释去掉


server:
  port: 8888
  servlet:
    context-path: /moduledemo

spring:
  datasource:
    url: jdbc:mysql://www.huangxin388.top:3306/coolvideo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
    username: 
    password: 
    driver-class-name: com.mysql.cj.jdbc.Driver
    platform: mysql
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initialSize: 1
      minIdle: 3
      maxActive: 20
      maxWait: 60000
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 30000
      validationQuery: select 'x'
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20
      filters: stat,wall,slf4j
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

#Mybatis
mybatis:
  #加载mybatis主要配置类
  config-location: classpath:/mybatis-config.xml
  #加载mapper配置类
  mapper-locations: classpath:/mapper/*.xml

(3)创建mybatis配置文件

既然我们在上述文件中配了mybatis配置文件路径在classpath下面,那我们就在api模块中的resources目录下创建mybatis-config.xml,内容如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org/DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!--使用jdbc的getGeneratedKeys获取数据库自增主键值-->
        <setting name="useGeneratedKeys" value="true"/>
        <!--使用列标签换列别名 默认:true-->
        <setting name="useColumnLabel" value="true"/>
        <!--开启驼峰命名转换:Tablecreate_Time->EntitycreateTime-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>

    <!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?,
        typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?,
        databaseIdProvider?, mappers? -->
</configuration>

(4)再次设置mapper扫描路径(重点)

如果是在单模块项目中,在yml中设置mapper扫描路径就可以了,但是多模块项目必须在具体模块中再次设置mapper扫描路径mybatgis才能正常使用

在DruidConfiguration.java中加入如下配置,否则service模块注入mapper时会提示找不到

    /**
     * 解决问题:service中无法找到 mapper bean
     * 默认情况下 mybatis 只读取同一个工程里的 Mapper Bean
     * Mapper接口所在包名,Spring会自动查找其下的Mapper
     * @return mapperScannerConfigurer
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() 
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("**.mapper");
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        return mapperScannerConfigurer;
    

3.mybatis逆向工具mybatis-generator集成

(1)在dao模块的pom.xml中加入mybatis-generator依赖

        <!--mybatis逆向-->
        <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.0</version>
        </dependency>

(2)在dao模块的pom.xml中配置mybatis-generator插件。注:放在plugins标签中

            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.0</version>
                <configuration>
                    <!-- mybatis-generator的配置文件-->
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.17</version>
                    </dependency>
                </dependencies>

            </plugin>

(3)配置逆向生成策略

在插件配置中我们设置了此插件的配置文件路径为src/main/resources/generatorConfig.xml,因此在dao模块的resources目录下创建generatorConfig.xml文件(因为此配置文件只是在逆向生成时使用,项目运行期间不会用到此配置文件;所以不必配置在最外层模块中)。内容如下

其中配置了:

        (a)生成实体类的路径为:src/main/java下的com.bupt.dao.entity包,因此在dao模块中创建entity目录

        (b) 生成mapper.xml的路径为:src/main/resources下的mapper,因此在dao模块中国创建mapper目录,此为我们在api模块中application.yml中也是将mybatis的mapper扫描路径设置为了classpath:/mapper/*.xml,如果我们这一步将生成的mapper设置为其他目录会导致mybatis扫描不到mapper文件

        (c)生成的mapper.java路径为:src/main/java下的com.bupt.dao.mapper

注意:b和c步骤中的mapper不是一个意思,b中的mapper是具体实现,里面包含各种数据库操作的sql;而c中的mapper则是一个个接口,也有很多人习惯于把它命名为dao

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

    <!-- 如果使用MyBatis3Simple则不生成Example类 -->
    <context id="MySQLTables" targetRuntime="MyBatis3" defaultModelType="flat">
        <!--数据库的用户名和密码我删掉了,小伙伴们不要忘了在下面配置-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://www.huangxin388.top:3306/coolvideo"
                        userId=""
                        password="">
        </jdbcConnection>

        <javaTypeResolver >
            <property name="forceBigDecimals" value="true" />
        </javaTypeResolver>

        <javaModelGenerator targetPackage="com.bupt.dao.entity" targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
            <property name="addSetProperty" value="true" />
            <property name="pageResultName" value="PageResult"/>
        </javaModelGenerator>

        <sqlMapGenerator targetPackage="mapper"  targetProject="src/main/resources">
            <property name="enableSubPackages" value="true" />
            <property name="sqlTagTypeUpper" value="true" />
        </sqlMapGenerator>

        <!--type XMLMAPPER\\ANNOTATEDMAPPER\\MIXEDMAPPER-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.bupt.dao.mapper"  targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
            <property name="numberIncremental" value="true" />
            <property name="turnPageName" value="TurnPage"/>
            <property name="rowHandler" value="true"/>
        </javaClientGenerator>

        <table tableName="comments" domainObjectName="Comments">
            <property name="useActualColumnNames" value="false"/>
            <!-- 插入时是否自动生成主键 -->
<!--             <generatedKey column="id" sqlStatement="MySql" identity="true"/>-->
              <columnOverride column="content" jdbcType="VARCHAR" />
        </table>

    </context>
</generatorConfiguration>

建立的目录结构如下所示

注意上述generatorConfig.xml中的table标签,这个标签配置的就是,将数据库中某个特定的表逆向生成某个特定的实体类及mapper。

(4)逆向生成

我的数据库中有一个bgm表,内容如下所示

我要将bgm表逆向生成一个Bgm实体类及相关的数据库操作工具类,修改generatorConfig.xml中的table标签为如下所示

        <table tableName="bgm" domainObjectName="Bgm">
            <property name="useActualColumnNames" value="false"/>
            <!-- 插入时是否自动生成主键 -->
<!--             <generatedKey column="id" sqlStatement="MySql" identity="true"/>-->
              <columnOverride column="content" jdbcType="VARCHAR" />
        </table>

如果你的mybatis-generator插件配置正确,就会在maven中找到此插件

经过上述操作,如果日志中打印出BUILD SUCCESS,表的逆向生成就完成了。如果失败你需要慢慢查是哪一步做错了

此时发现相应的文件已经生成了

最最容易忽略的一个配置

在api模块的启动类配置包的扫描路径,由于我的四个模块的groupId全是com.bupt因此这里设置一个就可以,如果你各个模块的groupId不同,则这里要写成数组的形式,如下

@SpringBootApplication(scanBasePackages = "com.bupt.service", "com.bupt.dao")
package com.bupt.api;

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

@SpringBootApplication(scanBasePackages = "com.bupt")
public class ApiApplication 

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


测试

(1)service模块

注入mapper时有红线提示,没影响。有强迫症的小伙伴可以在BgmMapper.java中加入@Component注解,红线消失

(2)api模块

(3)访问测试

关于打包

1.使用maven默认插件

使用spring boot的maven插件必须要有启动类,而我们的commons模块和dao模块的启动类都删除了,所以我们要使用maven默认的插件工具。删除父pom中的spring-boot-maven-plugin插件,因为其他模块中插件都是从父pom中继承的,所以删除后所有的模块都会使用maven默认的插件。

如果你还使用了其他必须使用是spring boot插件,就将启动类再加上吧,多一个启动类也无妨,别忘了在pom中指定唯一启动类就行。

2.跳过测试

我们知道执行maven的打包命令时会先执行其前置命令。即mvn package命令的执行链为clean->validate->compile->test->package,而test这一步会尝试寻找其依赖的模块,但是我们没在测试类中指定配置文件的路径,所以可能会找不到其他模块。最简单的方式就是跳过测试。跳过测试有如下a和b两种方式

(a)在IDEA中设置。file->settings->runner,勾上Skip tests

可以看到test生命周期已经被忽略了。

(b)直接在执行maven命令的时候跳过测试

3.需要先安装依赖包

我们项目中的依赖链是这样的:api模块依赖service模块,service模块依赖dao模块,其他模块可能都依赖commons模块

所以我们首先打开commons模块的maven工具,将commons模块整个打包安装在本地仓库中,这样在打包依赖于此模块的模块时才不至于找不到依赖。上面巴拉巴拉一大堆,总结起来就是下面这个图。

打包成功后,点击install,将此模块安装到本地maven仓库。也可以直接点击install,因为执行install命令也就意味着clean->validate->compile->package->verify->install会相继执行。

 commons模块打成功后,再用相同的方式打包安装dao模块,service模块,api模块(顺序不能乱)。

4.听说有捷径?

如果每次打包都一个一个模块的打包安装就太烦了,好在maven的反应堆已经帮我们解决了这个难题。

反应堆:对于一个单模块项目,反应堆就是该模块本身;对多模块项目来说,反应堆是指所有模块组成的一个构建结构,包含了模块之间继承与依赖的关系。

啥?听不懂?没事儿~,反应堆就是maven中的一个概念,不需要你做任何事。当你第一次按顺序安装各模块之后,直接点击父模块的package命令,maven就会自动分析各模块直接的依赖关系,将所有模块都帮你打包完毕。

啥?你嫌第一次太费劲?果然是懒才推动了社会的进步。直接打开maven找到父模块,点击install命令,各种依赖关系和打包安装的先后顺序,maven的反应堆统统帮我们搞定了。

整个教程到这里就结束了,其实我分的还不是很彻底,如果有需要,可以将dao模块中的entity,mapper和classpath中的mapper也划分成独立的模块。

这个项目是为了写博客才建立的,就不再存储了。想要源码的可以访问

https://github.com/huangxin388/coolvideo

这是我打算写的一个微信小程序的后端代码。整个项目结构和文中的项目一模一样

以上是关于Spring Boot模块划分的主要内容,如果未能解决你的问题,请参考以下文章

像屎一样的 Spring Boot入门,总算有反应了

Maven 反应器:使用 Spring Boot 启动器 pom 的 pom

如何将 Spring Boot 项目集成到已经存在的多模块 Maven 项目中?

spring boot 多模块在tomcat上运行

20191114 Spring Boot官方文档学习(4.7)

Spring Boot 的 Web 应用程序开发