Spring Boot 实现 AOP 动态热插拔功能并附DEMO源码

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

Spring Boot 实现 AOP 动态热插拔功能并附DEMO源码

  • 前言
  • 应用场景
  • 开始实战
    • ❶ 初始化项目
    • ❷ 创建自定义注解
    • ❸ 定义配置管理类
    • ❹ 定义切面类
    • ❺ 使用切面
    • ❻ 创建测试Controller
    • ❼ 测试效果
  • 总结

前言

本文对应代码下载地址:https://download.csdn.net/download/lhmyy521125/89504659 无需积分!

AOP(面向切面编程)是一种强大的编程范式,可以用于日志记录性能监控安全检查等跨越多个模块的通用功能。实现 AOP 的动态热插拔可以让我们在不重启应用的情况下启用禁用特定的切面,提高系统的灵活性和可维护性。

我们以一个例子来说明一下为什么需要 AOP 动态热插拔:我们系统有一个 AOP 切面,它负责了记录用户传递参数、执行时间、接口返回结果,默认是不开启的,现在因为某些原因需要检测某个接口参数接收情况 + 耗时 + 返回数据,那么我们就需要在不重启应用的情况下,动态开启关闭AOP切面来达到我们想要的效果。

本文就跟着博主一起来学习在 Spring Boot 中实现 AOP 的动态热插拔功能。


应用场景

动态热插拔功能适用的场景有很多,这里简单举例几个场景:

  • 1、调试和排查问题:在生产环境中临时启用日志或性能监控切面,以便快速定位问题。例如,当发现某个服务的响应时间突然增加时,可以动态启用性能监控切面,记录每个方法的执行时间,从而找出性能瓶颈。

  • 2、动态功能开关:根据业务需求动态启用或禁用某些功能,如限流鉴权等。例如,在高流量的促销活动期间,可以临时启用限流切面,防止服务器过载。在活动结束后,可以动态关闭限流切面,恢复正常流量处理。

  • 3、性能优化:在高负载时关闭一些耗性能的切面以提高系统吞吐量。例如,在系统的非高峰期,可以启用详细的日志记录和审计切面,以便收集用户行为数据和系统操作日志。而在系统高峰期,可以临时关闭这些切面,以减少日志记录带来的性能开销。

  • 4、安全审计:在面对安全审计或合规检查时,可以临时启用安全检查切面,记录所有的安全相关操作。例如,在接到安全审计通知时,可以动态启用安全检查切面,记录所有用户的登录和数据访问行为,确保审计数据的完整性。

  • 5、实验和AB测试:在进行新功能的实验和AB测试时,可以动态控制某些功能的启用。例如,在推出新功能时,可以动态启用或禁用相关切面,控制新功能的实验组和对照组,从而评估新功能的效果和性能影响。


开始实战

废话了那么多,我们还是以代码样例来进行演示讲解

❶ 初始化项目

首先,创建一个新的 Spring Boot 项目,在在 pom.xml 文件中添加相关依赖

<dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Starter AOP --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
</dependencies>

❷ 创建自定义注解

package com.toher.project.dynamic;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {
}

❸ 定义配置管理类

定义一个配置管理类,主要作用是控制AOP开关

package com.toher.project.dynamic;import org.springframework.stereotype.Component;@Component
public class AspectConfig {private boolean loggingEnabled = true;public boolean isLoggingEnabled() {return loggingEnabled;}public void setLoggingEnabled(boolean loggingEnabled) {this.loggingEnabled = loggingEnabled;}
}

❹ 定义切面类

定义一个切面类,模拟业务耗时打印的功能

package com.toher.project.dynamic;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {@Autowiredprivate AspectConfig aspectConfig;@Around("@annotation(com.toher.project.dynamic.Loggable)")public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {if (!aspectConfig.isLoggingEnabled()) {return joinPoint.proceed();}long start = System.currentTimeMillis();Object proceed = joinPoint.proceed();long executionTime = System.currentTimeMillis() - start;System.out.println(joinPoint.getSignature() + " 方法执行时间 " + executionTime + "ms");return proceed;}
}

❺ 使用切面

编写一个 service,在需要记录日志的方法上使用 @Loggable 注解

package com.toher.project.dynamic;import org.springframework.stereotype.Service;@Service
public class UserService {@Loggablepublic void performOperation() {// 业务逻辑System.out.println("执行相关操作...");}
}

❻ 创建测试Controller

接下来编写一个Controller主要用于测试,开关AOP的日志时间打印功能

package com.toher.project.dynamic;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/config")
public class ConfigController {@Autowiredprivate AspectConfig aspectConfig;@Autowiredprivate UserService userService;/*** 测试AOP执行* @return*/@GetMapping("/logging")public String isLoggingEnabled() {userService.performOperation();return "SUCCESS 当前loggingEnabled为 " + aspectConfig.isLoggingEnabled();}/*** 开关AOP日志耗时记录功能* @param enabled*/@PostMapping("/logging")public String setLoggingEnabled(@RequestParam boolean enabled) {aspectConfig.setLoggingEnabled(enabled);return "更新成功当前loggingEnabled为 " + aspectConfig.isLoggingEnabled();}
}

❼ 测试效果

运行Spring Boot项目,博主使用 Apifox 访问 http://localhost:端口号/api/config/logging
在这里插入图片描述
观察控制台输出

在这里插入图片描述

修改我们的loggingEnabled
在这里插入图片描述
修改后再次观察控制台,发现当 loggingEnabled = false 本次并没有执行耗时打印功能

在这里插入图片描述


总结

通过上述简单的DEMO相信大家已经初步了解了实现 AOP 动态热插拔功能,DEMO代码仅仅为了演示,实际上我们项目中还可以考虑以下几点:

  • 配置持久化:可以将配置状态存储在数据库或其他持久化存储中,确保应用重启后配置不丢失。
  • 丰富的控制接口:根据实际需求,可以扩展 REST 接口,增加对多个切面和更多配置项的管理。
  • 细粒度控制:在切面逻辑中可以根据更多条件(如请求参数、用户角色等)进行更细粒度的控制。

本篇文章我们实现了 Spring Boot 项目中 AOP 切面的动态热插拔功能。关键点在于通过配置管理类动态控制切面的启用状态,并在切面逻辑中根据状态决定是否执行切面代码。这样可以在不重启应用的情况下动态调整应用行为,提高系统的灵活性和可维护性。

如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!


在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【解锁未来:深入了解机器学习的核心技术与实际应用】

解锁未来&#xff1a;深入了解机器学习的核心技术与实际应用 &#x1f48e;1.引言&#x1f48e;1.1 什么是机器学习&#xff1f; &#x1f48e;2 机器学习的分类&#x1f48e;3 常用的机器学习算法&#x1f48e;3.1 线性回归&#xff08;Linear Regression&#xff09;&#x1…

基础算法模板

1. 相向双指针 class Solution { // 两数之和public int[] twoSum(int[] numbers, int target) {int left 0; // 第一步初始化开头和结尾两个指针int right numbers.length - 1;while (true) { // 之后一直while循环 int s numbers[left] numbers[right]; //计算左右两个…

Flutter循序渐进==>数据结构(列表、映射和集合)和错误处理

导言 填鸭似的教育确实不行&#xff0c;我高中时学过集合&#xff0c;不知道有什么用&#xff0c;毫无兴趣&#xff0c;等到我学了一门编程语言后&#xff0c;才发现集合真的很有用&#xff1b;可以去重&#xff0c;可以看你有我没有的&#xff0c;可以看我有你没有的&#xf…

mybatis实现多表查询

mybatis高级查询【掌握】 1、准备工作 【1】包结构 创建java项目&#xff0c;导入jar包和log4j日志配置文件以及连接数据库的配置文件&#xff1b; 【2】导入SQL脚本 运行资料中的sql脚本&#xff1a;mybatis.sql 【3】创建实体来包&#xff0c;导入资料中的pojo 【4】User…

Swift宏的实现

上篇介绍了Swift宏的定义与生声明&#xff0c;本篇主要看看是Swift宏的具体实现。结合Swift中Codable协议&#xff0c;封装一个工具让类或者结构体自动实现Codable协议&#xff0c;并且添加一些协议中没有的功能。 关于Codable协议 Codable很好&#xff0c;但是有一些缺陷&…

141个图表,完美展示数据分类别关系!

本文介绍使用Python工具seaborn详细实现分类关系图表&#xff0c;包含8类图141个代码模版。 分类关系图表用于展示数字变量和一个或多个分类变量之间的关系&#xff0c;可以进一步分为&#xff1a;箱形图&#xff08;box plot&#xff09;、增强箱形图&#xff08;enhanced bo…

DP:子数组问题

文章目录 引言子数组问题介绍动态规划的基本概念具体问题的解决方法动态规划解法&#xff1a;关于子数组问题的几个题1.最大子数组和2.环形子数组的最大和3.乘积最大子数组4.乘积为正数的最长子数组长度5.等差数列划分 总结 引言 介绍动态规划&#xff08;DP&#xff09;在解决…

Deep-LIBRA:一种用于可靠量化乳腺密度的人工智能方法,并在乳腺癌风险评估中进行了独立验证| 文献速递-深度学习自动化疾病检查

Title 题目 Deep-LIBRA: An artificial-intelligence method for robust quantification of breast density with independent validation in breast cancer risk assessment Deep-LIBRA&#xff1a;一种用于可靠量化乳腺密度的人工智能方法&#xff0c;并在乳腺癌风险评估中…

【内网渗透】从0到1的内网渗透基础概念笔记

目录 域 域的介绍 单域 父域和子域 域树 域森林 域名服务器 活动目录 活动目录介绍 域内权限 组 域本地组 全局组 通用组 总结 示例 A-G-DL-P策略 重要的域本地组 重要的全局组、通用组 安全域划分 域 域的介绍 Windows域是计算机网络的一种形式&#xf…

【机器学习】FFmpeg+Whisper:二阶段法视频理解(video-to-text)大模型实战

目录 一、引言 二、FFmpeg工具介绍 2.1 什么是FFmpeg 2.2 FFmpeg核心原理 2.3 FFmpeg使用示例 三、FFmpegWhisper二阶段法视频理解实战 3.1 FFmpeg安装 3.2 Whisper模型下载 3.3 FFmpeg抽取视频的音频 3.3.1 方案一&#xff1a;命令行方式使用ffmpeg 3.3.2 方案二&a…

[论文精读]Variational Graph Auto-Encoders

论文网址&#xff1a;[1611.07308] Variational Graph Auto-Encoders (arxiv.org) 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎…

Android 界面库 (二) 之 Data binding 详细介绍

1. 简介 回顾我们在前面文章《Android 界面库 (一) 之 View binding 简单使用》中学习的 View Binding&#xff0c;它旨在简化 View 与代码之间的绑定过程。它会在编译时期为每个 XML 布局文件生成相应的绑定类(Binding class)&#xff0c;该类里包含了布局文件每个有 ID 的 Vi…

基于SpringBoot扶农助农政策管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

利用 Docker 简化 Nacos 部署:快速搭建 Nacos 服务

利用 Docker 简化 Nacos 部署&#xff1a;快速搭建 Nacos 服务 引言 在微服务架构中&#xff0c;服务注册与发现是确保服务间通信顺畅的关键组件。Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;作为阿里巴巴开源的一个服务发现和配置管理平台&…

【单片机毕业设计选题24039】-基于单片机的太阳能储能智能恒温外卖柜设计

系统功能: 以单片机为控制核心&#xff0c;综合运用传感器、物联网、太阳能等技术&#xff0c;设计一种基于单片机为控制核心的智能恒温外卖柜。它由恒温系统、无线模块、智能提醒系统、供电系统等组成&#xff0c;通过太阳能电池板独立供电&#xff0c;利用太阳能储能元件驱动…

Linux网络编程:套接字编程

1.Socket套接字编程 1.1.什么是socket套接字编程 Socket套接字编程 是一种基于网络层和传输层网络通信方式&#xff0c;它允许不同主机上的应用程序之间进行双向的数据通信。Socket是网络通信的基本构件&#xff0c;它提供了不同主机间的进程间通信端点的抽象。一个Socket就是…

免费开源的后端API服务-supabase安装和使用-简直是前端学习者福音

文章目录 它是什么安装和部署关于安装关于部署1、注册用户2、创建组织3、创建项目 创建数据库表&#xff08;填充内容&#xff09;填充数据库表 使用postman联调API 它是什么 一个开源免费的后端框架&#xff0c;firebase的替代品。可以简单理解类似于headless cms&#xff0c…

浅谈定时器之泊松随机定时器

浅谈定时器之泊松随机定时器 “泊松随机定时器”(Poisson Random Timer)&#xff0c;它允许你基于泊松分布来随机化请求之间的延迟时间&#xff0c;这对于模拟具有随机到达率的事件特别有用&#xff0c;如用户访问网站或服务的请求。 泊松分布简介 泊松分布是一种统计与概率…

HarmonyOS开发探索:父子组件手势绑定问题处理

场景一&#xff1a;父子组件同时绑定手势的冲突处理 效果图 方案 在默认情况下&#xff0c;手势事件为非冒泡事件&#xff0c;当父子组件绑定相同的手势时&#xff0c;父子组件绑定的手势事件会发生竞争&#xff0c;最多只有一个组件的手势事件能够获得响应&#xff0c;默认子…

有哪些方法可以恢复ios15不小心删除的照片?

ios15怎么恢复删除的照片&#xff1f;在手机相册里意外删除了重要的照片&#xff1f;别担心&#xff01;本文将为你介绍如何在iOS 15系统中恢复已删除的照片。无需专业知识&#xff0c;只需要按照以下步骤操作&#xff0c;你就能轻松找回宝贵的回忆。 一、从iCloud云端恢复删除…