相关文章推荐
纯真的仙人掌  ·  element ...·  1 年前    · 
精明的蜡烛  ·  TiDB 6.0:让 TSO ...·  1 年前    · 

经常看到网上很多 优秀的开源项目中,代码简洁,模块分层完美 。反观自己代码层级混乱,,却不知如何整理分层。此文 手把手教你一步一步创建模块 ,左手右手一个慢动作。结合本人实际开发及个人项目中 分层思路的分享,大神请勿喷

⏲️本文阅读时长

约25分钟

🎯主要目标

  • 熟练掌握SpringBoot项目分层思路 ,丝滑拆分模块
  • 熟悉代码层级依赖 ,规范化管理模块分布
  • 手把手实战学习,理论实践相结合
  • 👨‍🎓试用人群

  • 对于Springboot熟悉但是不知道合理分层 小白
  • 有自己分层思路可以互相分享学习
  • 🎁快速链接

    公众号: JavaDog程序狗 在公众号,发送【分层】 ,无任何套路即可获得

    或访问 blog.javadog.net/archives/bo…

    下图反面教材,传统单体应用,结构臃肿

    下图分层截选自本人的一个小项目,模块清晰,分工明确

    我们要实现的小栗子的分层

    🥫1.IDEA新建项目

    起名第一步,一个好名字,说不定是个好的开始

    假如我们的项目是个 聊天相关 的项目,英文对应 chat ,所以定义项目名为 chat-boot ,其他的以此效仿

    点击New->project

    选择 Maven项 目,并选择 合适JDK版本 ,点击Next

    录入项目名称,并填写GAV坐标,点击Finish

    删除无用文件及目录,如src目录和*.iml文件

    删除后项目目录

    修改pom.xml中依赖,增加spring-boot-starter-parent

     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.3.1.RELEASE</version>
     </parent>
    

    🌭2.创建子模块-dependencies(依赖层)

    右击项目chat-boot,new ->Moudle新建模块chat-boot-dependencies

    选择对应Module SDK版本,本人选择jdk1.8

    填写子模块名 chat-boot-dependencies,然后检查对应GAV,点击Finish

    生成子模块chat-boot-dependencies如下图

    删除chat-boot-dependencies下无用文件及目录,如src目录,删除无用目录如下

    完善chat-boot-dependencies下pom.xml依赖, 常用依赖放入,作为依赖主体,以下是本狗常用依赖,可酌情选择;记得把packaging改为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>chat-boot</artifactId>
            <groupId>net.javadog.chat</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>chat-dependencies</artifactId>
        <packaging>pom</packaging>
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <mysql-connector-java.version>8.0.17</mysql-connector-java.version>
            <druid.version>1.1.21</druid.version>
            <mybatis-plus.version>3.4.1</mybatis-plus.version>
            <fastjson.version>1.2.75</fastjson.version>
            <hutool.version>5.5.8</hutool.version>
            <lombok.versin>1.18.12</lombok.versin>
            <easypoi.version>4.2.0</easypoi.version>
            <springfox-swagger2.version>2.9.2</springfox-swagger2.version>
            <springfox-swagger-ui.version>2.9.2</springfox-swagger-ui.version>
            <knife4j.version>2.0.4</knife4j.version>
            <weixin.version>4.4.5.B</weixin.version>
            <shiro.version>1.3.2</shiro.version>
            <jwt.version>3.2.0</jwt.version>
        </properties>
        <dependencyManagement>
            <dependencies>
                <!--mybatis-plus-->
                <dependency>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                    <version>${mybatis-plus.version}</version>
                </dependency>
                <!-- 数据库驱动,可根据自己需要自行删减,默认使用mysql -->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql-connector-java.version}</version>
                </dependency>
                <!--数据库连接池-->
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid</artifactId>
                    <version>${druid.version}</version>
                </dependency>
                <!--fastjson-->
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>fastjson</artifactId>
                    <version>${fastjson.version}</version>
                </dependency>
                <!--hutool-->
                <dependency>
                    <groupId>cn.hutool</groupId>
                    <artifactId>hutool-all</artifactId>
                    <version>${hutool.version}</version>
                </dependency>
                <!--lombok-->
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <version>${lombok.versin}</version>
                </dependency>
                <!--swagger2-->
                <dependency>
                    <groupId>io.springfox</groupId>
                    <artifactId>springfox-swagger2</artifactId>
                    <version>${springfox-swagger2.version}</version>
                </dependency>
                <!--swagger-ui-->
                <dependency>
                    <groupId>io.springfox</groupId>
                    <artifactId>springfox-swagger-ui</artifactId>
                    <version>${springfox-swagger-ui.version}</version>
                </dependency>
                <!-- swagger接口文档 -->
                <dependency>
                    <groupId>com.github.xiaoymin</groupId>
                    <artifactId>knife4j-spring-boot-starter</artifactId>
                    <version>${knife4j.version}</version>
                </dependency>
                <!--easypoi导入导出-->
                <dependency>
                    <groupId>cn.afterturn</groupId>
                    <artifactId>easypoi-base</artifactId>
                    <version>${easypoi.version}</version>
                </dependency>
                <!--WxJava - 微信开发 Java SDK-->
                <dependency>
                    <groupId>com.github.binarywang</groupId>
                    <artifactId>weixin-java-miniapp</artifactId>
                    <version>${weixin.version}</version>
                </dependency>
                <!--整合Shiro安全框架-->
                <dependency>
                    <groupId>org.apache.shiro</groupId>
                    <artifactId>shiro-spring</artifactId>
                    <version>${shiro.version}</version>
                </dependency>
                <!--集成jwt实现token认证-->
                <dependency>
                    <groupId>com.auth0</groupId>
                    <artifactId>java-jwt</artifactId>
                    <version>${jwt.version}</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>
    

    此处用的标签是 dependencyManagement

    dependencyManagement只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

    🍪3.创建子模块-main(主启动层)

    右击项目chat-boot,new ->Moudle新建模块chat-boot-main

    选择对应Module SDK版本,本狗选择jdk1.8,点击Next

    填写子模块名 chat-boot-main,然后检查对应GAV,点击Finish

    生成子模块chat-boot-main如下图

    完善chat-boot-main模块下pom.xml中依赖

  • 引入必要依赖
  • 完善profiles标签中环境相关
  • 配置build标签中插件
  • <?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>chat-boot</artifactId>
            <groupId>net.javadog.chat</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>chat-boot-main</artifactId>
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>net.javadog.chat</groupId>
                    <artifactId>chat-boot-dependencies</artifactId>
                    <version>1.0-SNAPSHOT</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <dependencies>
            <!-- web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <!--swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
            </dependency>
            <!--swagger-ui-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
            </dependency>
            <!-- swagger接口文档 -->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
            </dependency>
        </dependencies>
        <build>
            <finalName>chat</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <fork>true</fork>
                    </configuration>
                </plugin>
            </plugins>
            <resources>
                <resource>
                    <directory>src/main/webapp</directory>
                    <filtering>false</filtering>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                </resource>
            </resources>
        </build>
        <profiles>
            <profile>
                <id>local</id>
                <properties>
                    <spring.active>local</spring.active>
                </properties>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
            </profile>
            <profile>
                <id>dev</id>
                <properties>
                    <spring.active>dev</spring.active>
                </properties>
            </profile>
            <profile>
                <id>prod</id>
                <properties>
                    <spring.active>prod</spring.active>
                </properties>
            </profile>
        </profiles>
    </project>
    
  • 配置引入依赖chat-boot-dependencies,用作此模块依赖引入
  • <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>net.javadog.chat</groupId>
                 <artifactId>chat-boot-dependencies</artifactId>
                 <version>1.0-SNAPSHOT</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
    </dependencyManagement>
    
  • 配置build标签用于完善插件plugins,其中包含maven-compiler-plugin和maven-resources-plugin
  • <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.6</version>
                    <configuration>
                        <delimiters>
                            <delimiter>@</delimiter>
                        </delimiters>
                        <useDefaultDelimiters>false</useDefaultDelimiters>
                    </configuration>
                </plugin>
            </plugins>
            <resources>
                <resource>
                    <directory>src/main/webapp</directory>
                    <filtering>false</filtering>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                </resource>
            </resources>
        </build>
    
  • 配置profiles环境变量标签,用于方便打包切换,本狗设置了 local、dev、prod三种环境
  •  <profiles>
         <profile>
             <id>local</id>
             <properties>
                 <spring.active>local</spring.active>
             </properties>
             <activation>
                 <activeByDefault>true</activeByDefault>
             </activation>
         </profile>
         <profile>
             <id>dev</id>
             <properties>
                 <spring.active>dev</spring.active>
             </properties>
         </profile>
         <profile>
             <id>prod</id>
             <properties>
                 <spring.active>prod</spring.active>
             </properties>
         </profile>
     </profiles>
    

    操作可在IDEA右上角方便切换环境 💥切记一定主动Reload一下Maven依赖 💥切记一定主动Reload一下Maven依赖 💥切记一定主动Reload一下Maven依赖

    在chat-boot-main模块中加入启动类,在src/main/java下右键New=>Java Class

    录入启动类名ChatApplication

    完善ChatApplication启动类代码

    package net.javadog.chat;
    import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.core.env.Environment;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
     * @author: hdx
     * @Date: 2023-01-28 11:24
     * @version: 1.0
    @SpringBootApplication
    @ServletComponentScan
    @Slf4j
    @EnableSwagger2
    @EnableKnife4j
    public class ChatApplication {
        public static void main(String[] args) throws UnknownHostException {
            // 启动类
            ConfigurableApplicationContext application = SpringApplication.run(ChatApplication.class, args);
            // 打印基础信息
            info(application);
        static void info(ConfigurableApplicationContext application) throws UnknownHostException {
            Environment env = application.getEnvironment();
            String ip = InetAddress.getLocalHost().getHostAddress();
            String port = env.getProperty("server.port");
            String active = env.getProperty("spring.profiles.active");
            String contextPath = env.getProperty("server.servlet.context-path");
            if (contextPath == null) {
                contextPath = "";
            log.info("\n----------------------------------------------------------\n\t" +
                    "欢迎访问  \thttps://blog.javadog.net\n\t" +
                    "示例程序【" + active + "】环境已启动! 地址如下:\n\t" +
                    "Local: \t\thttp://localhost:" + port + contextPath + "\n\t" +
                    "External: \thttp://" + ip + ':' + port + contextPath + '\n' +
                    "Swagger文档: \thttp://" + ip + ":" + port + contextPath + "/doc.html\n" +
                    "----------------------------------------------------------");
    

    配置application.yml文件

    application.yml

    #============================#
    # server 配置
    #============================#
    server:
      port: 82
      max-http-header-size: 10240
      servlet:
        context-path: /chat/v1
    #============================#
    # spring 配置
    #============================#
    spring:
      application:
        # 应用名
        name: chat
      profiles:
        active: @spring.active@
      servlet:
        multipart:
          max-request-size: 100MB
          max-file-size: 100MB
      jackson:
        time-zone: GMT+8
        date-format: yyyy-MM-dd HH:mm:ss.SSS
        locale: zh_CN
        serialization:
          # 格式化输出
          indent_output: false
      main:
        allow-circular-references: true
        #解决swagger版本路径不兼容问题
        pathmatch:
          matching-strategy: ant_path_matcher
    #============================#
    # mybatisplus 配置
    #============================#
    mybatis-plus:
      mapper-locations: classpath:mapper/*.xml
      configuration:
        map-underscore-to-camel-case: true
        cache-enabled: true
        lazy-loading-enabled: true
        multiple-result-sets-enabled: true
        log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
      global-config:
        banner: false
        db-config:
          id-type: assign_id
          table-underline: true
        enable-sql-runner: true
          #数据库类型
        db-type: MYSQL
      configuration-properties:
        prefix:
        #如果数据库为postgresql,则需要配置为blobType: BINARY
        blobType: BLOB
        #如果数据库为oracle或mssql,则需要配置为boolValue: 1
        boolValue: true
    #============================#
    # logging 配置
    #============================#
    logging:
      level:
        root: info
      file:
        path: /root/javadog/chat/logs/${spring.application.name}/
        name: ${spring.application.name}
      logback:
        rollingpolicy:
          max-history: 7
          max-file-size: 10MB
    #============================#
    # file 配置
    #============================#
    file:
      # 静态附件前缀
      static-prefix: attach
      # 上传的文件对外暴露的访问路径
      access-path-pattern: /${file.static-prefix}/**
      # 文件上传目录
      upload-folder: /root/javadog/chat/
      # 文件上传最大
      max-post-size: 10
    

    application-local.yml

    #服务配置
    server:
      port: 8001
      max-http-header-size: 10240
    # Mysql数据库
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/chat-boot?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true
        username: root
        password: root
      redis:
        host: localhost
        port: 6379
        password:
    

    application-dev.yml

    #服务配置
    server:
      port: 7001
      max-http-header-size: 10240
    # mybatisplus 配置
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    

    application-prod.yml

    #服务配置
    server:
      port: 8005
    

    🌊顺便加一下logback-spring.xml 日志文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration scan="true" scanPeriod="60 seconds" debug="false">
        <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
        <conversionRule conversionWord="wex"
                        converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
        <conversionRule conversionWord="wEx"
                        converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
        <property name="CONSOLE_LOG_PATTERN"
                  value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
        <property name="FILE_LOG_PATTERN"
                  value="${FILE_LOG_PATTERN:-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
        <springProperty scope="context" name="application.name" source="spring.application.name" defaultValue="javadog"/>
        <springProperty scope="context" name="logging.path" source="logging.file.path" defaultValue="logs"/>
        <springProperty scope="context" name="logging.file.max-size" source="logging.logback.rollingpolicy.max-size"
                        defaultValue="10MB"/>
        <springProperty scope="context" name="logging.file.max-history" source="logging.logback.rollingpolicy.max-history"
                        defaultValue="30"/>
        <contextName>${application.name}</contextName>
        <springProfile name="dev,prod">
            <!--输出到控制台-->
            <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
                <encoder>
                    <pattern>${CONSOLE_LOG_PATTERN}</pattern>
                </encoder>
            </appender>
            <root level="info">
                <appender-ref ref="console"/>
            </root>
        </springProfile>
        <springProfile name="dev,test,prod">
            <!--输出到文件-->
            <appender name="file-info" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>${logging.path}/info/${application.name}-info.log</file>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>${logging.path}/info/${application.name}-info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                        <maxFileSize>${logging.file.max-size}</maxFileSize>
                    </timeBasedFileNamingAndTriggeringPolicy>
                    <!--只保留最近n天的日志-->
                    <maxHistory>${logging.file.max-history}</maxHistory>
                </rollingPolicy>
                <!-- 追加方式记录日志 -->
                <append>true</append>
                <encoder>
                    <pattern>${FILE_LOG_PATTERN}</pattern>
                </encoder>
            </appender>
            <appender name="file-warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <filter class="ch.qos.logback.classic.filter.LevelFilter">
                    <level>warn</level>
                    <onMatch>ACCEPT</onMatch>
                    <onMismatch>DENY</onMismatch>
                </filter>
                <file>${logging.path}/warn/${application.name}-warn.log</file>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>${logging.path}$/warn/${application.name}-warn.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                        <maxFileSize>${logging.file.max-size}</maxFileSize>
                    </timeBasedFileNamingAndTriggeringPolicy>
                    <!--只保留最近n天的日志-->
                    <maxHistory>${logging.file.max-history}</maxHistory>
                </rollingPolicy>
                <encoder>
                    <pattern>${FILE_LOG_PATTERN}</pattern>
                </encoder>
            </appender>
            <appender name="file-error" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <filter class="ch.qos.logback.classic.filter.LevelFilter">
                    <level>error</level>
                    <onMatch>ACCEPT</onMatch>
                    <onMismatch>DENY</onMismatch>
                </filter>
                <file>${logging.path}/error/${application.name}-error.log</file>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>${logging.path}/error/${application.name}-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                        <maxFileSize>${logging.file.max-size}</maxFileSize>
                    </timeBasedFileNamingAndTriggeringPolicy>
                    <!--只保留最近n天的日志-->
                    <maxHistory>${logging.file.max-history}</maxHistory>
                </rollingPolicy>
                <encoder>
                    <pattern>${FILE_LOG_PATTERN}</pattern>
                </encoder>
            </appender>
            <root level="INFO">
                <appender-ref ref="file-info"/>
                <appender-ref ref="file-warn"/>
                <appender-ref ref="file-error"/>
            </root>
        </springProfile>
    </configuration>
    

    启动一下项目试试,启动如下证明成功。如果报错少依赖请再拉一下Maven依赖!!!

    <?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>chat-boot</artifactId>
            <groupId>net.javadog.chat</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>chat-boot-module</artifactId>
        <packaging>pom</packaging>
        <modules>
            <module>chat-boot-common</module>
            <module>chat-boot-controller</module>
            <module>chat-boot-dao</module>
            <module>chat-boot-dto</module>
            <module>chat-boot-entity</module>
            <module>chat-boot-service</module>
        </modules>
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>net.javadog.chat</groupId>
                    <artifactId>chat-boot-dependencies</artifactId>
                    <version>${project.parent.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <dependencies>
            <!-- web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--WxJava - 微信开发 Java SDK-->
            <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-miniapp</artifactId>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <!--hutool-->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
            </dependency>
            <!--swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
            </dependency>
            <!--swagger-ui-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
            </dependency>
            <!--整合Knife4j-->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
            </dependency>
            <!--整合Shiro安全框架-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
            </dependency>
            <!--jwt-->
            <dependency>
                <groupId>com.auth0</groupId>
                <artifactId>java-jwt</artifactId>
            </dependency>
            <!--mybatis-plus-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
        </dependencies>
    </project>
    

    一定要重新拉取依赖! 一定要重新拉取依赖! 一定要重新拉取依赖!

    🍉5.创建chat-boot-module模块下对应功能分层

    目前本狗分为如下6层

  • common-共通层
  • controller-控制器层
  • dao-数据持久层
  • dto-数据传输对象层
  • entity-实体层
  • service-业务逻辑层
  • 依次按照上述添加模块方式进行新增子模块,本狗如下示例一个,其余都如法炮制

    右击项目chat-boot-module,new ->Moudle新建模块chat-boot-common

    一定看清楚父模块是否正确 一定看清楚父模块是否正确 一定看清楚父模块是否正确

    确认父级模块后,点击Finish,生成chat-boot-common模块

    依次按照上述方法,新建其他模块

    chat-boot-controller模块

    chat-boot-dao模块

    chat-boot-dto模块

    chat-boot-entity模块

    chat-boot-service模块

    总体模块雏形基本完成

    🍧6.实际流程填充

  • 模拟正常前端请求后台服务调用过程,进行实际代码补充
  • 在chat-boot-entity下新建实体类User,在src/main/java下右键New=>Java Class,录入包名及类名

    package net.javadog.chat.entity;
    import lombok.Data;
     * @author: hdx
     * @Date: 2023-01-28 14:26
     * @version: 1.0
    @Data
    public class User {
        private Long id;
        private String username;
        private String idCard;
    

    在chat-boot-dto下新建目request和response,分别代表请求传输对象和返回传输对象,并分别在目录下创建UserRequest.java和UserResponse.java

    package net.javadog.chat.request;
    import lombok.Data;
     * @author: hdx
     * @Date: 2023-01-28 14:59
     * @version: 1.0
    @Data
    public class UserRequest {
        private Long id;
        private String username;
    
    package net.javadog.chat.response;
    import lombok.Data;
     * @author: hdx
     * @Date: 2023-01-28 14:59
     * @version: 1.0
    @Data
    public class UserResponse {
        private Long id;
        private String username;
    

    在chat-boot-dao下修改chat-boot-dao模块下修改pom.xml文件依赖,引入chat-boot-entity;并增对应UserMapper.java

    package net.javadog.chat.mapper;
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import net.javadog.chat.entity.User;
     * 用户mapper
     * @author: hdx
     * @Date: 2023-01-10 11:43
     * @version: 1.0
    public interface UserMapper extends BaseMapper<User> {
    
    <?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>chat-boot-module</artifactId>
            <groupId>net.javadog.chat</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>chat-boot-dao</artifactId>
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <dependencies>
            <dependency>
                <groupId>net.javadog.chat</groupId>
                <artifactId>chat-boot-entity</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
        </dependencies>
    </project>
    

    在chat-boot-service下新建目录service和impl,并在对应目录下新建UserService.java和UserServiceImpl.java,并修改chat-boot-service模块下修改pom.xml文件依赖,引入chat-boot-dto,chat-boot-dao

    package net.javadog.chat.service;
    import com.baomidou.mybatisplus.extension.service.IService;
    import net.javadog.chat.entity.User;
     * 用户接口
     * @author: hdx
     * @Date: 2023-01-10 11:53
     * @version: 1.0
    public interface UserService extends IService<User> {
    
    package net.javadog.chat.service.impl;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import net.javadog.chat.entity.User;
    import net.javadog.chat.mapper.UserMapper;
    import net.javadog.chat.service.UserService;
    import org.springframework.stereotype.Service;
     * 用户接口实现类
     * @author: hdx
     * @Date: 2023-01-10 11:55
     * @version: 1.0
    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    <?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>chat-boot-module</artifactId>
            <groupId>net.javadog.chat</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>chat-boot-service</artifactId>
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <dependencies>
            <dependency>
                <groupId>net.javadog.chat</groupId>
                <artifactId>chat-boot-dao</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
            <dependency>
                <groupId>net.javadog.chat</groupId>
                <artifactId>chat-boot-dto</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
        </dependencies>
    </project>
    

    在chat-boot-controller创建UserController.java,并修改chat-boot-controller模块下修改pom.xml文件依赖,引入chat-boot-dto,chat-boot-service

    package net.javadog.chat.controller;
    import cn.hutool.core.bean.BeanUtil;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import net.javadog.chat.entity.User;
    import net.javadog.chat.request.UserRequest;
    import net.javadog.chat.response.UserResponse;
    import net.javadog.chat.service.UserService;
    import org.springframework.web.bind.annotation.*;
    import javax.annotation.Resource;
     * 用户控制器
     * @author: hdx
     * @Date: 2022-12-07 15:48
     * @version: 1.0
    @Api(tags = "用户控制器")
    @RestController
    @RequestMapping("/user")
    public class UserController {
        @Resource
        private UserService userService;
        @ApiOperation(value = "用户详情", notes = "用户详情")
        @GetMapping
        public UserResponse detail(UserRequest userRequest){
            UserResponse userResponse = new UserResponse();
            User user = userService.getById(userRequest.getId());
            BeanUtil.copyProperties(user, userResponse);
            return userResponse;
    

    🎯重要补充 1.切记修改chat-boot-main下的pom.xml依赖,将chat-boot-controller模块加入 2.切记修改chat-boot-main下的pom.xml依赖,将chat-boot-dao模块加入 3.切记修改启动类ChatApplication中加入@MapperScan注解

    <?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>chat-boot</artifactId>
            <groupId>net.javadog.chat</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>chat-boot-main</artifactId>
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>net.javadog.chat</groupId>
                    <artifactId>chat-boot-dependencies</artifactId>
                    <version>1.0-SNAPSHOT</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <dependencies>
            <!-- web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <!--swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
            </dependency>
            <!--swagger-ui-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
            </dependency>
            <!-- swagger接口文档 -->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
            </dependency>
            <!-- controller -->
            <dependency>
                <groupId>net.javadog.chat</groupId>
                <artifactId>chat-boot-controller</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
            <!-- dao -->
            <dependency>
                <groupId>net.javadog.chat</groupId>
                <artifactId>chat-boot-dao</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.6</version>
                    <configuration>
                        <delimiters>
                            <delimiter>@</delimiter>
                        </delimiters>
                        <useDefaultDelimiters>false</useDefaultDelimiters>
                    </configuration>
                </plugin>
            </plugins>
            <resources>
                <resource>
                    <directory>src/main/webapp</directory>
                    <filtering>false</filtering>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                </resource>
            </resources>
        </build>
        <profiles>
            <profile>
                <id>local</id>
                <properties>
                    <spring.active>local</spring.active>
                </properties>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
            </profile>
            <profile>
                <id>dev</id>
                <properties>
                    <spring.active>dev</spring.active>
                </properties>
            </profile>
            <profile>
                <id>prod</id>
                <properties>
                    <spring.active>prod</spring.active>
                </properties>
            </profile>
        </profiles>
    </project>
    
    package net.javadog.chat;
    import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
    import lombok.extern.slf4j.Slf4j;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.core.env.Environment;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
     * @author: hdx
     * @Date: 2023-01-28 11:24
     * @version: 1.0
    @SpringBootApplication
    @ServletComponentScan
    @Slf4j
    @EnableSwagger2
    @EnableKnife4j
    @MapperScan(basePackages = {"net.javadog.chat.mapper"})
    public class ChatApplication {
        public static void main(String[] args) throws UnknownHostException {
            // 启动类
            ConfigurableApplicationContext application = SpringApplication.run(ChatApplication.class, args);
            // 打印基础信息
            info(application);
        static void info(ConfigurableApplicationContext application) throws UnknownHostException {
            Environment env = application.getEnvironment();
            String ip = InetAddress.getLocalHost().getHostAddress();
            String port = env.getProperty("server.port");
            String active = env.getProperty("spring.profiles.active");
            String contextPath = env.getProperty("server.servlet.context-path");
            if (contextPath == null) {
                contextPath = "";
            log.info("\n----------------------------------------------------------\n\t" +
                    "欢迎访问  \thttps://blog.javadog.net\n\t" +
                    "示例程序【" + active + "】环境已启动! 地址如下:\n\t" +
                    "Local: \t\thttp://localhost:" + port + contextPath + "\n\t" +
                    "External: \thttp://" + ip + ':' + port + contextPath + '\n' +
                    "Swagger文档: \thttp://" + ip + ":" + port + contextPath + "/doc.html\n" +
                    "----------------------------------------------------------");
    

    🦔7.示例DB更新

  • 模拟正常前端请求后台服务调用过程,进行实际代码补充
  • DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user`  (
      `id` bigint(20) NOT NULL COMMENT 'id',
      `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
      `id_card` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '身份证',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES (1, 'JavaDog', '123123');
    

    🧩8.访问测试

    浏览器访问http://localhost:8001/chat/v1/user?id=1

    测试成功如下图所示

    以上示例只是简单示范分层思路,其中代码逻辑实现方式有很多种,大家选取适用自己就好,希望自己的思路能对大家有帮助

    如遇缺少依赖情况,一定要重新拉取依赖!

    此生两悔,悔遇见你,更悔未早遇见你,珍惜当下拥有,勿念昔日美好。

    JavaDog狗屋地址
    个人博客blog.javadog.net
    公众号mp.weixin.qq.com/s/_vgnXoQ8F…
    CSDNblog.csdn.net/baidu_25986…
    掘金juejin.cn/user/217229…
    知乎www.zhihu.com/people/Java…
    简书www.jianshu.com/u/1ff9c6bdb…
    giteegitee.com/javadog-net
    GitHubgithub.com/javadog-net
    分类:
    后端
    标签: