@RefreshScope热更新原理

本文涉及的产品
RDS AI 助手,专业版
PolarClaw,2核4GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: @RefreshScope通过组合注解实现配置热更新,核心在于@Scope("refresh")。其利用代理模式与缓存机制,将Bean纳入自定义刷新作用域,配置变更时清空缓存,触发Spring重新创建Bean实例,从而动态加载最新配置,实现毫秒级更新。

在前面学习Nacos的章节中,为了实现配置的热更新我们采取了两种方式,其一就是借助于注解:@RefreshScope,那么这个注解是如何做到标识即生效的?我们尝试一起分析一下。
1.了解@RefreshScope本身
点击进去此注解,可以发现其本质也是一个组合注解,如下
对于Spring注解有过研究的读者,对于这几个元注解一定不陌生,简短的篇幅了解一下:
@Target({ ElementType.TYPE, ElementType.METHOD })
目标的作用范围
ElementType.TYPE:能修饰类、接口或枚举类型
ElementType.FIELD:能修饰成员变量
ElementType.METHOD:能修饰方法
ElementType.PARAMETER:能修饰参数
ElementType.CONSTRUCTOR:能修饰构造器
ElementType.LOCAL_VARIABLE:能修饰局部变量
ElementType.ANNOTATION_TYPE:能修饰注解
ElementType.PACKAGE:能修饰包
@Retention(RetentionPolicy.RUNTIME)
保留的生命周期
SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;即保留在.java文件中
CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;即保留在.class文件中
RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后仍然存在;即保留在内存中的字节码文件中,一旦jvm加载就会更新,生命周期最长
@Scope("refresh")
实现配置、实例热加载的关键核心,默认了ScopedProxyMode.TARGET_CLASS; 属性,此属性的功能就是在创建一个代理,在每次调用的时候都用它来调用GenericScope get 方法来获取对象。集成了Spring框架之后,实际就是调用Spring的装配机制重新装配属性。
所以截止目前我们可以了解到:@RefreshScope注解本身是一个组合注解,其实现配置热更新的关键是依赖@Scope("refresh")。我们进一步来看看@RefreshScope到底做了什么?
2.@RefreshScope做了什么
@RefreshScope主要就是基于@Scope注解的作用域代理的基础上进行扩展实现的,加了@RefreshScope注解的类,在被Bean工厂创建后会加入自己的refresh scope 这个Bean缓存中,后续会优先从Bean缓存中获取,当配置中心发生了变更,会把变更的配置更新到spring容器的Environment中,并且同时bean缓存就会被清空,从而就会从bean工厂中创建bean实例了,而这次创建bean实例的时候就会继续经历这个bean的生命周期,使得@Value属性值能够从Environment中获取到最新的属性值,这样整个过程就达到了动态刷新配置的效果。
所以截止目前我们可以了解到下述大致流程:
Spring获取标注@RefreshScope的Bean流程
配置更新清空缓存​
开始
获取标注@Scope的Bean

refresh scope缓存是否有

调用Spring创建过程全新创建

返回并结束

refresh scope缓存bean

Nacos配置更新
清空​
加入新创建bean​
清空的目的是为了重新创建,获取全新的Bean从而达到动态更新,这个过程非常快(ms级)

3.@RefreshScope怎么做到的
基于上面我们知道,@Scope基于缓存失效,实现配置的热更新,我们继续看看它是如何做到的:
4.总结
对于@RefreshScope注解实现配置热更新的流程,实际是借助于缓存失效+Spring重新创建配置Bean解决,知道这个思路之后,读者们可以借助本章节2,或3做流程性、原理性了解。

相关文章
|
3月前
|
算法 NoSQL Java
拒绝服务雪崩!4种经典限流算法图文详解(附Java实战代码)
限流是保护系统的“保险丝”,防止突发流量导致服务雪崩。常见算法有:固定窗口(简单但有突刺)、滑动窗口(精准平滑)、漏桶(恒定处理速率)和令牌桶(允许突发,最常用)。单机限流可用计数器或Guava,分布式场景则依赖Redis实现全局控制。
849 9
|
9月前
|
SQL XML 缓存
控制接口RT暴降80%!CompletableFuture异步编排实战代码模板
Springboot 控制接口RT暴降80%!CompletableFuture异步编排实战代码模板
|
前端开发 Java 微服务
SpringCloud微服务之间传输文件
SpringCloud微服务之间传输文件
640 1
|
SQL JSON Java
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
本文为Spring Boot增删改查接口的小白入门教程,介绍了项目的构建、配置YML文件、代码编写(包括实体类、Mapper接口、Mapper.xml、Service和Controller)以及使用Postman进行接口测试的方法。同时提供了SQL代码和完整代码的下载链接。
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
|
消息中间件 Java 数据库
新版 Seata 集成 RocketMQ事务消息,越来越 牛X 了!阿里的 Seata , yyds !
这里 借助 Seata 集成 RocketMQ 事务消息的 新功能,介绍一下一个新遇到的面试题:如果如何实现 **强弱一致性 结合**的分布式事务?
新版 Seata 集成 RocketMQ事务消息,越来越 牛X 了!阿里的 Seata , yyds !
|
Java 数据库连接 数据库
sqlLite 如何使用数据库连接池
这篇文章介绍了如何在SQLite数据库操作中使用HikariCP连接池以减少频繁建立和释放数据库连接的资源消耗,包括在Maven项目中添加依赖、配置HikariDataSource对象以及实现数据库连接池的具体代码示例。
|
存储 缓存 监控
详解缓存雪崩、缓存击穿、缓存穿透问题,一文掌握,干货不断
详解缓存雪崩、缓存击穿、缓存穿透问题,一文掌握,干货不断
|
Java 数据库连接 数据库
mybatis自制插件+注解实现数据脱敏
mybatis自制插件+注解实现数据脱敏
421 1