😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
Spring Boot 实现 AOP 动态热插拔功能并附DEMO源码
前言
本文对应代码下载地址: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>
❷ 创建自定义注解
packagecom.toher.project.dynamic;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceLoggable{}
❸ 定义配置管理类
定义一个配置管理类,主要作用是控制
AOP
开关
packagecom.toher.project.dynamic;importorg.springframework.stereotype.Component;@ComponentpublicclassAspectConfig{privateboolean loggingEnabled =true;publicbooleanisLoggingEnabled(){return loggingEnabled;}publicvoidsetLoggingEnabled(boolean loggingEnabled){this.loggingEnabled = loggingEnabled;}}
❹ 定义切面类
定义一个切面类,模拟业务耗时打印的功能
packagecom.toher.project.dynamic;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;@Aspect@ComponentpublicclassLoggingAspect{@AutowiredprivateAspectConfig aspectConfig;@Around("@annotation(com.toher.project.dynamic.Loggable)")publicObjectlogExecutionTime(ProceedingJoinPoint joinPoint)throwsThrowable{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
注解
packagecom.toher.project.dynamic;importorg.springframework.stereotype.Service;@ServicepublicclassUserService{@LoggablepublicvoidperformOperation(){// 业务逻辑System.out.println("执行相关操作...");}}
❻ 创建测试Controller
接下来编写一个
Controller
主要用于测试,开关
AOP
的日志时间打印功能
packagecom.toher.project.dynamic;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;@RestController@RequestMapping("/api/config")publicclassConfigController{@AutowiredprivateAspectConfig aspectConfig;@AutowiredprivateUserService userService;/**
* 测试AOP执行
* @return
*/@GetMapping("/logging")publicStringisLoggingEnabled(){
userService.performOperation();return"SUCCESS 当前loggingEnabled为 "+ aspectConfig.isLoggingEnabled();}/**
* 开关AOP日志耗时记录功能
* @param enabled
*/@PostMapping("/logging")publicStringsetLoggingEnabled(@RequestParamboolean 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
切面的动态热插拔功能。关键点在于通过配置管理类动态控制切面的启用状态,并在切面逻辑中根据状态决定是否执行切面代码。这样可以在不重启应用的情况下动态调整应用行为,提高系统的灵活性和可维护性。
如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!
版权归原作者 Micro麦可乐 所有, 如有侵权,请联系我们删除。