最新要闻
- 今头条!北方多地迎沙尘!长春直接下“泥雨”:汽车变泥车
- 环球速讯:OPPO、小米、vivo联盟:跨品牌一键换机新增第三方应用迁移
- 最新消息:史上最强骁龙7系 真我GT Neo5 SE跑分过百万:16+1TB存储确认
- 今日关注:Alphaliner:2月底港口停运船比率达6.4% 增至去年同期3倍
- 4月上映!《长空之王》新预告出炉:王一博驾驶歼20一飞冲天
- 世界今头条!自嗨锅自热煲仔饭4桶到手价32.8元:15分钟速烹美食
- 今年以来最强沙尘来袭!你的城市在下雨 他的城市在下泥
- 邓紫棋你把我灌醉高音最高是多少?邓紫棋你把我灌醉歌词
- 苏菲日记是什么?苏菲日记的读后感怎么写?
- strict怎么读?strict的反义词是什么?
- 主题班会的开场白有什么要求?主题班会的开场白怎么写?
- 河南洛阳旅游景点排名前十名有哪些?河南洛阳美食排行榜前十名
- 【环球新要闻】害怕开车也不愁 小米汽车新专利:根据驾驶员匹配自动驾驶等级
- 前沿资讯!漫威《美国队长4:新世界秩序》开拍 片场首曝:“猎鹰”美队来了
- 每日热门:一语成谶!网传鬼火少年“三部曲”:片头壮行、片尾撞车
- 俄罗斯伏尔加汽车厂:中国汽车是新款拉达Vesta的主要对手
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
环球报道:关于asp.net core filters生命周期的探究
1.背景
昨天看了关于一篇 api 限流的文章,ASP.NET Core WebApi接口限流,作者给出了demo,写的很好,但是我看了一遍,api限流用actionfilterattribute,觉得很奇怪,难道说每次都是用的同一个filter。思考一番觉得自己还是写个demo验证以下,顺便看看源码是如何实现的,
(资料图片)
2.demo
public class MyActionfilterAttribute:ActionFilterAttribute { private int a; public MyActionfilterAttribute() { a = 50; } public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { Console.WriteLine($"begin"); ++a; Console.WriteLine(a.ToString()) ; Console.WriteLine("end"); return base.OnActionExecutionAsync(context, next); } }
调试连续点击多次 出现如下结果,果然是同一个filter。看来确实是可以用actionfilter进行请求限制。
3.源码探究
感觉到奇怪的我转手就去看源码了,不对首先先搜一下有没有相关的文章,找到了一篇https://www.cnblogs.com/xiaoxiaotank/p/15622083.html 详细介绍了filters。点赞。
我的上一篇文章探究了以下controller在什么时侯被构建的,同时什么使用调用filter过滤器管道,其中就有如何获取filter,所以接着继续薅就是了。
ControllerActionInvokerCache
public (ControllerActionInvokerCacheEntry cacheEntry, IFilterMetadata[] filters) GetCachedResult(ControllerContext controllerContext) { // We don"t care about thread safety here if (cacheEntry is null) { var filterFactoryResult = FilterFactory.GetAllFilters(_filterProviders, controllerContext); filters = filterFactoryResult.Filters; //省略若干代码 } else { // Filter instances from statically defined filter descriptors + from filter providers filters = FilterFactory.CreateUncachedFilters(_filterProviders, controllerContext, cacheEntry.CachedFilters); } return (cacheEntry, filters); }
逻辑比较简单,如果没有缓存那么就获取所有的filters,如果有缓存那么就创建没有缓存的filters。
FilterFactory
public static FilterFactoryResult GetAllFilters( IFilterProvider[] filterProviders, ActionContext actionContext) { var actionDescriptor = actionContext.ActionDescriptor; var staticFilterItems = new FilterItem[actionDescriptor.FilterDescriptors.Count]; var orderedFilters = actionDescriptor.FilterDescriptors .OrderBy( filter => filter, FilterDescriptorOrderComparer.Comparer) .ToList(); for (var i = 0; i < orderedFilters.Count; i++) { staticFilterItems[i] = new FilterItem(orderedFilters[i]); } var allFilterItems = new List(staticFilterItems); // 由filter factory 决定哪个filter可以被缓存 // Execute the filter factory to determine which static filters can be cached. var filters = CreateUncachedFiltersCore(filterProviders, actionContext, allFilterItems); // Cache the filter items based on the following criteria // 1. Are created statically (ex: via filter attributes, added to global filter list etc.)2. Are re-usable //缓存filter基于以下几点 : 首先静态生成 其次能够被重复使用 var allFiltersAreReusable = true; for (var i = 0; i < staticFilterItems.Length; i++) { var item = staticFilterItems[i]; if (!item.IsReusable) { item.Filter = null; allFiltersAreReusable = false; } } if (allFiltersAreReusable && filterProviders.Length == 1 && filterProviders[0] is DefaultFilterProvider defaultFilterProvider) { // If we know we can safely cache all filters and only the default filter provider is registered, we can probably re-use filters between requests. //如果我们知道我们能够安全的缓存这些filters,然后只有默认的filter providerb被注册,那么我们大 概可以在请求中重复使用这些过滤器 actionDescriptor.CachedReusableFilters = filters; } return new FilterFactoryResult(staticFilterItems, filters); }
看到官方的注释确实我们是重复使用这些 filter的,应该是为了提高提高效率
主要的逻辑是 filterprovider来创建filter,然后我们拿到filter,有个属性为 IsReuable决定了我们是否可以重用这个filter
FilterFactory
private static IFilterMetadata[] CreateUncachedFiltersCore( IFilterProvider[] filterProviders, ActionContext actionContext, List filterItems) { // Execute providers var context = new FilterProviderContext(actionContext, filterItems); for (var i = 0; i < filterProviders.Length; i++) { filterProviders[i].OnProvidersExecuting(context); } for (var i = filterProviders.Length - 1; i >= 0; i--) { filterProviders[i].OnProvidersExecuted(context); } // Extract filter instances from statically defined filters and filter providers//删除一些代码 var filters = new IFilterMetadata[count]; var filterIndex = 0; for (int i = 0; i < filterItems.Count; i++) { var filter = filterItems[i].Filter; if (filter != null) { filters[filterIndex++] = filter; } } return filters; }
进去看看 onprovidersexecuting方法 看就怎么产生的filters,默认的实现是
DefaultFilterProvider
public void OnProvidersExecuting(FilterProviderContext context) { if (context.ActionContext.ActionDescriptor.FilterDescriptors != null) { var results = context.Results; // Perf: Avoid allocating enumerator and read interface .Count once rather than per iteration var resultsCount = results.Count; for (var i = 0; i < resultsCount; i++) { ProvideFilter(context, results[i]); } } }public void ProvideFilter(FilterProviderContext context, FilterItem filterItem) { if (filterItem.Filter != null) {return;} var filter = filterItem.Descriptor.Filter; if (filter is not IFilterFactory filterFactory) //标记的filter不是IFilterFactory类型 { filterItem.Filter = filter; filterItem.IsReusable = true; //那么可以重复使用 } else { var services = context.ActionContext.HttpContext.RequestServices; filterItem.Filter = filterFactory.CreateInstance(services);//创建实例 filterItem.IsReusable = filterFactory.IsReusable; ApplyFilterToContainer(filterItem.Filter, filterFactory); } }
上面的注释就是创建filter的主要逻辑了,如果是静态构造那么可用重复使用,然后IFilterFactory主要有两种类型,一种是ServiceFilterAttribute,要求该过滤器和构造函数参数要在DI容器中注册,另一种是TypeFilterAttribute,部分参数自己提供,部分参数ioc提供。这两种filter.IsReusable=false.
看看如果有缓存那么是如何创建filters
FilterFactory
public static IFilterMetadata[] CreateUncachedFilters( IFilterProvider[] filterProviders, ActionContext actionContext, FilterItem[] cachedFilterItems) {//删除一些代码 if (actionContext.ActionDescriptor.CachedReusableFilters is { } cached) { return cached; //如果都是可以缓存的filter直接返回 }//深拷贝一份数据 // Deep copy the cached filter items as filter providers could modify them var filterItems = new List(cachedFilterItems.Length); for (var i = 0; i < cachedFilterItems.Length; i++) { var filterItem = cachedFilterItems[i]; filterItems.Add( new FilterItem(filterItem.Descriptor) { Filter = filterItem.Filter, IsReusable = filterItem.IsReusable }); } return CreateUncachedFiltersCore(filterProviders, actionContext, filterItems); }
深度拷贝了一份数据,但是filterItem.Filter没有拷贝进来,复制的是filterItem.Descriptor属性所以再调用CreateUncachedFiltersCore的时候我们可以复用静态构造的filter,但是其他的就要重新构造一份了。
4.总结
1.静态构造的filter会复用,其他的会重新构造
2.翻了一遍源码,写bug更有心得了。
关键词:
-
环球报道:关于asp.net core filters生命周期的探究
1 背景昨天看了关于一篇api限流的文章,ASP NETCoreWebApi接口限流,作者给出了demo,写的很好,但是...
来源: JavaSE笔记之注解和反射(含案例代码)
当前速递!Android BLE 广播定制
环球报道:关于asp.net core filters生命周期的探究
今头条!北方多地迎沙尘!长春直接下“泥雨”:汽车变泥车
环球速讯:OPPO、小米、vivo联盟:跨品牌一键换机新增第三方应用迁移
最新消息:史上最强骁龙7系 真我GT Neo5 SE跑分过百万:16+1TB存储确认
世界今热点:孤立森林(IForest)代码实现及与PyOD对比
最资讯丨three.js加载环境贴图
天天热讯:java中同步和异步的区别
今日关注:Alphaliner:2月底港口停运船比率达6.4% 增至去年同期3倍
4月上映!《长空之王》新预告出炉:王一博驾驶歼20一飞冲天
世界今头条!自嗨锅自热煲仔饭4桶到手价32.8元:15分钟速烹美食
今年以来最强沙尘来袭!你的城市在下雨 他的城市在下泥
邓紫棋你把我灌醉高音最高是多少?邓紫棋你把我灌醉歌词
苏菲日记是什么?苏菲日记的读后感怎么写?
strict怎么读?strict的反义词是什么?
主题班会的开场白有什么要求?主题班会的开场白怎么写?
河南洛阳旅游景点排名前十名有哪些?河南洛阳美食排行榜前十名
当前简讯:一种基于实时大数据的图指标解决方案
【天天报资讯】智能零售柜商品检测软件(Python+YOLOv5深度学习模型+清新界面)
来了解下GNOME 2 的 Linux 文件管理器 Caja
【状压DP】蒙德里安的梦想
【环球新要闻】害怕开车也不愁 小米汽车新专利:根据驾驶员匹配自动驾驶等级
前沿资讯!漫威《美国队长4:新世界秩序》开拍 片场首曝:“猎鹰”美队来了
每日热门:一语成谶!网传鬼火少年“三部曲”:片头壮行、片尾撞车
俄罗斯伏尔加汽车厂:中国汽车是新款拉达Vesta的主要对手
省钱神器!淘宝内测同款比价功能:最快本周上线
全球速看:记一次 rr 和硬件断点解决内存踩踏问题
天天新资讯:生核桃怎么变熟核桃_生核桃怎么弄熟
魅族20 PRO三款配色公布:绝美朝阳金吸睛
天天快消息!25日继续公测 暴雪承诺《暗黑4》会解决排队问题:服务器顶得住
环球精选!沙尘天气席卷!北京再现火星同款“蓝太阳” 专家揭秘
世界即时:开特斯拉回村被乡亲群嘲“大冤种” 30万买BBA不好吗?
今日热门!微信聊天记录不用头疼了:vivo宣布跨品牌换机数据迁移
基于深度学习的安全帽检测系统(YOLOv5清新界面版,Python代码)
MAC 最新中文版 FCPX 10.6.5 及相关插件下载安装教程 亲测有效
大数据计算引擎 EasyMR:拥抱开源,引领技术创新
当前聚焦:Java面试问题
解放生产力:30+实用AI工具汇总
全球今日讯!谷歌版ChatGPT开放测试:不会编程、不支持中文
全球聚焦:微软研究员质疑Bard数据集包括Gmail邮件:谷歌迅速澄清
2999元 小米米家对开门540L冰箱今晚开售:风冷无霜保鲜
120mg原生高钙 特仑苏纯牛奶3元/盒大促
天天最新:破解大难题!苹果新专利:佩戴太阳镜也可看清iPhone屏幕内容
【报资讯】vue3
世界视点!设计模式-index
精彩看点:商铺上月买卖91宗 涉21亿创半年高
热点评!平板电脑屏幕冷知识:高刷比高分辨率重要
焦点热讯:比尔·盖茨:GPT是1980年以来最革命性的技术进步
今日热讯:极氪009平均订单金额达52.7万元 一台订单收入相当于吉利卖5台
谷歌版ChatGPT Bard开启公测!CEO:肯定会出错、欢迎反馈
世界焦点!漫威《美队4》正式开拍 首曝片场路透:猎鹰美队就位
世界热议:Android性能优化-ListView自适应性能问题
读C#代码整洁之道笔记03_切面关注点、异常处理和线程与并发
当前时讯:放假一天不调休!2023清明节假期火车票今日开售
快资讯丨《霍格沃茨》在线人数锐减 “反恐同”人士冷嘲热讽
环球今日讯!《战争机器》电影确定编剧
世界聚焦:刚买1个月的特斯拉掉漆车主质疑非新车 售后:交付时没问题
热消息:公交司机急刹车致乘客死亡获刑 官方判定当时不需刹车:交通肇事罪
全球最资讯丨新车品鉴:2020广州车展探馆:广汽传祺EMPOWER
每日热闻!【看新股】10家拟上市银行“换道”注册制:利润普遍增长、资产质量分化、资本充足率承压
精选!iOS 17将支持第三方应用商店:看齐安卓
读Java性能权威指南(第2版)笔记24_ Java飞行记录器JFR
洗衣机6个月不清洗比马桶还脏?我麻了
时代的眼泪 25年历史的数码相机权威网站Dpreview关停
当前快报:Go 并发编程(二):锁、Select、Context、定时器
焦点报道:智能生活垃圾检测与分类系统(UI界面+YOLOv5+训练数据集)
当前通讯!Servlet的基本使用
每日资讯:中国移动:命苦
天天速看:鹿客发布掌心锁V5:掌静脉+3D结构光刷脸解锁 3399元起
尼泊尔空难20天就查明原因?为什么东航事故还没有结果?
世界微资讯!腾讯四年磨一剑!结果 让大家看笑话了
OPPO Find X6 Pro:表演一场简单的光影魔术
亨迪药业(301211):3月21日北向资金减持66.63万股
世界最资讯丨uni-app云开发入门
当前资讯!WPF学习-布局
世界热文:全明星爆款APP“偶像驾到”正式上线 主播经济和明星经纪开启新时代
小屏手机真凉了!苹果卖最差的iPhone 14 Plus 出货量也远超13 mini
今日快讯:mysql集群搭建docker-compose方案
上海农商银行完成上海市政府柜台债发售
山姆会员店寿司致多人上吐下泻:官方拒绝三倍赔偿
天天新消息丨致敬葫芦娃?保时捷911 Carrera GTS泰国特别版官图发布
环球最资讯丨14.5英寸超大屏+天玑9000!联想Y900平板正式发布:4999元起
天天观点:13代酷睿+RTX 40!联想拯救者Y7000P 2023电竞本发布:屏幕大升级
13900HX+4090顶配20999元!联想拯救者Y9000P 2023价格公布
环球最新:睡眠报告:山东人上床睡觉时间全国最早、广东人最能熬夜
焦点快看:埃安(埃)
数据库系统
世界看点:day08-2-Thymeleaf
世界快看:使用OpenCVSharp和NAudio库在C#中录制带有声音的视频并保存下来的代码
焦点快报!债市日报:3月21日
天天观速讯丨放假5天!大学生已经在为五一做准备了
外出告别“板砖”电源!联想拯救者推出140W氮化镓适配器
4799元 创维推出新款G60 4K显示器:150Hz高刷 96W反向充电
即时焦点:2023载人航天飞行任务标识正式发布:中国神话神兽鲲元素
全国车企疯狂降价!吉利汽车CEO:吉利不打价格战
每日消息!微服务与rpc/grpc
全球观热点:第132篇:npm第一次使用自己的包(package-lock.json、package.json文件作用说明)
精彩看点:【Visual Leak Detector】在 QT 中使用 VLD(方式一)
热讯:华硕发布新款Vivobook Go 14/15 OLED笔记本:高配酷睿i3-N305