深入理解Spring AOP的工作流程

文章目录

    • 引言
    • 什么是AOP?
    • Spring AOP的工作原理
      • 1. JDK动态代理
      • 2. CGLIB代理
    • Spring AOP的注解方式
      • @Aspect注解
      • @EnableAspectJAutoProxy注解
    • Spring AOP的工作流程
    • 拓展应用
      • 1. 自定义注解
      • 2. 异常处理
      • 3. 切面优先级
    • 结论

在这里插入图片描述

🎉深入理解Spring AOP的工作流程


  • ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹
  • ✨博客主页:IT·陈寒的博客
  • 🎈该系列文章专栏:架构设计
  • 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习
  • 🍹文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • 📜 欢迎大家关注! ❤️

引言

在现代的软件开发中,面向切面编程(AOP)是一种重要的编程范式,用于解耦业务逻辑和横切关注点(cross-cutting concerns)。Spring框架提供了强大而灵活的AOP支持,通过代理机制实现横切关注点的注入。本文将深入探讨Spring AOP的工作流程,帮助读者更好地理解其原理和应用。

什么是AOP?

AOP是一种编程思想,通过在程序中间插入横切关注点,将系统划分为核心业务逻辑和横切关注点两部分。横切关注点包括日志记录、事务管理、安全控制等与核心业务逻辑无关但又必须在程序中执行的功能。AOP通过将这些横切关注点与核心业务逻辑分离,提高了代码的模块化和可维护性。

Spring AOP通过代理机制实现横切关注点的注入,其中代理对象负责执行横切逻辑。在Spring AOP中,常见的横切关注点包括日志记录、性能监控、事务管理等。

Spring AOP的工作原理

Spring AOP基于代理模式,主要通过两种方式实现:

  1. JDK动态代理: 基于接口的代理机制,使用java.lang.reflect.Proxy类生成代理对象。

  2. CGLIB代理: 基于类的代理机制,使用CGLIB库生成代理对象。

1. JDK动态代理

JDK动态代理要求目标类实现一个或多个接口,代理对象实现这些接口并委托给目标对象。以下是一个简单的例子:

public interface UserService {
    void addUser(String username, String password);
}

public class UserServiceImpl implements UserService {
    @Override
    public void addUser(String username, String password) {
        // 实际业务逻辑
        System.out.println("User added: " + username);
    }
}

public class LogAspect implements InvocationHandler {
    private Object target;

    public LogAspect(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Log: Method " + method.getName() + " is invoked");
        Object result = method.invoke(target, args);
        return result;
    }
}

// 使用代理
public class Main {
    public static void main(String[] args) {
        UserService target = new UserServiceImpl();
        InvocationHandler handler = new LogAspect(target);
        UserService proxy = (UserService) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                handler
        );
        proxy.addUser("John", "123456");
    }
}

2. CGLIB代理

CGLIB代理不要求目标类实现接口,代理对象继承目标对象。以下是一个简单的例子:

public class UserService {
    public void addUser(String username, String password) {
        // 实际业务逻辑
        System.out.println("User added: " + username);
    }
}

public class LogAspect implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Log: Method " + method.getName() + " is invoked");
        Object result = proxy.invokeSuper(obj, args);
        return result;
    }
}

// 使用代理
public class Main {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class);
        enhancer.setCallback(new LogAspect());

        UserService proxy = (UserService) enhancer.create();
        proxy.addUser("John", "123456");
    }
}

Spring AOP的注解方式

除了基于XML的配置方式,Spring AOP还支持使用注解的方式配置切面。

@Aspect注解

在使用注解方式配置AOP时,首先需要使用@Aspect注解声明一个切面类。该类包含了多个切点和通知,用于定义横切逻辑。

@Aspect
@Component
public class LogAspect {

    @Pointcut("execution(* com.example.service.*.*(..))")
    public void pointcut() {}

    @Before("pointcut()")
    public void beforeAdvice(JoinPoint joinPoint) {
        System.out.println("Log: Before " + joinPoint.getSignature().

getName());
    }

    @After("pointcut()")
    public void afterAdvice(JoinPoint joinPoint) {
        System.out.println("Log: After " + joinPoint.getSignature().getName());
    }
}

上述例子中,@Pointcut注解定义了一个切点,表示匹配com.example.service包下所有类的所有方法。@Before@After注解分别表示前置通知和后置通知。

@EnableAspectJAutoProxy注解

在Spring Boot中,还需要在配置类上使用@EnableAspectJAutoProxy注解开启自动代理功能。该注解告诉Spring Boot启用AspectJ自动代理。

@SpringBootApplication
@EnableAspectJAutoProxy
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

Spring AOP的工作流程

Spring AOP的工作流程可以概括为以下几个步骤:

  1. 定义切面: 创建一个Java类,并在类上使用@Aspect注解声明为切面类。在切面类中定义切点和通知。

  2. 配置通知: 使用@Before@After等注解配置通知,定义横切逻辑。

  3. 激活切面: 在配置类上使用@EnableAspectJAutoProxy注解激活切面。

  4. 容器初始化: Spring容器启动时,会扫描并解析所有标有@Aspect注解的类。

  5. 生成代理对象: 对于被代理的目标对象,Spring会根据切面定义生成代理对象。代理对象包含了横切逻辑。

  6. 执行横切逻辑: 在目标方法执行前、后或异常时,执行横切逻辑。

拓展应用

Spring AOP的应用远不止上述简单例子所示,还可以结合更复杂的切面和通知,实现更丰富的横切逻辑。以下是一些拓展应用的示例:

1. 自定义注解

可以使用自定义注解来标记切点,让代码更具可读性。例如,定义一个@Log注解,标记需要记录日志的方法。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";
}

然后,在切面类中使用@Around注解拦截被@Log注解标记的方法。

@Aspect
@Component
public class LogAspect {

    @Around("@annotation(com.example.annotation.Log)")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Log: Method " + joinPoint.getSignature().getName() + " is invoked");
        Object result = joinPoint.proceed();
        return result;
    }
}

2. 异常处理

通过@AfterThrowing注解可以实现异常处理逻辑,记录异常信息或进行其他处理。

@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")
public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {
    System.out.println("Exception: " + ex.getMessage());
}

3. 切面优先级

通过@Order注解可以指定切面的优先级,数字越小,优先级越高。

@Aspect
@Component
@Order(1)
public class LogAspect {
    // ...
}

在这里插入图片描述

结论

Spring AOP是Spring框架中一个重要的组件,通过代理机制实现横切关注点的注入。本文深入介绍了Spring AOP的工作原理,包括基于JDK动态代理和CGLIB代理的实现方式,以及使用注解配置AOP的方法。通过理解Spring AOP的工作流程,我们能更好地应用和拓展AOP,提高代码的模块化和可维护性。希望本文能够帮助读者更深入地理解和应用Spring AOP。


🧸结尾 ❤️ 感谢您的支持和鼓励! 😊🙏
📜您可能感兴趣的内容:

  • 【Java面试技巧】Java面试八股文 - 掌握面试必备知识(目录篇)
  • 【Java学习路线】2023年完整版Java学习路线图
  • 【AIGC人工智能】Chat GPT是什么,初学者怎么使用Chat GPT,需要注意些什么
  • 【Java实战项目】SpringBoot+SSM实战:打造高效便捷的企业级Java外卖订购系统
  • 【数据结构学习】从零起步:学习数据结构的完整路径

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

相机和滤镜应用程序Nevercenter CameraBag Photo mac软件特点说明

Nevercenter CameraBag Photo mac是一款相机和滤镜应用程序,它提供了一系列先进的滤镜、调整工具和预设,可以帮助用户快速地优化和编辑照片。 Nevercenter CameraBag Photo mac软件特点 1. 滤镜:Nevercenter CameraBag Photo提供了超过200种…

Harmony Ble蓝牙App(二)连接与发现服务

Ble蓝牙App(二)连接与发现服务 前言正文一、BlePeripheral回调二、连接和断连三、连接状态回调四、发现服务五、服务提供者六、显示服务七、源码 前言 在上一篇中我们进行扫描设备的处理,本文中进行连接和发现服务的数据处理,运行…

多数据库使用django-apscheduler时,migrate后并不能生成django_apscheduler_djangojob表的问题

先说一下django-apscheduler定时器的使用过程: django-apscheduler基本使用 1.安装django-apscheduler代码如下(示例): pip install django-apscheduler 2.配置settings.py的INSTALLED_APPS代码如下(示例&#xff09…

性能测试必备知识-使用MySQL存储过程构造大量数据:实例解析

在软件开发过程中,测试是一个不可或缺的环节。通过测试,我们可以发现并修复软件中的各种问题,提高软件的质量和稳定性。然而,手动编写大量的测试用例是一项耗时且容易出错的任务。为了解决这个问题,我们需要学会使用批…

ES ElasticSearch安装、可视化工具kibana安装

1、安装ES docker run -d --name es9200 -e "discovery.typesingle-node" -p 9200:9200 elasticsearch:7.12.1访问测试: http://域名:9200/ 2、安装kibana对es进行可视化操作 执行命令 docker run -d --name kibana5601 -p 5601:5601 kibana:7.1.12.修…

在线工具收集

在线工具收集 1、在线P图 https://www.photopea.com/ 一款类似于PS的在线抠图软件 ①去除图片中的文字,并填充背景色 第一步:使用矩形选中要清除的文字 第二步:点击编辑选择填充 第三步:选择内容识别,保留透明区域…

[MySQL] MySQL 表的增删查改

本篇文章对mysql表的增删查改进行了详细的举例说明解释。对表的增删查改简称CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)。其中重点是对查询select语句进行了详细解释,并且通过多个实际例子来帮助…

物联网AI MicroPython学习之语法 I2S音频总线接口

学物联网,来万物简单IoT物联网!! I2S 介绍 模块功能: I2S音频总线驱动模块 接口说明 I2S - 构建I2S对象 函数原型:I2S(id, sck, ws, sd, mode, bits, format, rate, ibuf)参数说明: 参数类型必选参数&#xff1f…

《洛谷深入浅出基础篇》P4017最大食物链————拓扑排序

上链接:P4017 最大食物链计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P4017 上题干: 题目背景 你知道食物链吗?Delia 生物考试的时候,数食物链条数的题目全都错了,因为她总是…

力扣:178. 分数排名(Python3)

题目: 表: Scores ---------------------- | Column Name | Type | ---------------------- | id | int | | score | decimal | ---------------------- 在 SQL 中,id 是该表的主键。 该表的每一行都包含了一场比赛的分数。Score …

电子学会C/C++编程等级考试2023年03月(一级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:字符长方形 给定一个字符,用它构造一个长为4个字符,宽为3个字符的长方形,可以参考样例输出。 时间限制:1000 内存限制:65536输入 输入只有一行, 包含一个字符。输出 该字符构成的长方形,长4个字符,宽3个字符。样例输入…

虚拟机VMware上安装Ubuntu系统(详细图文教程)

关于虚拟机VMware的安装教程,学者看我另外一篇博客:VMware详细安装教程 目录 一、Ubuntn系统准备二、VMware上安装Ubuntn系统2.1 答疑 三、导入Ubuntu系统四、总结 一、Ubuntn系统准备 先下载好Ubuntn系统,这里我提供一个,下载链…

一、用户管理

一、后端数据库初始化 1.1 因为版本问题,始终报错,按照报错信息去查询解决方案,无法解决 灵机一动: 网址: Spring Boot 3.0 升级 实战踩坑记录 - 掘金 (juejin.cn) 1.2 个人配置【运行成功…

机器学习实战-第5章 Logistic回归

Logistic 回归 概述 Logistic 回归 或者叫逻辑回归 虽然名字有回归,但是它是用来做分类的。其主要思想是: 根据现有数据对分类边界线(Decision Boundary)建立回归公式,以此进行分类。 须知概念 Sigmoid 函数 回归 概念 假设现在有一些数据点,我们用一条直线对这些点进行…

KT404A远程更换语音芯片方案支持OTA 4G 蓝牙 wifi 物联网

目录 一、简介 2.1 芯片的硬件 2.2 测试的方法 一、简介 KT404A远程更换语音芯片方案支持OTA 4G 蓝牙 wifi 物联网 在线下载的mp3语音芯片ic,通过KT404A的uart直接更换内部的语音文件,从而实现动态的更新语音内容 物联网大潮的来袭。随着智能家居、…

OpenStack云计算平台-计算服务

目录 一、计算服务概览 二、安装并配置控制节点 1、先决条件 2、安全并配置组件 3、完成安装 三、安装和配置计算节点 1、安全并配置组件 2、完成安装 四、验证操作 一、计算服务概览 使用OpenStack计算服务来托管和管理云计算系统。OpenStack计算服务是基础设施即服务…

EI论文故障识别程序:DBN深度置信/信念网络的故障识别Matlab程序,数据由Excel导入,直接运行!

​适用平台:Matlab2021b版及以上 本程序参考中文EI期刊《基于变分模态分解和改进灰狼算法优化深度置信网络的自动转换开关故障识别》中的深度置信网络(Deep Belief Network,DBN)部分进行故障识别,程序注释清晰&#x…

深度学习卷积神经网络的花卉识别 计算机竞赛

文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基…

数十万QPS,百度热点大事件搜索的稳定性保障实践

作者 | 文燕 导读 在互联网行业里,业务迭代很快,系统变更频繁,尤其长青业务随着时间会积累越来越多历史包袱。阿拉丁作为百度搜索垂直化的产品,业务历经多年更迭,历史包袱很多,在应对大事件比如高考、东京奥…

【PyQt】QPixmap与numpy.array互转

这里给出QPixmap→numpy.ndarray的两条转换(一个是使用PIL.Image而另一个不用), 以及numpy.ndarray→QPixmap两条转换(同样也是用不用PIL.Image的区别)。 代码运行结果: from PyQt5.QtCore import QPoint,QRect,Qt from PyQt5.QtWidgets import QLabel …
最新文章