@RefreshScope
@RestController
public class RoleController {
@Value("${aa}")
private String aa;
@GetMapping("test")
public String list(){
System.out.println(aa);
return aa;
}
}
bootstrap.yml
spring:
application:
name: order
cloud:
nacos:
config:
file-extension: properties #文件扩展名
server-addr: localhost:8848
username: nacos
password: nacos
pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.16</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo5</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo5</name>
<description>demo5</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--服务发现 加了这个依赖 nacos才会显示服务-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.0.5.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--Nacos配置中心的依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.0.5.0</version>
</dependency>
<!--在springcloud 2021的版本中 已经去掉了bootstrap.yml 加入下面的依赖 就是为了解决添加了bootstrap.yml 启动报错-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.0.3</version>
</dependency>
<!--和其他服务进行通信-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.7</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>3.1.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
初始值aa=66666
RefreshScope类里面会有@Scope("refresh")这个注解
当项目启动的时候,访问下面的方法
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
会判断有没有加@RefreshScope注解
如果有读取Scope的信息
加了@RefreshScope注解的会进入下面的方法
把当前的name和对象工厂放入bean生命周期的缓存中
org.springframework.cloud.context.scope.GenericScope#get
返回之后scope对应的对象,可以看到aa的当前值
在NacosContextRefresher这个类中实现了监听器,然后再项目启动完毕之后
注册nacos的配置文件的监听
com.alibaba.cloud.nacos.refresh.NacosContextRefresher#onApplicationEvent
com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListenersForApplications
应用上下文发布事件
com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListener
在这个方法中,监听nacos的配置修改
org.springframework.cloud.endpoint.event.RefreshEventListener#onApplicationEvent
监听配置文件的变化
当我们把aa修改成555
立马触发监听事件
com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListener
并在下面的方法中刷新配置
org.springframework.cloud.endpoint.event.RefreshEventListener#handle(org.springframework.cloud.endpoint.event.RefreshEvent)
在初始化这个方法中,读取到了修改后的数据
org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration#initialize
然后回到准备上下文方法这里,把新的配置放入bean中
org.springframework.boot.SpringApplication#run(java.lang.String...)
然后我们在@value读取的时候,就是刷新后的配置
一句话总结
如果加了@RefreshScope注解,nacos配置变更,监听配置文件的变化,刷新上下文
那么在doGetBean方法中会从scope的生命周期缓存中拿到aa这个bean的信息
如果没有加@RefreshScope注解,不会去读socpe这块的数据