Spring AOP 入门教程:基础概念与实现

news2025/3/6 16:58:25

目录

第一章:AOP概念的引入

第二章:AOP相关的概念

1. AOP概述

2. AOP的优势

3. AOP的底层原理

 第三章:Spring的AOP技术 - 配置文件方式

1. AOP相关的术语

2. AOP配置文件方式入门

3. 切入点的表达式

4. AOP的通知类型

 第四章:Spring AOP技术 - 注解方式

1. 创建 Maven 工程,导入依赖

2. 编写接口并完成 IOC 配置

3. 编写切面类

4. 配置 XML 扫描注解

5. 配置 XML 自动代理

6. 编写 User 类

7. 通知类型注解

8. 测试类

9. 结果输出


Spring完整基础内容,请看这篇博客 :

Spring基础之——控制反转(IOC)、依赖注入(DI)与切面编程(AOP)概念详解(适合小白,初学者必看)_spring 控制反转、依赖注入、面向切面编程的代码呈现-CSDN博客文章浏览阅读1.1k次,点赞30次,收藏18次。本篇博客讲详细介绍Spring框架中的两个最核心且最基础的概念:控制反转(IOC)和面向切面编程(AOP)。以及如何通过IDEA来构建一个Spring项目,通过实战和理论结合的方式来让大家真的学会Spring这个最流行的Java框架。Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。它是为了解决企业应用开发的复杂性而创建的。_spring 控制反转、依赖注入、面向切面编程的代码呈现 https://blog.csdn.net/Future_yzx/article/details/143406347?sharetype=blogdetail&sharerId=143406347&sharerefer=PC&sharesource=Future_yzx&spm=1011.2480.3001.8118

前言

        在本篇博客中,我们将详细介绍 Spring AOP(面向切面编程) 的基本概念、应用及实现方法。AOP 是一种能够在不修改源代码的前提下对程序进行增强的技术,广泛应用于日志记录、性能统计、权限校验等领域。我们将从概念入手,逐步展示如何使用 Spring AOP 实现增强功能。

第一章:AOP概念的引入

首先我们来看一下用户登录的原理流程

我们先从一个简单的登录原理图开始思考,如果我们希望在登录功能中添加新的操作,例如权限校验,通常可以采取两种方式:

  1. 修改源代码:直接在原有代码中添加权限校验逻辑。
  2. 不修改源代码:通过 AOP 技术,在不改变现有代码的情况下进行增强。

Spring AOP 技术恰恰解决了第二种需求,它允许我们在现有业务逻辑上加入横向功能(如权限检查、日志记录等),而不需要直接修改源代码。


 第二章:AOP相关的概念

1. AOP概述

AOP(Aspect-Oriented Programming)是“面向切面编程”的缩写,它是对传统 OOP(面向对象编程) 的补充,通过在程序执行过程中动态地插入额外的功能来增强代码的可复用性与模块化。

Spring AOP 通过 代理 机制实现切面功能,通常在运行时为目标对象创建代理对象,从而实现方法增强。

2. AOP的优势

AOP 的核心优势在于它能够 解耦 业务逻辑和横向功能(如日志、事务、缓存等),从而提高代码的可维护性、重用性及开发效率。

AOP 的优势总结:

  • 减少重复代码:避免在每个业务方法中重复相同的代码。
  • 提高开发效率:通过统一处理横向功能,简化业务逻辑。
  • 方便维护:可以在不改变核心业务逻辑的前提下,修改或添加横向功能。

3. AOP的底层原理

Spring AOP 的实现基于 动态代理技术,主要有两种方式:

(1)JDK 动态代理通过接口创建代理类。

  1. 为接口创建代理类的字节码文件
  2. 使用ClassLoader将字节码文件加载到JVM
  3. 创建代理类实例对象,执行对象的目标方法

(2)CGLIB 代理通过继承目标类生成代理类,适用于没有接口的类。

  • 为类生成代理对象,被代理类有没有接口都无所谓,底层是生成子类,继承被代理类


 第三章:Spring的AOP技术 - 配置文件方式

1. AOP相关的术语

在 AOP 中,以下是一些关键术语:

  • Joinpoint(连接点):表示在程序中可以插入增强的地方,通常是方法。
  • Pointcut(切入点):定义了哪些连接点会被拦截。
  • Advice(通知):在切入点处执行的代码,分为不同类型(前置通知、后置通知、环绕通知等)。
  • Aspect(切面):切入点与通知的结合,表示一个完整的 AOP 增强。

2. AOP配置文件方式入门

首先,我们需要创建一个 Maven 项目并导入以下依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>aopalliance</groupId>
        <artifactId>aopalliance</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.3</version>
    </dependency>
</dependencies>
创建被增强的类(目标类)
// 被增强的类
public class User {
    // 连接点/切入点
    public void add() {
        System.out.println("add......");
    }

    public void update() {
        System.out.println("update......");
    }
}
创建切面类
public class UserProxy {
    // 增强/通知 ---》前置通知
    public void before() {
        System.out.println("before.............");
    }
}
在配置文件中完成aop的配置
<!-- 定义目标类和切面类 -->
<bean id="user" class="com.aopImpl.User"></bean>
<bean id="userProxy" class="com.aopImpl.UserProxy"></bean>

<!-- 配置切面 -->
<aop:config>
    <!-- 配置切面 = 切入点 + 通知组成 -->
    <aop:aspect ref="userProxy">
        <!-- 前置通知:UserServiceImpl的save方法执行前,会增强 -->
        <aop:before method="before" pointcut="execution(public void com.aopImpl.User.add())"/>
    </aop:aspect>
</aop:config>
测试类
public class DemoTest {
    @Test
    public void aopTest1() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) applicationContext.getBean("user");
        user.add();
    }
}

3. 切入点的表达式

再配置切入点的时候,需要定义表达式,具体展开如下:

① 切入点表达式的格式如下:

execution( [修饰符] [返回值类型] [类全路径] [方法名 ( [参数] )] )

注意:

  • 修饰符不是必须要出现的,可以省略不写。
  • 返回值类型是不能省略不写的,根据你的方法来编写返回值,可以使用 * 代替。

② 包名,类名,方法名,参数的规则如下:

例如:com.qcby.demo3.BookDaoImpl.save()

  • 首先包名,类名,方法名不能省略不写,可以使用 * 代替
  • 中间的包名可以使用 * 号代替
  • 类名也可以使用 * 号代替,例如有类似的写法: *DaoImpl
  • 方法也可以使用 * 号代替
  • 参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用 ..

比较通用的表达式:execution(* com.qcby.*.ServiceImpl.save(..))

举例2:对 com.qcby.demo3.BookDaoImpl 当中所有的方法进行增强

execution(* com.qcby.*.ServiceImpl.*(..))

举例3: com.qcby.demo3 包当中所有的方法进行增强

execution(* com.qcby.*.*.*(..))

代码实例:

<!--配置切面-->
<aop:config>
    <!--配置切面 = 切入点 + 通知组成-->
    <aop:aspect ref="userProxy">
        <!--切入点的表达式
        execution() 固定的写法
        public 是可以省略不写的
        方法的返回值 int String 通用的写法,可以编写 * 不能省略不写的
        包名+类名 不能省略不写的,编写 * com.*
        方法名称 add() 可以写 *
        参数列表 (..) 表示任意类型和个数的参数
        比较通用的表达式:execution(* com.*.User.add(..))-->
        <aop:before method="before" pointcut="execution(* com.*.User.add(..))"/>
    </aop:aspect>
</aop:config>

4. AOP的通知类型

Spring AOP 提供了多种通知类型,以下是常用的通知:

  • 前置通知(Before):在目标方法执行前进行增强。
  • 环绕通知(Around):在目标方法执行前后都可以增强,且需要手动调用目标方法。
  • 最终通知(After):无论目标方法执行成功还是失败,都会执行。
  • 后置通知(AfterReturning):目标方法执行成功后执行。
  • 异常通知(AfterThrowing):当目标方法抛出异常时执行。

接下来,我们一一展开并配置这些通知。

1. 前置通知(Before)

目标:目标方法执行前进行增强。
适用场景:例如,进行权限检查或日志记录时,在方法执行之前就进行操作。

代码示例

// 前置通知
public void before() {
    System.out.println("before.............");
}

XML 配置

<aop:before method="before" pointcut="execution(public void com.aopImpl.User.add())"/>

2. 环绕通知(Around)

目标:目标方法执行前后都可以进行增强。需要手动执行目标方法。
适用场景:例如,在方法执行前后做性能监控、事务管理等,或者在执行方法之前和之后加上额外的逻辑。

代码示例

// 环绕通知
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("before.............");
    // 执行被增强的方法
    proceedingJoinPoint.proceed(); 
    System.out.println("after.............");
}

XML 配置

<aop:around method="around" pointcut="execution(* com.*.User.add(..))"/>

3. 最终通知(After)

目标:目标方法执行成功或者失败时都进行增强。
适用场景:例如,无论方法执行是否成功,都需要执行清理操作(如关闭资源)。

代码示例

// 最终通知
public void after() {
    System.out.println("after.............");
}

XML 配置

<aop:after method="after" pointcut="execution(* com.*.User.add(..))"/>

4. 后置通知(AfterReturning)

目标:目标方法执行成功后进行增强。
适用场景:例如,在方法执行成功后进行记录日志,或者根据方法的返回值进行后续处理。

代码示例

// 后置通知
public void afterReturning() {
    System.out.println("afterReturning.............");
}

XML 配置

<aop:after-returning method="afterReturning" pointcut="execution(public void com.aopImpl.User.add())"/>

5. 异常通知(AfterThrowing)

目标:目标方法执行失败(抛出异常)时进行增强。
适用场景:例如,当目标方法出现异常时记录日志、发送报警等。

代码示例

// 异常通知
public void afterThrowing() {
    System.out.println("afterThrowing.............");
}

连接点/切入点
这里的目标方法 add() 在执行时故意抛出异常,用于触发异常通知。

// 连接点/切入点
public void add() {
    int a = 10 / 0;  // 故意抛出异常
    System.out.println("add......");
}

XML 配置

<aop:after-throwing method="afterThrowing" pointcut="execution(public void com.aopImpl.User.add())"/>

适用场景:

  • 前置通知:适用于方法执行前需要进行一些准备工作,如权限验证、输入检查等。
  • 环绕通知:适用于你需要控制方法执行的前后逻辑,能够在方法执行前后插入自定义行为。
  • 最终通知:适用于在方法执行后无论成功与否都需要执行的操作,如资源清理等。
  • 后置通知:适用于方法执行成功后进行的操作,例如记录成功日志或结果处理。
  • 异常通知:适用于方法执行时发生异常,需要对异常进行处理,如记录日志或发送告警通知。

 第四章:Spring AOP技术 - 注解方式

   下面用一个AOP注解方式入门程序来为大家演示:注解方式使用AOP。

1. 创建 Maven 工程,导入依赖

pom.xml 中添加必要的 Spring 相关依赖。具体依赖配置略。

2. 编写接口并完成 IOC 配置

(此部分略,假设已经完成)

3. 编写切面类

给切面类添加 @Aspect 注解,编写增强的方法,使用通知类型注解声明:

@Component
@Aspect  // 生成代理对象
public class UserProxy {

    // 增强/通知 ---》前置通知
    @Before(value = "execution(* com.*.User.add(..))")
    public void before() {
        System.out.println("before.............");
    }

    // 环绕通知
    @Around(value = "execution(* com.*.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("before.............");
        // 执行被增强的方法
        proceedingJoinPoint.proceed();
        System.out.println("after.............");
    }

    // 最终通知
    @After(value = "execution(* com.*.User.add(..))")
    public void after() {
        System.out.println("after.............");
    }

    // 异常通知
    @AfterThrowing(value = "execution(* com.*.User.add(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing.............");
    }

    // 后置通知
    @AfterReturning(value = "execution(* com.*.User.add(..))")
    public void afterReturning() {
        System.out.println("afterReturning.............");
    }
}

4. 配置 XML 扫描注解

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 开启注解扫描 -->
    <context:component-scan base-package="com.aopImpl"></context:component-scan>

</beans>

5. 配置 XML 自动代理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 开启注解扫描 -->
    <context:component-scan base-package="com.aopImpl"></context:component-scan>

    <!-- 开启 AspectJ 自动代理 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

6. 编写 User

@Component
public class User {
    // 连接点/切入点
    public void add() {
        System.out.println("add......");
    }
}

7. 通知类型注解

  • @Before: 前置通知
  • @AfterReturning: 后置通知
  • @Around: 环绕通知(目标对象方法默认不执行,需要手动调用)
  • @After: 最终通知
  • @AfterThrowing: 异常抛出通知
@Component
@Aspect  //生成代理对象
public class UserProxy {
    //增强/通知  ---》前置通知
    @Before(value = "execution(* com.*.User.add(..))")
    public void before(){
        System.out.println("before.............");

    }

    // 环绕通知
    @Around(value = "execution(* com.*.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("before.............");
        //  执行被增强的方法
        proceedingJoinPoint.proceed();
        System.out.println("after.............");
    }

    // 最终通知
    @After(value = "execution(* com.*.User.add(..))")
    public void after() {

        System.out.println("after.............");
    }

    //异常通知
    @AfterThrowing(value = "execution(* com.*.User.add(..))")
    public void afterThrowing() {

        System.out.println("afterThrowing.............");
    }

    //后置通知
    @AfterReturning(value = "execution(* com.*.User.add(..))")
    public void afterReturning() {

        System.out.println("afterReturning.............");
    }
}

8. 测试类

@Test
public void aopTest1() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    User user = (User) applicationContext.getBean("user");
    user.add();
}

9. 结果输出

user.add() 被调用时,输出将会是:

before.............
before.............
add......
after.............
after.............
afterReturning.............

        这样就完成了一个基本的 AOP 注解方式入门程序,涵盖了前置通知、后置通知、环绕通知、最终通知和异常通知的使用。

如果有更多问题或者需要进一步的讲解,随时告诉我! 


结语

        在本文中,我们介绍了 Spring AOP 的基本概念、配置文件方式和注解方式的实现。通过 Spring AOP,我们可以在不修改源代码的前提下灵活地为现有代码添加横向功能,提高代码的复用性和可维护性。希望本文能帮助你更好地理解和使用 Spring AOP!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2289732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Upscayl-官方开源免费图像AI增强软件

upscayl 链接&#xff1a;https://pan.xunlei.com/s/VOI0Szqe0fCwSSUSS8zRqKf7A1?pwdhefi#

SpringBoot Web开发(SpringMVC)

SpringBoot Web开发&#xff08;SpringMVC) MVC 核心组件和调用流程 Spring MVC与许多其他Web框架一样&#xff0c;是围绕前端控制器模式设计的&#xff0c;其中中央 Servlet DispatcherServlet 做整体请求处理调度&#xff01; . 除了DispatcherServletSpringMVC还会提供其他…

苍穹外卖第一天

角色分工 技术选型 pojo子模块 nginx反向代理 MD5密码加密

C# Winform enter键怎么去关联button

1.关联按钮上的Key事件按钮上的keypress&#xff0c;keydown&#xff0c;keyup事件随便一个即可private void textBox1_KeyDown(object sender, KeyEventArgs e){if (e.KeyCode Keys.Enter){this.textBox2.Focus();}}2.窗体上的事件private void textBox2_KeyPress(object sen…

LeGO LOAM坐标系问题的自我思考

LeGO LOAM坐标系问题的自我思考 IMU坐标系LeGO LOAM代码分析代码 对于IMU输出测量值的integration积分过程欧拉角的旋转矩阵VeloToStartIMU()函数TransformToStartIMU(PointType *p) IMU坐标系 在LeGO LOAM中IMU坐标系的形式采用前(x)-左(y)-上(z)的形式&#xff0c;IMU坐标系…

vim交换文件的作用

1.数据恢复&#xff1a;因为vim异常的退出&#xff0c;使用交换文件可以恢复之前的修改内容。 2.防止多人同时编辑&#xff1a;vim检测到交换文件的存在,会给出提示&#xff0c;以避免一个文件同时被多人编辑。 &#xff08;vim交换文件的工作原理&#xff1a;vim交换文件的工作…

PHP实现混合加密方式,提高加密的安全性(代码解密)

代码1&#xff1a; <?php // 需要加密的内容 $plaintext 授权服务器拒绝连接;// 1. AES加密部分 $aesKey openssl_random_pseudo_bytes(32); // 生成256位AES密钥 $iv openssl_random_pseudo_bytes(16); // 生成128位IV// AES加密&#xff08;CBC模式&#xff09…

五. Redis 配置内容(详细配置说明)

五. Redis 配置内容(详细配置说明) 文章目录 五. Redis 配置内容(详细配置说明)1. Units 单位配置2. INCLUDES (包含)配置3. NETWORK (网络)配置3.1 bind(配置访问内容)3.2 protected-mode (保护模式)3.3 port(端口)配置3.4 timeout(客户端超时时间)配置3.5 tcp-keepalive()配置…

(9) 上:学习与验证 linux 里的 epoll 对象里的 EPOLLIN、 EPOLLHUP 与 EPOLLRDHUP 的不同

&#xff08;1&#xff09;经过之前的学习。俺认为结论是这样的&#xff0c;因为三次握手到四次挥手&#xff0c;到 RST 报文&#xff0c;都是 tcp 连接上收到了报文&#xff0c;这都属于读事件。所以&#xff1a; EPOLLIN : 包含了读事件&#xff0c; FIN 报文的正常四次挥手、…

因果推断与机器学习—用机器学习解决因果推断问题

Judea Pearl 将当前备受瞩目的机器学习研究戏谑地称为“仅限于曲线拟合”,然而,曲线拟合的实现绝非易事。机器学习模型在图像识别、语音识别、自然语言处理、蛋白质分子结构预测以及搜索推荐等多个领域均展现出显著的应用效果。 在因果推断任务中,在完成因果效应识别之后,需…

2025全自动企业站群镜像管理系统 | 支持繁简转换拼音插入

2025全自动企业站群镜像管理系统 | 支持繁简转换拼音插入 在全球化的今天&#xff0c;企业面临着管理多站点的挑战&#xff0c;尤其是跨语言和地理位置的站点。为此&#xff0c;我们设计了一套基于PHP的全自动企业站群镜像管理系统&#xff0c;它不仅能够自动化站点的管理&…

基于阿里云百炼大模型Sensevoice-1的语音识别与文本保存工具开发

基于阿里云百炼大模型Sensevoice-1的语音识别与文本保存工具开发 摘要 随着人工智能技术的不断发展&#xff0c;语音识别在会议记录、语音笔记等场景中得到了广泛应用。本文介绍了一个基于Python和阿里云百炼大模型的语音识别与文本保存工具的开发过程。该工具能够高效地识别东…

GIS与相关专业软件汇总

闲来无事突然想整理一下看看 GIS及相关领域 究竟有多少软件或者工具包等。 我询问了几个AI工具并汇总了一个软件汇总&#xff0c;不搜不知道&#xff0c;一搜吓一跳&#xff0c;搜索出来了大量的软件&#xff0c;大部分软件或者工具包都没有见过&#xff0c;不知大家还有没有要…

飞书项目流程入门指导手册

飞书项目流程入门指导手册 参考资料准备工作新建空间国际化配置新建工作项字段管理新建字段对接标识授权角色 流程管理基础说明流程节点配置流程节点的布局配置页面上布局按钮布局配置 流程节点驳回流程图展示自动化字段修改 局限性 参考资料 飞书官方参考文档&#xff1a;飞书…

Android学习制作app(ESP8266-01S连接-简单制作)

一、理论 部分理论见arduino学习-CSDN博客和Android Studio安装配置_android studio gradle 配置-CSDN博客 以下直接上代码和效果视频&#xff0c;esp01S的收发硬件代码目前没有分享&#xff0c;但是可以通过另一个手机网络调试助手进行模拟。也可以直接根据我的代码进行改动…

如何使用SliverList组件

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了沉浸式状态栏相关的内容&#xff0c;本章回中将介绍SliverList组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在这里介绍的SliverList组件是一种列表类组件&#xff0c;类似我们之前介…

单细胞分析基础-第一节 数据质控、降维聚类

scRNA_pipeline\1.Seurat 生物技能树 可进官网查询 添加链接描述 分析流程 准备:R包安装 options("repos"="https://mirrors.ustc.edu.cn/CRAN/") if(!require("BiocManager")) install.packages("BiocManager",update = F,ask =…

HTML<hgroup>标签

例子&#xff1a; 使用hgroup元素标记标题和段落是相关的&#xff1a; <hgroup> <h2>Norway</h2> <p>The land with the midnight sun.</p> </hgroup> 定义和用法&#xff1a; 标签<hgroup>用于包围标题和一个或多个<p&g…

【已解决】黑马点评项目Redis版本替换过程的数据迁移

黑马点评项目Redis版本替换过程的数据迁移 【哭哭哭】附近商户中需要用到的GEO功能只在Redis 6.2以上版本生效 如果用的是老版本&#xff0c;美食/KTV的主页能正常返回&#xff0c;但无法显示内容 上次好不容易升到了5.0以上版本&#xff0c;现在又用不了了 Redis 6.2的windo…

mybatis辅助配置

驼峰映射 sql里面定义字段通常是使用下划线定义 比如dept_id 而我们的后端属性通常就是驼峰命名 deptId 所以这两匹配进行自动赋值就比较麻烦 可以使用 select dept_id as deptId 来解决&#xff08;起别名&#xff09; 也可以用mybatis的辅助配置解决 第三种就是推荐的在spr…