还不会Spring Boot项目模块分层?来这手把手教你

前言

缘由

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

主要目标

  1. 熟练掌握SpringBoot项目分层思路,丝滑拆分模块
  2. 熟悉代码层级依赖,规范化管理模块分布
  3. 手把手实战学习,理论实践相结合

试用人群

  1. 对于Springboot熟悉但是不知道合理分层小白
  2. 有自己分层思路可以互相分享学习

水图

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

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

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

正文

1.IDEA新建项目

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

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

点击New->project

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

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

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

删除后项目目录

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

 
     org.springframework.boot
     spring-boot-starter-parent
     2.3.1.RELEASE
 
复制代码


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

    
        chat-boot
        net.javadog.chat
        1.0-SNAPSHOT
    
    4.0.0

    chat-dependencies

    pom

    
        8
        8
        UTF-8
        UTF-8
        8.0.17
        1.1.21
        3.4.1
        1.2.75
        5.5.8
        1.18.12
        4.2.0
        2.9.2
        2.9.2
        2.0.4
        4.4.5.B
        1.3.2
        3.2.0
    

    
        
            
            
                com.baomidou
                mybatis-plus-boot-starter
                ${mybatis-plus.version}
            

            
            
                mysql
                mysql-connector-java
                ${mysql-connector-java.version}
            

            
            
                com.alibaba
                druid
                ${druid.version}
            

            
            
                com.alibaba
                fastjson
                ${fastjson.version}
            

            
            
                cn.hutool
                hutool-all
                ${hutool.version}
            

            
            
                org.projectlombok
                lombok
                ${lombok.versin}
            

            
            
                io.springfox
                springfox-swagger2
                ${springfox-swagger2.version}
            

            
            
                io.springfox
                springfox-swagger-ui
                ${springfox-swagger-ui.version}
            

            
            
                com.github.xiaoymin
                knife4j-spring-boot-starter
                ${knife4j.version}
            

            
            
                cn.afterturn
                easypoi-base
                ${easypoi.version}
            

            
            
                com.github.binarywang
                weixin-java-miniapp
                ${weixin.version}
            

            
            
                org.apache.shiro
                shiro-spring
                ${shiro.version}
            

            
            
                com.auth0
                java-jwt
                ${jwt.version}
            
        
    

复制代码

重点

此处用的标签是 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中依赖

  1. 引入必要依赖
  2. 完善profiles标签中环境相关
  3. 配置build标签中插件
<?xml version="1.0" encoding="UTF-8"?>

    
        chat-boot
        net.javadog.chat
        1.0-SNAPSHOT
    
    4.0.0

    chat-boot-main

    
        8
        8
    

    
        
            
                net.javadog.chat
                chat-boot-dependencies
                1.0-SNAPSHOT
                pom
                import
            
        
    

    
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.projectlombok
            lombok
        
        
        
            io.springfox
            springfox-swagger2
        
        
        
            io.springfox
            springfox-swagger-ui
        
        
        
            com.github.xiaoymin
            knife4j-spring-boot-starter
        
    

    
        chat
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            repackage
                        
                    
                
                
                    true
                
            
        
        
            
                src/main/webapp
                false
            
            
                src/main/resources
                true
            
            
                src/main/java
                
                    **/*.xml
                
            
        
    

    
        
            local
            
                local
            
            
                true
            
        
        
            dev
            
                dev
            
        
        
            prod
            
                prod
            
        
    

复制代码

重点


     
         
             net.javadog.chat
             chat-boot-dependencies
             1.0-SNAPSHOT
             pom
             import
         
     

复制代码

        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.1
                
                    ${java.version}
                    ${java.version}
                
            
            
                org.apache.maven.plugins
                maven-resources-plugin
                2.6
                
                    
                        @
                    
                    false
                
            
        
        
            
                src/main/webapp
                false
            
            
                src/main/resources
                true
            
            
                src/main/java
                
                    **/*.xml
                
            
        
    
复制代码
 
     
         local
         
             local
         
         
             true
         
     
     
         dev
         
             dev
         
     
     
         prod
         
             prod
         
     
 
复制代码

操作可在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("
----------------------------------------------------------
	" +
                "欢迎访问  	https://blog.javadog.net
	" +
                "示例程序【" + active + "】环境已启动! 地址如下:
	" +
                "Local: 		http://localhost:" + port + contextPath + "
	" +
                "External: 	http://" + ip + ':' + port + contextPath + '
' +
                "Swagger文档: 	http://" + ip + ":" + port + contextPath + "/doc.html
" +
                "----------------------------------------------------------");
    }
}
复制代码

配置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版本路径不兼容问题
  mvc:
    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" ?>

    
    
    
    
    

    
    
    
    
    ${application.name}

    
        
        
            
                ${CONSOLE_LOG_PATTERN}
            
        
        
            
        
    

    
        
        
            ${logging.path}/info/${application.name}-info.log
            
                ${logging.path}/info/${application.name}-info.%d{yyyy-MM-dd}.%i.log

                
                    ${logging.file.max-size}
                
                
                ${logging.file.max-history}
            
            
            true
            
                ${FILE_LOG_PATTERN}
            
        
        
            
                warn
                ACCEPT
                DENY
            
            ${logging.path}/warn/${application.name}-warn.log
            
                ${logging.path}$/warn/${application.name}-warn.%d{yyyy-MM-dd}.%i.log
                
                    ${logging.file.max-size}
                
                
                ${logging.file.max-history}
            
            
                ${FILE_LOG_PATTERN}
            
        
        
            
                error
                ACCEPT
                DENY
            
            ${logging.path}/error/${application.name}-error.log
            
                ${logging.path}/error/${application.name}-error.%d{yyyy-MM-dd}.%i.log
                
                    ${logging.file.max-size}
                
                
                ${logging.file.max-history}
            
            
                ${FILE_LOG_PATTERN}
            
        

        
            
            
            
        
    


复制代码

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


4.创建子模块-module(模块层)

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

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

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

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

自此外部大框架初步搭建成功

完善chat-boot-module下pom.xml依赖,如lombok,web等必要依赖

<?xml version="1.0" encoding="UTF-8"?>

    
        chat-boot
        net.javadog.chat
        1.0-SNAPSHOT
    
    4.0.0

    chat-boot-module
    pom
    
        chat-boot-common
        chat-boot-controller
        chat-boot-dao
        chat-boot-dto
        chat-boot-entity
        chat-boot-service
    

    
        8
        8
    

    
        
            
                net.javadog.chat
                chat-boot-dependencies
                ${project.parent.version}
                pom
                import
            
        
    

    
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            com.github.binarywang
            weixin-java-miniapp
        
        
        
            org.projectlombok
            lombok
        
        
        
            cn.hutool
            hutool-all
        
        
        
            io.springfox
            springfox-swagger2
        
        
        
            io.springfox
            springfox-swagger-ui
        
        
        
            com.github.xiaoymin
            knife4j-spring-boot-starter
        
        
        
            org.apache.shiro
            shiro-spring
        
        
        
            com.auth0
            java-jwt
        
        
        
            com.baomidou
            mybatis-plus-boot-starter
        
        
            mysql
            mysql-connector-java
        
    


复制代码

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


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

目前本狗分为如下6层

依次按照上述添加模块方式进行新增子模块,本狗如下示例一个,其余都如法炮制

右击项目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 {
}

复制代码
<?xml version="1.0" encoding="UTF-8"?>

    
        chat-boot-module
        net.javadog.chat
        1.0-SNAPSHOT
    
    4.0.0

    chat-boot-dao

    
        8
        8
    

    
        
            net.javadog.chat
            chat-boot-entity
            ${project.parent.version}
        
    


复制代码

在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 {

}

复制代码
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 implements UserService {

}
复制代码
<?xml version="1.0" encoding="UTF-8"?>

    
        chat-boot-module
        net.javadog.chat
        1.0-SNAPSHOT
    
    4.0.0

    chat-boot-service

    
        8
        8
    

    
        
            net.javadog.chat
            chat-boot-dao
            ${project.parent.version}
        
        
            net.javadog.chat
            chat-boot-dto
            ${project.parent.version}
        
    


复制代码

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

    
        chat-boot
        net.javadog.chat
        1.0-SNAPSHOT
    
    4.0.0

    chat-boot-main

    
        8
        8
    

    
        
            
                net.javadog.chat
                chat-boot-dependencies
                1.0-SNAPSHOT
                pom
                import
            
        
    

    
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.projectlombok
            lombok
        
        
        
            io.springfox
            springfox-swagger2
        
        
        
            io.springfox
            springfox-swagger-ui
        
        
        
            com.github.xiaoymin
            knife4j-spring-boot-starter
        

        
        
            net.javadog.chat
            chat-boot-controller
            ${project.parent.version}
        
        
        
            net.javadog.chat
            chat-boot-dao
            ${project.parent.version}
        
    

    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.1
                
                    ${java.version}
                    ${java.version}
                
            
            
                org.apache.maven.plugins
                maven-resources-plugin
                2.6
                
                    
                        @
                    
                    false
                
            
        
        
            
                src/main/webapp
                false
            
            
                src/main/resources
                true
            
            
                src/main/java
                
                    **/*.xml
                
            
        
    

    
        
            local
            
                local
            
            
                true
            
        
        
            dev
            
                dev
            
        
        
            prod
            
                prod
            
        
    

复制代码

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("
----------------------------------------------------------
	" +
                "欢迎访问  	https://blog.javadog.net
	" +
                "示例程序【" + active + "】环境已启动! 地址如下:
	" +
                "Local: 		http://localhost:" + port + contextPath + "
	" +
                "External: 	http://" + ip + ':' + port + contextPath + '
' +
                "Swagger文档: 	http://" + ip + ":" + port + contextPath + "/doc.html
" +
                "----------------------------------------------------------");
    }
}
复制代码

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

测试成功如下图所示

总结

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

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

展开阅读全文

页面更新:2024-05-13

标签:模块   项目   示例   思路   版本   代码   标签   文件   目录   用户

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top