跟我一起学.NetCore之配置变更监听
前言
通常程序中配置少不了,配置的修改也避免不了,配置的热更新为此给应用程序带来很大的便捷,不用重启,提高用户体验;但往往有时候需要对修改进行审计,也就是需要记录,有时候也会针对配置修改的时候触发相关操作,比如说发邮件通知,或是其他业务操作等,遇到这种情况,配置变更监听的用处就体现出来了,接下来就尝尝鲜去;
正文
在看前两篇文档的小伙伴可能会看到IConfiguration、IConfigurationProvider接口中有一个GetReloadToken()方法,之前只是注释了一下,其实此方法返回的值就是变更通知的核心,如下图的定义:

看看返回的IChangeToken里定义了什么

对于上面GetReloadToken其实最后返回的真正类型是ConfigurationReloadToken,继承与IChangeToken,其作用就是为了通知程序:改变之后的配置源数据已经通过对应的IConfigurationProvider重新加载;看看其中是本质是啥?

通过以上代码显示,其实ConfigurationReloadToken就是利用CancellationTokenSource在OnReload触发的时候进行通知,这里暂且不深入再研究CancellationTokenSource了,不然感觉要跑题了(可以私下研究研究),停,赶紧回来;
大概了解到变更通知的原理,再来回顾一下配置IConfigurationRoot和IConfigurationSection,其实这两个微软其实已经实现了两个类,ConfigurationRoot和ConfigurationSection,有默认的实现,简单看看是如何实现的,稍微进行了重点注释哦;
namespace Microsoft.Extensions.Configuration
{
// 实现了IConfiguration 和ConfigurationRoot
public class ConfigurationRoot : IConfigurationRoot, IConfiguration, IDisposable
{
// 用于存放注册进来的IConfigurationProvider,Provider的作用还记得吗?
private readonly IList<IConfigurationProvider> _providers;
// 默认创建一个ConfirationReloadToken,
private ConfigurationReloadToken _changeToken = new ConfigurationReloadToken();
// 提供一个_providers的访问属性
public IEnumerable<IConfigurationProvider> Providers => _providers;
// 实现中括号访问,获取配置值,看过前两篇文章的应该知道都是用中括号的方式获取值
public string this[string key]
{
get
{ // 注意,这里倒序遍历,这样就会导致相同Key,后注册的配置源会覆盖之前的
for (int num = _providers.Count - 1; num >= 0; num--)
{
if (_providers[num].TryGet(key, out string value))
{
return value;
}
}
return null;
}
set
{
if (!_providers.Any())
{
throw new InvalidOperationException(Resources.Error_NoSources);
}
// 其实这里的设置值只是在内存里,没有持久化
foreach (IConfigurationProvider provider in _providers)
{
provider.Set(key, value);
}
}
}
// 构造函数
public ConfigurationRoot(IList<IConfigurationProvider> providers)
{
if (providers == null)
{
throw new ArgumentNullException("providers");
}
_providers = providers;
_changeTokenRegistrations = new List<IDisposable>(providers.Count);
// 遍历所有有providers,加载数据
foreach (IConfigurationProvider p in providers)
{
// 加载数据
p.Load();
// 注册监听及回调
_changeTokenRegistrations.Add(ChangeToken.OnChange((Func<IChangeToken>)(() => p.GetReloadToken()), (Action)delegate
{
// 通知
RaiseChanged();
}));
}
}
// 获取通知Token
public IChangeToken GetReloadToken()
{
return _changeToken;
}
// 重新加载数据
public void Reload()
{
// 遍历所有provider进行重新加载数据
foreach (IConfigurationProvider provider in _providers)
{
provider.Load();
}
// 发送通知
RaiseChanged();
}
// 触发通知
private void RaiseChanged()
{
Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken()).OnReload();
}
........省去一些方法......
}
}
ConfigurationSection就不贴代码,其实内部大多都是通过调用了IConfigrationRoot对象的方法来实现的,还是贴个图吧,如下:

由ConfigurationRoot可见,触发通知的方法RaiseChanged在ConfigurationRoot构造函数中(ConfigurationProvider对应的IChangeToken回调中调用)及Reload的方法中进行调用,也就是说当IConfigurationProvider捕捉到配置源改变时会利用IChangeToken进行通知,或通过调用Reload方法加载时也会通知;
好了好了,理论就暂且说这么多了,撸撸代码,看看是如何监听的,话说在前头,理论一大堆,使用很简单,哈哈哈哈哈,控制台程序走起来:

运行结果

经过上面案例演示,一个IChangeToken只能通知一次,需要多次创建,如果多次都是自己肯定很麻烦,所以微软已经想到了,提供了一个静态函数,如下代码优化即可:

运行结果:

静态方法这种形式,就是ConfigurationRoot构造函数中IChangeToken监听的方式,忘了的话往上再看看;
总结
有没有被这节给忽悠了,一个这么简单的使用,还说那么多"废话",写文字不累吗? 我去,又过12点了,洗洗睡觉!!!!!;下次开始说说“Option”~~~
----------------------------------------------
一个被程序搞丑的帅小伙,关注"Code综艺圈",跟我一起学~~~

跟我一起学.NetCore之配置变更监听的更多相关文章
- 配置静态监听解决ORA-12514错误的案例(转)
今天做Linux下DG配置的时候,遇到一个现象,tnsname.ora文件配置都正常,tnsping也正常,监听也正常,但是仍然报ORA-12514错误: SQL> set lin 130 ...
- Tomcat介绍、安装jdk、安装Tomcat、配置Tomcat监听80端口
1.Tomcat介绍 2.安装jdk下载:wget -c http://download.oracle.com/otn-pub/java/jdk/10.0.1+10/fb4372174a714e6b8 ...
- 配置Tomcat监听80端口 配置Tomcat虚拟主机 Tomcat日志
配置Tomcat监听80端口 • vim /usr/local/tomcat/conf/server.xml Connector port=" protocol="HTTP/1.1 ...
- 配置静态监听解决ORA-12514错误的案例
今天做Linux下DG配置的时候,遇到一个现象.tnsname.ora文件配置都正常,tnsping也正常,监听也正常.可是仍然报ORA-12514错误: SQL> set lin 130 pa ...
- 配置Tomcat监听80端口、配置Tomcat虚拟主机、Tomcat日志
6月27日任务 16.4 配置Tomcat监听80端口16.5/16.6/16.7 配置Tomcat虚拟主机16.8 Tomcat日志扩展邱李的tomcat文档 https://www.linuser ...
- CentOS7 配置 SSH监听多个端口方法
一.修改ssh默认端口,防止暴力破解,让系统安全多一点点: i. 在配置文件/etc/ssh/sshd_config文件中修改 Port #AddressFamily any #ListenAddre ...
- 作业调度框架Quartz.NET-现学现用-02-任务监听
原文:作业调度框架Quartz.NET-现学现用-02-任务监听 前言 任务调度系统并不是完美的,它会出现任务执行失败的情况.如果你需要处理任务失败后的逻辑,希望这篇笔记可以为你提供些帮助. Quar ...
- 作业调度框架Quartz.NET-现学现用-02-任务监听 - 简书
原文:作业调度框架Quartz.NET-现学现用-02-任务监听 - 简书 前言 任务调度系统并不是完美的,它会出现任务执行失败的情况.如果你需要处理任务失败后的逻辑,希望这篇笔记可以为你提供些帮助. ...
- Linux centosVMware 配置Tomcat监听80端口、配置Tomcat虚拟主机、Tomcat日志
一.配置Tomcat监听80端口 关闭tomcat报错 [root@davery src]# /usr/local/tomcat/bin/shutdown.sh 重装tomcat即可 vim /usr ...
随机推荐
- jmeter零散知识点
- leetcode题库练习_数组中重复的数字
题目:数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次 ...
- 5G UE能力-UE capability information解析(ENDC)
本文主要以EN-DC(双连接),mmw(毫米波)的接入过程中的为例,其他以此类推,整理不易,望多推荐 第一次UE能力问询 第一次能力问询主要是基站向UE问询4G和3G能力 第一次UE能力上报 第一次U ...
- Pexpect模块的简单使用
Pexpect 是一个用来启动子程序并对其进行自动控制的 Python 模块. Pexpect 可以用来和像 ssh.ftp.passwd.telnet 等命令行程序进行自动交互.以下所有代码都是在K ...
- pandas之Seris和DataFrame
pandas是一个强大的python工具包,提供了大量处理数据的函数和方法,用于处理数据和分析数据. 使用pandas之前需要先安装pandas包,并通过import pandas as pd导入. ...
- 事件流和初识Jquery
一.事件流 定义: 多个彼此嵌套元素,他们拥有相同的事件,最内部元素事件被触发后,外边多个元素的同类型事件也会被触发,多个元素他们同类型事件同时执行的效果称为“事件流”. 事件对象获取: 获得: ①主 ...
- Lua学习入门(基本数据类型)
数据类型 Lua 中有 8 个基本类型分别为:nil.boolean.number.string.userdata.function.thread 和 table. 数据类型 描述 nil 这个最简单 ...
- Python os.pathconf() 方法
概述 os.pathconf() 方法用于返回一个打开的文件的系统配置信息.高佣联盟 www.cgewang.com Unix 平台下可用. 语法 fpathconf()方法语法格式如下: os.fp ...
- Python os.ftruncate() 方法
概述 os.ftruncate() 裁剪文件描述符fd对应的文件, 它最大不能超过文件大小.高佣联盟 www.cgewang.com Unix, Windows上可用. 语法 ftruncate()方 ...
- PHP curl_setopt函数
(PHP 4 >= 4.0.2, PHP 5) curl_setopt — 设置一个cURL传输选项. 说明 bool curl_setopt ( resource $ch , int $opt ...