目录

一、Spring Boot 核心定位

二、Spring Boot 核心工作原理

1. 起步依赖(Starter Dependencies):简化依赖管理

2. 自动配置(AutoConfiguration):零配置启动

三、若依 Spring Boot 前后端分离版核心结构

四、核心注解详解(若依 + Spring Boot+MyBatis-Plus)

1. 框架配置层注解(项目启动核心)

2. 数据访问层注解(数据库交互核心)

3. 业务服务层注解(业务逻辑核心)

4. 控制层注解(接口访问核心)

5. 若依自定义增强注解(若依核心特色)

六、核心组件集成方法(Maven+MyBatis-Plus+Redis)

1. Maven 集成(pom.xml)

2. MyBatis-Plus 集成(核心配置)

3. Redis 集成(核心配置 + 工具类)

步骤 1:Redis 配置(application.yml)

步骤 2:Redis 配置类(若依已实现)

步骤 3:Redis 工具类使用(若依封装)

七、用户管理增删改查案例(基于若依规范)

1. 实体类(SysUser.java)

2. Mapper 接口(SysUserMapper.java)

3. Service 接口 + 实现类

(1)Service 接口(SysUserService.java)

(2)Service 实现类(SysUserServiceImpl.java)

4. Controller 控制器(SysUserController.java)

五、测试验证(Postman / 接口文档)

测试注意事项:

总结


本文深入若依 Spring Boot 前后端分离版的核心细节,包括注解解析、核心组件(Maven、MyBatis-Plus、Redis)集成方法,以及实现一个用户管理的增删改查案例并进行测试验证。若依 Spring Boot 前后端分离版的核心细节,重点包括注解解析、Maven/MyBatis-Plus/Redis 集成方法,并落地一个用户管理增删改查案例 + 测试。按 “框架核心结构→注解详解→核心组件集成→用户管理案例→测试验证” 的逻辑,给出可落地的完整教程。

一、Spring Boot 核心定位

Q:Spring Boot 是什么?核心目标与设计理念分别是什么?​

A:Spring Boot 是 Spring 框架的快速开发脚手架;核心目标是简化 Spring 应用的搭建、开发、部署流程;设计理念是 “约定优于配置”,消除传统 Spring 繁琐 XML 配置,让开发者聚焦业务逻辑。​

Q:基于 “约定优于配置” 的理念,Spring Boot 有哪些核心价值?​

A:​

开箱即用:集成 Spring MVC、MyBatis、Redis 等常用框架,无需手动整合;​

简化配置:通过注解和配置文件替代 XML,自动完成 Bean 注册、依赖注入;​

内嵌服务器:默认集成 Tomcat/Jetty,可直接打包为 Jar 包运行;​

生态完善:无缝兼容 Spring Security、Spring Data 等生态,支持微服务开发。​

Q:Spring Boot 对 IOC 容器的管理有什么特点?容器创建后如何管理 Bean?​

A:IOC 容器由框架全自动管理,无需手动实例化、刷新或配置,通过核心注解和默认规则自动完成容器创建、初始化、Bean 管理及生命周期管控;容器创建后,Bean 的生命周期和依赖注入也由框架全自动管理,开发者仅需标注注解即可。​

Q:实现 IOC 容器自动配置的核心注解是什么?它的本质是什么?​

A:核心注解是 @SpringBootApplication;其本质是复合注解,包含三个核心注解,共同支撑容器的自动配置功能。

注解 作用
@Configuration 标记当前类为配置类,容器会加载该类中的 @Bean 定义
@ComponentScan 自动扫描启动类所在包及子包下的 @Component/@Service/@Repository 等注解 Bean
@EnableAutoConfiguration 开启自动配置:加载 Spring Boot 内置的自动配置类(如 Tomcat、数据源等)

最简示例:一行代码启动容器

// 仅需这一个类,就能自动创建并启动 IOC 容器
@SpringBootApplication
public class AutoContainerApplication {
    public static void main(String[] args) {
        // 核心方法:自动创建容器 + 初始化 + 启动应用
        ConfigurableApplicationContext context = SpringApplication.run(AutoContainerApplication.class, args);
        System.out.println("容器自动创建完成,容器类型:" + context.getClass().getName());
    }
}

注解是什么? Java 的元数据,是贴在代码上的 “便签 / 指令”,本身不执行逻辑,需解析工具解读;

为什么需要注解? 简化配置(替代 XML)、标准化标记代码意图、支持工具自动化解析,降低开发和维护成本;

IOC 容器与注解的关联? 注解是容器的 “指令集”,容器是注解的 “执行引擎”—— 容器通过扫描→解析注解→按注解指令创建 / 注入 / 管理 Bean,最终完成 IOC 核心逻辑。

记住:注解是 “说” 的一方(告诉容器要做什么),IOC 容器是 “做” 的一方(按注解的要求完成 Bean 管理),二者配合实现了 Spring 自动化的核心能力

二、Spring Boot 核心工作原理

Spring Boot 的核心工作原理围绕 “自动配置(AutoConfiguration)、起步依赖(Starter Dependencies)、嵌入式服务器(Embedded Server)” 三大核心机制展开,以下是详细解析:

1. 起步依赖(Starter Dependencies):简化依赖管理

传统 Spring 项目需要手动引入大量依赖(如 Spring MVC、Jackson、Tomcat 等),且需协调版本冲突。Spring Boot 通过 “起步依赖” 将相关依赖打包整合,开发者只需引入一个 Starter,即可自动获得该场景所需的所有依赖。

原理示例

引入 spring-boot-starter-web 起步依赖,会自动包含:

Spring MVC 核心依赖(处理 HTTP 请求);

Tomcat 嵌入式服务器(无需单独部署);

Jackson 依赖(JSON 序列化 / 反序列化);

Spring 核心依赖(IOC、AOP 等)。

关键实现

Starter 本质是 Maven 的 “依赖传递” 封装,每个 Starter 的 pom.xml 中定义了该场景所需的所有依赖;

Spring Boot 维护统一的版本管理(parent 工程 spring-boot-starter-parent),避免版本冲突。

与若依的关联

若依的 ruoyi-admin 模块引入 spring-boot-starter-webmybatis-plus-boot-starter 等 Starter,无需手动配置依赖版本,直接复用 Spring Boot 的版本管理。

2. 自动配置(AutoConfiguration):零配置启动

自动配置是 Spring Boot 最核心的机制,核心目标是 “根据类路径下的依赖,自动创建 Bean 并配置”,无需手动编写 XML 或 Java 配置。

核心原理步骤

注解触发@SpringBootApplication 注解包含 @EnableAutoConfiguration,该注解会开启自动配置;

扫描配置文件:Spring Boot 启动时,会扫描 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件(Spring Boot 2.7 + 版本),该文件中定义了所有自动配置类的全路径;

条件注解判断:每个自动配置类(如 RedisAutoConfigurationMybatisPlusAutoConfiguration)都包含条件注解(如 @ConditionalOnClass@ConditionalOnMissingBean),只有满足条件才会生效;

示例:RedisAutoConfiguration 包含 @ConditionalOnClass(RedisTemplate.class),当类路径下存在 Redis 依赖时,才会自动创建 RedisTemplate Bean;

配置绑定:通过 @ConfigurationProperties 注解,将 application.yml/application.properties 中的配置(如 spring.redis.host)绑定到自动配置类的属性中,实现自定义配置。

三、若依 Spring Boot 前后端分离版核心结构

先明确框架基础结构,理解注解和集成的上下文:

ruoyi-vue/

├── ruoyi-admin (后端核心模块,Spring Boot应用)

│   ├── src/main/java/com/ruoyi/

│   │   ├── common/ (通用注解、工具类)

│   │   ├── framework/ (框架配置:MyBatis-Plus、Redis、MVC)

│   │   ├── system/ (核心业务:用户、角色、菜单管理)

│   │   └── RuoyiApplication.java (启动类)

│   └── pom.xml (Maven依赖配置)

└── ruoyi-ui (前端Vue项目,无需关注注解)

核心:后端基于 Spring Boot + MyBatis-Plus + Redis,所有注解和集成操作都在ruoyi-admin模块完成。

四、核心注解详解(若依 + Spring Boot+MyBatis-Plus)

若依在 Spring Boot 基础上封装了大量通用注解,结合 MyBatis-Plus 注解,以下是高频核心注解:

Spring Boot 注解核心遵循 “分层设计” 思想,配合若依自定义注解,形成 “框架配置→数据层→业务层→控制层→通用增强” 的完整体系,以下是分类明细:

分层

核心注解集群

核心作用

框架配置层

@SpringBootApplication、@Configuration、@Bean、@MapperScan

项目启动、组件配置、依赖注入

数据访问层

@TableName、@TableId、@TableField、@TableLogic、@Transactional

数据库映射、事务控制

业务服务层

@Service、@Autowired、@Resource、@Qualifier

服务注册、依赖注入

控制层

@RestController、@RequestMapping、@GetMapping/@PostMapping、@PathVariable 等

接口定义、请求映射、参数接收

若依增强层

@Log、@Dict、@PreAuthorize、@Validated

日志记录、字典转换、权限校验

五、各分层注解深度解析(含若依封装)

1. 框架配置层注解(项目启动核心)

负责 Spring Boot 项目的初始化、组件注册、配置加载,是项目运行的基础。

注解名称

归属框架

核心功能

使用场景 + 示例

避坑要点

@SpringBootApplication

Spring Boot

整合 3 大注解:1. @Configuration(配置类). @EnableAutoConfiguration(自动配置)3. @ComponentScan(组件扫描)

项目启动类唯一注解 @SpringBootApplication class RuoyiApplication {    public static void main(String[] args) {Application.run(RuoyiApplication.class, args);    }>}`

1. 仅用在启动类,不可重复标注 2. 扫描范围默认是启动类所在包及子包

@Configuration

Spring Boot

标记类为配置类,替代传统 xml 配置文件,内部可通过 @Bean 注册组件

配置 MyBatis-Plus、Redis 等组件 @ConfigurationConfig {@Bean RedisTemplate redisTemplate () { ... }}`

1. 配置类需被 @ComponentScan 扫描到 > 2. @Bean 方法返回值会被注册为 Spring Bean

@Bean

Spring Boot

注册自定义组件到 Spring 容器,交给 Spring 管理

注册分页插件、RedisTemplate 等 @BeanPlusInterceptor mybatisPlusInterceptor () { ...}`

1. 仅用在 @Configuration 类的方法上 Bean 名称为方法名,可通过 name 属性指定

@MapperScan

MyBatis-Plus

扫描 MyBatis-Plus 的 Mapper 接口,自动生成代理对象,无需手动加 @Mapper

若依已配置在启动类,扫描所有 Mapper ("com.ruoyi.**.mapper")`

1. 路径需覆盖所有 Mapper 包(用 ** 匹配多级目录)2. 无需在 Mapper 接口加 @Mapper

2. 数据访问层注解(数据库交互核心)

对接 MyBatis-Plus,负责实体与数据库表映射、CRUD 操作、事务控制,若依默认集成并简化配置。

注解名称

归属框架

核心功能

使用场景 + 示例

避坑要点

@TableName

MyBatis-Plus

实体类与数据库表映射,指定表名

若依实体类必加注解@TableName("sys_user") SysUser extends BaseEntity { ... }

1. 表名需与数据库一致(若依规范:小写 + 下划线)2. 若实体名与表名一致可省略

@TableId

MyBatis-Plus

标记主键字段,指定主键生成策略

自增主键(MySQL 常用)@TableId(type = IdType.AUTO);

1. 生成策略需与数据库主键类型匹配(如 AUTO 对应自增)2. 主键类型推荐 Long(避免溢出)

@TableField

MyBatis-Plus

普通字段与数据库列映射,控制字段是否入库

字段映射(驼峰转下划线可省略)@TableField("user_name")private String userName;

1. 忽略非数据库字段用exist=false字段名与列名一致(驼峰转下划线)可省略

@TableLogic

MyBatis-Plus

逻辑删除注解(标记删除状态字段)

若依实体类默认集成@TableLogic>private String delFlag;(0 = 正常,1 = 删除)

1. 需配合数据库字段默认值(如 del_flag DEFAULT 0)2. 删除操作会自动转为更新 del_flag

@Transactional

Spring

声明式事务,控制事务提交 / 回滚

服务层增删改操作必加 (rollbackFor = Exception.class) User (SysUser user) { ... }`

1. 建议指定 rollbackFor=Exception.class(默认仅回滚 RuntimeException) 仅作用于 public 方法

3. 业务服务层注解(业务逻辑核心)

负责服务组件注册、依赖注入,若依遵循 Spring 规范,同时优化了依赖注入方式。

注解名称

归属框架

核心功能

使用场景 + 示例

@Service

Spring

标记类为业务层组件,注册到 Spring 容器

若依 Service 实现类必加@Service class SysUserServiceImpl implements SysUserService { ... }

@Autowired

Spring

按类型自动依赖注入(Spring 核心)

注入 Mapper、Service 等 @AutowiredUserMapper sysUserMapper;`

@Resource

JDK(Spring 支持)

按名称 / 类型注入(兼容 JDK 规范)

按名称注入特定 Bean@Resource (name = "sysUserService") private SysUserService userService;`

@Qualifier

Spring

配合 @Autowired,按名称注入 Bean

解决同类型 Bean 冲突 >@AutowiredQualifier("sysUserService")UserService userService;

4. 控制层注解(接口访问核心)

负责 HTTP 请求映射、参数接收、响应返回,若依封装了统一响应格式(AjaxResult)。

注解名称

归属框架

核心功能

使用场景 + 示例

@RestController

Spring MVC

整合 @Controller+@ResponseBody,标记 REST 接口控制器

若依所有接口控制器必加 @RestControllerRequestMapping ("/system/user")public class SysUserController { ... }`

@RequestMapping

Spring MVC

基础请求映射,指定 URL、请求方法、请求头

类级 / 方法级映射 @RequestMapping (value = "/list", method = RequestMethod.GET)`

@GetMapping

Spring MVC

简化 @RequestMapping,仅接收 GET 请求

查询类接口@GetMapping("/{userId}") AjaxResult getInfo(@PathVariable Long userId) { ... }

@PostMapping

Spring MVC

仅接收 POST 请求,用于提交数据

新增类接口 Mapping (@RequestBody SysUser user) { ... }`

@PutMapping

Spring MVC

仅接收 PUT 请求,用于更新数据

修改类接口public AjaxResult edit(@RequestBody SysUser user) { ... }`

@DeleteMapping

Spring MVC

仅接收 DELETE 请求,用于删除数据

删除类接口 DeleteMapping ("/{userIds}") Result remove (@PathVariable Long [] userIds) { ... }`

@PathVariable

Spring MVC

接收 URL 路径中的参数

接收路径中的 ID 参数 {userId}")>public AjaxResult getInfo (@PathVariable Long userId) { ... }`

@RequestBody

Spring MVC

接收 JSON 格式的请求体,绑定到实体类

接收新增 / 修改的实体数据@PostMapping>public AjaxResult add(@RequestBody SysUser user) { ... }

@RequestParam

Spring MVC

接收 URL 查询参数或表单参数

接收分页参数、查询条件 @GetMapping ("/list")public TableDataInfo list(@RequestParam(defaultValue = "1") Integer pageNum) { ... }`

5. 若依自定义增强注解(若依核心特色)

若依在 Spring Boot 基础上封装的高频注解,解决日志、权限、字典等通用需求,开箱即用。

注解名称

归属框架

核心功能

使用场景 + 示例

避坑要点

@Log

若依自定义

记录操作日志(自动入库 sys_oper_log 表),包含操作人、时间、模块等

接口层增删改操作必加@Log(title = "用户管理", businessType = BusinessType.INSERT)<br>@PostMapping>public AjaxResult add(...) { ... }

1. title(模块名称)和 businessType(操作类型)必填。仅作用于控制层方法

@Dict

若依自定义

字典转换(将编码转为中文显示,如 1 = 男、2 = 女)

实体类字典字段标注@Dict(dictType = "sys_user_sex") String sex;

1. dictType 需与字典表(sys_dict_type)的 dict_type 一致 > 2. 仅在返回前端时生效(数据库存储编码)

@PreAuthorize

Spring Security + 若依封装

接口权限校验,基于 RBAC 模型(用户 - 角色 - 权限)

控制接口访问权限@PreAuthorize("@ss.hasPermi('system:user:add')")Mapping(...) { ... }

1. 权限标识(如 system:user:add)需在菜单表(sys_menu)中配置需登录后携带 Token 访问

@Validated

Spring

入参校验(配合 JSR-380 注解,如 @NotBlank、@NotNull)

新增 / 修改接口的参数校验public AjaxResult add(@Validated @RequestBody SysUser user) { ... }`

1. 需在实体类字段上加校验注解(如 @NotBlank (message = "用户名不能为空")) 若依会自动捕获校验异常并返回统一错误信息

六、核心组件集成方法(Maven+MyBatis-Plus+Redis)

若依已默认集成这些组件,以下是 “理解配置 + 自定义扩展” 的核心步骤:

1. Maven 集成(pom.xml)

若依采用模块化 Maven,核心依赖在ruoyi-admin/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">

    <parent>

        <groupId>com.ruoyi</groupId>

        <artifactId>ruoyi</artifactId>

        <version>4.7.7</version> <!-- 若依版本 -->

    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>ruoyi-admin</artifactId>

    <name>ruoyi-admin</name>

    <description>若依管理系统-后端核心模块</description>

    <!-- 核心依赖 -->

    <dependencies>

        <!-- 1. Spring Boot核心 -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

        <!-- 2. MyBatis-Plus集成(若依已封装) -->

        <dependency>

            <groupId>com.baomidou</groupId>

            <artifactId>mybatis-plus-boot-starter</artifactId>

            <version>3.5.3.1</version>

        </dependency>

        <!-- 3. Redis集成 -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-data-redis</artifactId>

        </dependency>

        <!-- 4. 若依核心封装 -->

        <dependency>

            <groupId>com.ruoyi</groupId>

            <artifactId>ruoyi-common</artifactId>

        </dependency>

    </dependencies>

    <!-- 打包配置 -->

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

                <configuration>

                    <mainClass>com.ruoyi.RuoyiApplication</mainClass>

                </configuration>

            </plugin>

        </plugins>

    </build>

</project>

关键说明:若依已将通用依赖抽离到父工程ruoyi/pom.xml,子模块只需继承即可,无需重复声明版本。

2. MyBatis-Plus 集成(核心配置)

若依在com.ruoyi.framework.config.MybatisPlusConfig中完成配置,核心代码:

@Configuration

@MapperScan("com.ruoyi.**.mapper") // 扫描所有Mapper接口

public class MybatisPlusConfig {

    /**

     * 分页插件(若依核心,无需手动写分页SQL)

     */

    @Bean

    public MybatisPlusInterceptor mybatisPlusInterceptor() {

        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 适配MySQL

        return interceptor;

    }

    /**

     * 开启MyBatis-Plus日志(开发环境用)

     */

    @Bean

    public ConfigurationCustomizer configurationCustomizer() {

        return configuration -> configuration.setLogImpl(StdOutImpl.class);

    }

}

扩展使用:自定义 Mapper 只需继承BaseMapper,无需写 CRUD SQL:

public interface SysUserMapper extends BaseMapper<SysUser> {

    // 自定义SQL用@Select,如:

    // @Select("select * from sys_user where user_name = #{userName}")

    // SysUser selectByUserName(String userName);

}

3. Redis 集成(核心配置 + 工具类)

若依封装了 Redis 工具类com.ruoyi.common.core.redis.RedisCache,开箱即用。

步骤 1:Redis 配置(application.yml)

spring:

  # Redis配置

  redis:

    host: localhost # Redis服务器地址

    port: 6379 # Redis端口

    password: # 密码(无则空)

    database: 0 # 数据库索引

    timeout: 10000ms # 连接超时时间

    lettuce:

      pool:

        max-active: 100 # 最大连接数

        max-idle: 10 # 最大空闲连接

        min-idle: 5 # 最小空闲连接

步骤 2:Redis 配置类(若依已实现)

@Configuration

@EnableCaching

public class RedisConfig {

    /**

     * 序列化配置(解决乱码)

     */

    @Bean

    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();

        template.setConnectionFactory(factory);

        // 使用Jackson2JsonRedisSerializer序列化

        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);

        ObjectMapper mapper = new ObjectMapper();

        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

        serializer.setObjectMapper(mapper);

        // 设置key/value序列化

        template.setKeySerializer(new StringRedisSerializer());

        template.setValueSerializer(serializer);

        template.setHashKeySerializer(new StringRedisSerializer());

        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();

        return template;

    }

}

步骤 3:Redis 工具类使用(若依封装)

// 注入工具类

@Autowired

private RedisCache redisCache;

// 存值:key=user:1, value=user对象, 过期时间5分钟

redisCache.setCacheObject("user:1", user, 5, TimeUnit.MINUTES);

// 取值

SysUser user = redisCache.getCacheObject("user:1");

// 删除

redisCache.deleteObject("user:1");

七、用户管理增删改查案例(基于若依规范)

以下是 “自定义用户管理模块” 的完整代码(若依风格),包含 Entity、Mapper、Service、Controller,实现核心 CRUD。

Spring Boot作为轻量级的Spring框架封装版,核心依托Spring IOC容器实现Java对象的全生命周期管理,通过分层架构+注解驱动实现业务解耦,结合各类中间件完成灵活协作与高效数据操作,最终为用户提供优化的使用体验,其整体设计围绕对象管理、分层交互、中间件协同三大核心展开。

一、总体设计思路

  1. 核心依托Spring IOC容器,实现所有Java对象的创建、管理、销毁全生命周期管控,是Spring Boot应用启动和运行的先决条件;
  1. 采用注解驱动的方式,将各层级的类、接口自动注入IOC容器,无需手动管理对象依赖;
  1. 设计分层架构(Controller、Service、Mapper、Model),明确各层职责,实现业务与数据、各层级间的解耦;
  1. 引入各类中间件(Redis、MyBatis Plus、MQ等),既省去大量重复编程工作,又实现异步操作、灵活协作,同时通过Maven实现中间件的统一管理与激活;
  1. 全程采用面向对象(ORM) 的数据操作方式,以数据库表反射生成的实体类作为数据交互的核心载体,实现前后端、后端各层的统一数据传输;
  1. 内置权限逻辑,根据用户权限级别展示不同的前端页面、菜单和操作按钮,实现精细化的访问控制。

二、各层级组成及依赖关系

Spring Boot Web应用核心分为Controller层、Service层、Mapper层(数据层)、Model层(实体层) 四层,所有层级的类/接口均通过注解注入IOC容器,由容器统一管理,层级间为上层调用下层、下层为上层提供支撑的依赖关系,核心依赖链路为:Controller层 → Service层 → Mapper层,Model层为所有层级提供公共的实体对象支撑。

1. Model层(实体层)

  • 核心作用:作为全应用的公共数据载体,是前后端、后端各层数据交互的核心对象;
  • 生成方式:通过数据库表反射自动生成实体类,避免手动编写,适配多表场景;
  • 容器管理:实体类会被注入IOC容器,实现全局的对象实例化与调用;
  • 依赖关系:无底层依赖,为Controller、Service、Mapper三层提供统一的操作对象,同时与前端页面进行数据交互。

2. Mapper层(数据层)

  • 核心作用:封装所有数据的增删改查操作,是应用与数据库交互的唯一入口;
  • 操作方式:基于MyBatis Plus中间件,采用ORM面向对象方式操作数据库,无需直接编写SQL语句;
  • 依赖关系:依赖Model层的实体类,以实体类为操作对象实现数据库的读写;为上层Service层提供数据操作支撑,接收Service层的业务指令执行数据操作。

3. Service层(业务逻辑层)

  • 核心作用:处理应用的核心业务逻辑,承接Controller层的请求,调用Mapper层完成数据操作并封装业务结果;
  • 分层设计:分为接口定义实现逻辑两部分,职责分离:
  • 接口定义:由业务人员参与,明确业务场景下的各类逻辑接口;
  • 实现逻辑:由开发/数据人员参与,基于Mapper层实现接口的具体业务逻辑;
  • 依赖关系:依赖下层Mapper层获取数据支撑,依赖Model层的实体类进行数据封装与传递;为上层Controller层提供业务逻辑调用能力。

4. Controller层(控制层)

  • 核心作用:作为前后端交互的入口,接收前端用户的请求和数据,调用Service层处理业务,最终将结果以指定格式返回前端;
  • 核心注解:@RestController(标识控制层)、@GetMapping/@RequestMapping等(映射前端请求方式);
  • 权限关联:承接系统内置的权限逻辑,根据用户权限处理对应的请求操作,仅返回权限范围内的结果;
  • 依赖关系:依赖下层Service层的业务逻辑接口,依赖Model层的实体类进行前端数据的接收与返回封装;是前端页面的唯一后端请求入口。

三、数据传输逻辑

Spring Boot应用中所有数据传输的载体为Model层的实体类对象,对象经IOC容器实例化后,在前后端、后端各层之间实现无缝传递,全程围绕**“对象实例化 → 层级间传递 → 数据处理/返回”** 展开,具体流程如下:

1. 前端到后端的传输:用户操作触发数据提交

  1. 用户基于自身权限在前端页面进行操作(查询、提交表单等),将数据以请求形式提交;
  1. 后端Controller层通过注解映射接收前端请求,将请求数据封装为Model层的实体类对象,完成前端数据到后端对象的转换。

2. 后端各层间的传输:层级调用实现对象传递

  1. Controller层将封装好的实体类对象作为参数,调用Service层的业务逻辑接口,实现对象从Controller层到Service层的传递;
  1. Service层根据业务逻辑,将实体类对象作为数据操作依据,调用Mapper层的增删改查方法,实现对象从Service层到Mapper层的传递;
  1. Mapper层以实体类对象为操作对象,基于ORM方式与数据库交互,完成数据的读写,将操作结果封装为实体类对象回传给Service层
  1. Service层对Mapper层返回的实体类对象进行业务逻辑处理,将最终的业务结果封装为实体类对象回传给Controller层

3. 后端到前端的传输:结果封装为JSON格式返回

  1. Controller层接收Service层回传的实体类对象,将其转换为JSON格式
  1. 以JSON格式将数据返回至前端页面,前端解析数据并展示,完成一次完整的请求-响应流程。

4. 核心传输原则

  1. 全程以Model层实体类对象为数据载体,所有层级的交互均基于对象,统一数据格式;
  1. 实体类对象由IOC容器实例化后注入各层级,实现全局可调用,避免重复创建对象;
  1. 前后端的数据交互以JSON格式为标准,由@RestController注解自动实现对象与JSON的转换;
  1. 后端各层的操作均围绕实体类对象展开,实现数据操作的标准化和统一化。

四、中间件的协同与管理

1. 核心中间件及作用

Spring Boot引入的中间件核心实现解耦简化编程两大作用,同时支撑异步操作和灵活协作,各中间件职责如下:

  • MyBatis Plus:作为数据层中间件,实现ORM面向对象的数据库操作,替代原生SQL,简化数据层开发;
  • Redis:提供缓存能力,优化数据访问效率,降低数据库压力;
  • MQ:实现生产方与消费方的解耦,支撑异步操作,避免系统间的强依赖(如美团外卖柜解耦订餐与送餐用户的逻辑)。

2. 中间件的管理与激活

  1. 依赖管理:通过Maven项目管理工具,在pom.xml文件中引入各中间件的依赖,实现中间件的统一管理;
  1. 配置生效:在pom.xml或项目资源目录中完成中间件的配置(如端口号、地址、用户名/权限等);
  1. 容器激活:当Spring Boot应用启动、IOC容器初始化时,已配置的中间件会被自动激活,可在各层级中直接调用。

3. 中间件的协同逻辑

Spring Boot作为中间件的集成平台,将各类中间件整合到分层架构中,让中间件在对应层级发挥作用:

  • 数据层集成MyBatis Plus,实现高效的数据库操作;
  • 全应用集成Redis,实现数据缓存的全局调用;
  • 业务层集成MQ,实现业务逻辑的异步处理和解耦;
  • 所有中间件基于IOC容器和Maven实现统一管理,确保各组件协同工作,提升系统的可扩展性和灵活性。

五、应用启动的核心前提

Spring Boot Web应用启动的最先决条件Spring IOC容器的初始化

  1. 在程序的main方法中,通过ApplicationContext相关注解触发IOC容器启动;
  1. 容器启动时,自动扫描项目中带有注解的Controller、Service、Mapper、Model层的类/接口,将其自动注入容器

容器完成所有对象的实例化和依赖管理后,各层级才可实现正常的调用和交互,应用正式具备对外提供服务的能力。

1. 实体类(SysUser.java)

package com.ruoyi.system.domain;

import com.baomidou.mybatisplus.annotation.*;

import com.ruoyi.common.core.domain.BaseEntity;

import com.ruoyi.common.annotation.Dict;

import lombok.Data;

import lombok.EqualsAndHashCode;

import java.util.Date;

/**

 * 用户实体类(若依规范:继承BaseEntity,包含创建/更新时间)

 */

@Data

@EqualsAndHashCode(callSuper = true)

@TableName("sys_user") // 映射数据库表

public class SysUser extends BaseEntity {

    private static final long serialVersionUID = 1L;

    /** 主键ID */

    @TableId(type = IdType.AUTO) // 自增主键

    private Long userId;

    /** 用户名 */

    @TableField("user_name") // 映射user_name列

    private String userName;

    /** 昵称 */

    @TableField("nick_name")

    private String nickName;

    /** 密码 */

    @TableField("password")

    private String password;

    /** 性别(1=男,2=女) */

    @TableField("sex")

    @Dict(dictType = "sys_user_sex") // 若依字典注解,自动转换显示值

    private String sex;

    /** 手机号 */

    @TableField("phonenumber")

    private String phonenumber;

    /** 状态(0=禁用,1=正常) */

    @TableField("status")

    private String status;

    /** 删除标志(0=正常,1=删除) */

    @TableField("del_flag")

    @TableLogic // MyBatis-Plus逻辑删除注解

    private String delFlag;

    /** 创建时间(若依BaseEntity已封装,无需手动赋值) */

    @TableField(value = "create_time", fill = FieldFill.INSERT)

    private Date createTime;

}

2. Mapper 接口(SysUserMapper.java)

package com.ruoyi.system.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import com.ruoyi.system.domain.SysUser;

import org.springframework.stereotype.Repository;

/**

 * 用户Mapper(继承BaseMapper,无需写基础CRUD)

 */

@Repository // 标记为持久层组件

public interface SysUserMapper extends BaseMapper<SysUser> {

    // 自定义SQL可在此扩展,如根据用户名查询

    // SysUser selectByUserName(String userName);

}

3. Service 接口 + 实现类
(1)Service 接口(SysUserService.java)

package com.ruoyi.system.service;

import com.baomidou.mybatisplus.extension.service.IService;

import com.ruoyi.system.domain.SysUser;

import com.ruoyi.common.core.page.TableDataInfo;

import java.util.List;

/**

 * 用户Service(继承IService,扩展MyBatis-Plus基础方法)

 */

public interface SysUserService extends IService<SysUser> {

    /**

     * 分页查询用户列表

     */

    TableDataInfo selectUserList(SysUser sysUser);

    /**

     * 根据ID查询用户

     */

    SysUser selectUserById(Long userId);

    /**

     * 新增用户

     */

    int insertUser(SysUser sysUser);

    /**

     * 修改用户

     */

    int updateUser(SysUser sysUser);

    /**

     * 删除用户(逻辑删除)

     */

    int deleteUserById(Long userId);

}

(2)Service 实现类(SysUserServiceImpl.java)

package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ruoyi.common.core.page.TableDataInfo;

import com.ruoyi.common.utils.PageUtils;

import com.ruoyi.system.domain.SysUser;

import com.ruoyi.system.mapper.SysUserMapper;

import com.ruoyi.system.service.SysUserService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**

 * 用户Service实现类(继承ServiceImpl,封装BaseMapper)

 */

@Service

public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired

    private SysUserMapper sysUserMapper;

    /**

     * 分页查询用户列表(若依规范分页)

     */

    @Override

    public TableDataInfo selectUserList(SysUser sysUser) {

        // 构造分页条件

        Page<SysUser> page = new Page<>(PageUtils.getPageNum(), PageUtils.getPageSize());

        // 构造查询条件(模糊查询用户名/昵称)

        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();

        queryWrapper.like(sysUser.getUserName() != null, SysUser::getUserName, sysUser.getUserName())

                    .like(sysUser.getNickName() != null, SysUser::getNickName, sysUser.getNickName())

                    .eq(SysUser::getDelFlag, "0"); // 排除已删除数据

        // 执行分页查询

        Page<SysUser> userPage = sysUserMapper.selectPage(page, queryWrapper);

        // 封装若依分页结果

        return PageUtils.buildTableDataInfo(userPage.getRecords(), userPage.getTotal());

    }

    /**

     * 根据ID查询用户

     */

    @Override

    public SysUser selectUserById(Long userId) {

        return sysUserMapper.selectById(userId);

    }

    /**

     * 新增用户(事务控制)

     */

    @Override

    @Transactional(rollbackFor = Exception.class)

    public int insertUser(SysUser sysUser) {

        // 若依密码加密(可选)

        // sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword()));

        return sysUserMapper.insert(sysUser);

    }

    /**

     * 修改用户

     */

    @Override

    @Transactional(rollbackFor = Exception.class)

    public int updateUser(SysUser sysUser) {

        return sysUserMapper.updateById(sysUser);

    }

    /**

     * 删除用户(逻辑删除)

     */

    @Override

    @Transactional(rollbackFor = Exception.class)

    public int deleteUserById(Long userId) {

        return sysUserMapper.deleteById(userId); // MyBatis-Plus自动执行逻辑删除

    }

}

4. Controller 控制器(SysUserController.java)

package com.ruoyi.system.controller;

import com.ruoyi.common.annotation.Log;

import com.ruoyi.common.core.controller.BaseController;

import com.ruoyi.common.core.domain.AjaxResult;

import com.ruoyi.common.core.page.TableDataInfo;

import com.ruoyi.common.enums.BusinessType;

import com.ruoyi.common.utils.SecurityUtils;

import com.ruoyi.system.domain.SysUser;

import com.ruoyi.system.service.SysUserService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.access.prepost.PreAuthorize;

import org.springframework.validation.annotation.Validated;

import org.springframework.web.bind.annotation.*;

/**

 * 用户控制器(若依规范:继承BaseController,返回AjaxResult/TableDataInfo)

 */

@RestController

@RequestMapping("/system/user")

public class SysUserController extends BaseController {

    @Autowired

    private SysUserService sysUserService;

    /**

     * 分页查询用户列表

     */

    @PreAuthorize("@ss.hasPermi('system:user:list')") // 权限校验

    @GetMapping("/list")

    public TableDataInfo list(SysUser sysUser) {

        return sysUserService.selectUserList(sysUser);

    }

    /**

     * 根据ID查询用户详情

     */

    @PreAuthorize("@ss.hasPermi('system:user:query')")

    @GetMapping(value = "/{userId}")

    public AjaxResult getInfo(@PathVariable Long userId) {

        return AjaxResult.success(sysUserService.selectUserById(userId));

    }

    /**

     * 新增用户

     */

    @PreAuthorize("@ss.hasPermi('system:user:add')")

    @Log(title = "用户管理", businessType = BusinessType.INSERT) // 操作日志

    @PostMapping

    public AjaxResult add(@Validated @RequestBody SysUser sysUser) {

        // 模拟创建人赋值(若依BaseEntity自动处理)

        sysUser.setCreateBy(SecurityUtils.getUsername());

        return toAjax(sysUserService.insertUser(sysUser));

    }

    /**

     * 修改用户

     */

    @PreAuthorize("@ss.hasPermi('system:user:edit')")

    @Log(title = "用户管理", businessType = BusinessType.UPDATE)

    @PutMapping

    public AjaxResult edit(@Validated @RequestBody SysUser sysUser) {

        sysUser.setUpdateBy(SecurityUtils.getUsername());

        return toAjax(sysUserService.updateUser(sysUser));

    }

    /**

     * 删除用户

     */

    @PreAuthorize("@ss.hasPermi('system:user:remove')")

    @Log(title = "用户管理", businessType = BusinessType.DELETE)

    @DeleteMapping("/{userIds}")

    public AjaxResult remove(@PathVariable Long[] userIds) {

        int count = 0;

        for (Long userId : userIds) {

            count += sysUserService.deleteUserById(userId);

        }

        return toAjax(count);

    }

}

五、测试验证(Postman / 接口文档)

若依集成了 Knife4j 接口文档(http://localhost:8080/doc.html),可直接测试,以下是核心接口测试用例

接口地址

请求方法

请求参数示例

预期结果

/system/user/list

GET

userName=admin(URL 参数)

返回分页用户列表,包含 admin

/system/user/1

GET

路径参数userId=1

返回 ID=1 的用户详情

/system/user

POST

JSON:{"userName":"test","nickName":"测试用户","sex":"1","phonenumber":"13800138000","status":"1"}

新增用户成功,返回code=200

/system/user

PUT

JSON:{"userId":100,"nickName":"测试用户修改","status":"1"}

修改用户成功,返回code=200

/system/user/100

DELETE

路径参数userIds=100

删除用户成功,返回code=200

测试注意事项:

启动前需配置数据库(MySQL):修改application-druid.yml中的数据库连接;

启动 Redis:确保 Redis 服务运行,否则框架启动失败;

登录认证:若依接口需携带 Token,先调用/login接口获取 Token,再在请求头添加Authorization: Bearer {Token}

权限校验:测试@PreAuthorize注解需用有对应权限的用户登录(如 admin 用户)。

总结

注解核心:若依基于 Spring Boot+MyBatis-Plus 封装了大量通用注解,重点掌握@TableName/@TableId(数据层)、@RestController/@PreAuthorize(控制层)、@Log/@Dict(若依自定义);

集成要点

Maven:继承若依父工程,自动引入核心依赖;

MyBatis-Plus:核心是@MapperScan+ 分页插件,Mapper 继承BaseMapper无需写基础 CRUD;

Redis:若依封装了RedisCache工具类,直接注入即可使用,重点配置序列化避免乱码;

开发规范:若依要求实体继承BaseEntity、Service 继承IService、Controller 继承BaseController,返回AjaxResult/TableDataInfo,遵循该规范可快速开发;

测试关键:需先完成数据库 / Redis 配置,通过 Knife4j 接口文档测试,注意 Token 和权限校验。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐