SpringCloud中使⽤Nacos作为配置中⼼原理
springcloud和springboot
使⽤了是Nacos的⾃动配置依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
spring:
cloud:
nacos:
# Nacos 控制台添加配置:
# Data ID:example.properties
# Group:DEFAULT_GROUP
config:
server-addr: 127.0.0.1:8848
prefix: example
# 指定配置的后缀,⽀持 properties、yaml、yml,默认为 properties
file-extension: properties
username: nacos
password: nacos
使⽤到nacos配置中⼼的bean上配置@RefreshScope 注解,标识这个bean的作⽤域
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${useLocalCache:false}")
private boolean useLocalCache;
@RequestMapping("/get")
public boolean get() {
return useLocalCache;
}
}
以上⾯的配置为例⼦。
先说下具体配置点
1、加载的nacos属性源列表有哪些?
默认会加载 group=DEFAULT_GROUP的属性源列表有:
1、带profile的 dataId配置源 dataId = ${prefix}-${spring.profiles.active}.${file-extension}
2、不带profile的 dataId配置源 dataId = ${prefix}.${file-extension}
3、不带后缀的 dataId配置源 dataId = ${prefix}
默认情况下前缀 prefix = spring.application.name
加载属性源列表优先级为:
带profile的 DataId名称 > 带 .后缀的 dataId名称 > 不带 .后缀的 dataId名称
如上⾯的配置按照优先级,从⾼到底会加载
dataId = example-dev.properties
dataId = example.properties
dataId = example
2、nacos属性源是否覆盖本地配置⽂件和系统属性的设置
SpringCloud中,nacos是借助SpringCloud的Config来加载属性源的,所以是否覆盖系统属性和配置⽂件属性的设置也是通过SpringCloud 的配置进⾏触发。
默认情况下的配置:
spring:
cloud:
config:
# 是否不覆盖其他属性源,默认为false,即覆盖其他源
override-none: false
# 允许nacos被本地⽂件覆盖,默认为true
allow-override: true
# 是否覆盖系统属性源,默认为true
override-system-properties: true
默认情况下nacos属性源优先级最⾼,会覆盖系统属性源和配置属性源。
如果⽤户想复写上述的属性,则放在l或l配置⽂件中是⽆效的
如果要修改nacos的属性源优先级,则需要将上述配置放到nacos上的配置内容中才⽣效!
当nacos属性源中有上⾯的配置参数时
会先判断
1、(!allow-override || (!override-none && override-system-properties))
上⾯条件为真时,
override-none: false
allow-override: true
override-system-properties: true
会将nacos属性源添加到 environment的属性源列表第⼀位,
即覆盖系统属性源,并且可以覆盖其他属性源
propertySources.addFirst()
2、(override-none)
不满⾜条件1,且条件2为真时。
override-none: true
allow-override: true
override-system-properties: true
即不覆盖其他属性源,将nacos属性源放到属性源列表最后⾯。
propertySources.addLast()
3、override-system-properties = false时,
不满⾜条件1和2,上⾯条件通过
会将nacos属性源添加到系统属性源(systemEnvironment)后⾯,在其他配置⽂件之前。
所以当要让nacos优先级最⾼,使⽤默认fig配置即可。
当要让nacos属性源不覆盖本地配置⽂件,需要设置override-none: true
当要让nacos属性源覆盖本地配置⽂件,但不覆盖系统属性源,设置override-system-properties: false
启动过程:
1、SpringBoot的prepareEnvironment()⽅法初始化完系统环境属性源后,
  发布环境准备完成事件中,进⾏SpringCloud容器启动,会在这⾥进⾏Nacos的配置源加载到Environment中。
2、Nacos动态刷新配置属性相关bean定义的设置(@RefreshScope注解配置)
  @RefreshScope 注解标识 bean的⽣命周期(作⽤域)
@RefreshScope标识的bean:标识bean的⽣命周期为当前配置没发⽣变化的时间段内。
    即:当配置⽂件发⽣变化(配置content的MD5值发⽣变化时),
    会触发作⽤域:refresh的刷新操作。将会重新创建bean实例,放⼊到作⽤域bean实例列表中。
  具体查看资料::my.oschina/merryyou/blog/3119993
  如request作⽤域,标识为@RequestScope注解的bean,即等同于@Scope(WebApplicationContext.SCOPE_REQUEST),    该bean的声明周期为⼀次http请求开始到结束。即每⼀次获取http请求获取到的bean对象实例都是新创建的。
    ⽽在⼀个http请求内引⽤的bean对象实例都是相同的对象。
启动过程中作⽤域
如上⾯实例:ConfigController
有@RefreshScope注解,会被归类到作⽤域refresh下⾯,bean的创建,销毁都是由作⽤域来管理。
通过Bean(String name) ⽅法获取 ConfigController实例时,
  会判断该bean是否属于Singleton单例, Prototype原型类型
  如果都不是,则会⽤Scope作⽤域来获取bean实例。
  (String name, ObjectFactory<?> objectFactory)⽅法
refresh作⽤域对应的Scope实现类: RefreshScope
SpringBoot运⾏过程中配置的刷新:
在⾃动配置类com.alibaba.cloud.nacos.NacosConfigAutoConfiguration
申明的配置刷新类:NacosContextRefresher
刷新事件处理类:RefreshEventListener 和 ContextRefresher
当有配置变更时发布RefreshEvent事件,这个事件是RefreshEventListener监听
NacosConfigService内部维持了⼀个executor轮询线程(单线程,每隔0.01秒执⾏⼀次)和⼀个executorService处理数据线程。轮询线程会检查配置数据的md5是否变化,发⽣变化再通知listener进⾏配置变更接收。
NacosContextRefresher向Nacos注册的,会发布RefreshEvent事件
后⾯就通过Spring Cloud的刷新机制,进⾏环境配置属性的重新加载。对 scope作⽤域中 key为 "refresh" 下的bean进⾏重新⽣成。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。