- - 探究中间件(MiddleWare)
1, 何为中间件?
中间件是组装到应用程序管道中以处理请求和响应的家伙, 管道中的每个组件都要满足以下两个条件
选择是否将请求传递给管道中的下一个组件
可以在调用管道中的下一个组件之前和之后执行工作.
2, 中间件的本质
在. Net Core 中, 中间件的本质就是一个 Func 的委托, 其中 RequestDelegate 的本质也是一个委托(常常听人说, 要想进阶到高级开发, 必须要搞清楚委托. 看来不得不搞懂委托了, 本文默认您已搞懂了? 如果没搞懂怎么办呢? 不要紧, 抽时间搞懂就行了), 让我们来看看它的定义(证明我没在吹牛)
再来看看 RequestDelegate
接下来我尝试着解释下 Func 这个委托. 我们都知道 Func 这个 内置的委托
(我只截了与本文相关的一张图)
通过 Func 这个截图的定义来看, 它接受一个 T 返回一个 TResult , 结合我们前面说的中间件
来说, 它接受一个 RequestDelegate, 返回一个 RequestDelegate. 也就是说, 每一个中间件 Func 的传入参数 RequestDelegate 是下一个中间件的返回值, 同时每一个中间件 Func 的返回值是前一个中间件的传入参数. 这样就构成了一串中间件链表, 每当一个请求过来, 都会按照中间件的注册顺序依次执行 RequestDelegate 中的内容, 这就构成了 ASP.NET Core 中的请求管道.(好好理解这句话, 这是真理呀, 开个玩笑, 这是我本人这么认为的.)
这里得上一张经典的图配合上一句真理来理解就不那么难了.
好, 我们现在知道了 Http 请求处理管理是由多个 Middleware 组成的. 可我们上面从没提到 Http 相关的信息, 现在让我们看看它们是如何发生恋爱(产生关系的)?
仔细看了前文的话, 大家应该注意到 RequestDelegate 的定义(仔细回想下), 哎 估计你们都想起来了, 对还是上图我们再学习下
这次我把这个家伙的定义到截到图里, 我们尝试着翻译下: A function that can process an HTTP request. 我将它翻译为: 一个能够处理 HTTP 请求的 function(函数, 方法). 是不是大家突然间知道了, 原来是这个家伙让它们与 HTTP 关联在一起的(产生了恋情).
好, 如果你不信的话就让我们来看看 HttpContext 这个家伙. 为什么要看这个家伙呢, 因为它是 RequestDelegate 这个委托 接受的参数.
好了, 这里不得不相信,.Net Core 的 Http 请求处理管道是由多个 Middleware 组成的, 并且 Middleware 与 Http 请求上下文 仅仅的关联在一起.
使用 Use,Run 和 Map 配置 HTTP 管道.
3,Use,Run 和 Map
您可以使用 Use,Run 和 Map 来配置 HTTP 管道, 但各方法针对构建的中间件作用不同.
Use:Use[Middleware]中间件负责调用管道中的下一个中间件, 也可使管道短路(即不调用 next 请求委托).
Run:Run[Middleware]是一种约定, 一些中间件组件可能会公开在管道末端运行的 Run[Middleware]方法.
Map: Map 扩展用作约定来创建管道分支, Map * 创建请求管道分支是基于给定请求路径的匹配项.
- public class Startup
- {
- public void Configure(IApplicationBuilder App)
- {
- App.Use(async (context, next) =>
- {
- // Do work that doesn't write to the Response.
- await next.Invoke();
- // Do logging or other work that doesn't write to the Response.
- });
- App.Run(async context =>
- {
- await context.Response.WriteAsync("Hello from 2nd delegate.");
- });
- }
- }
Use 将多个请求委托链接在一起, next 参数表示管道中的下一个委托, 可通过不 调用 next 参数使管道短路. 通常可在下一个委托前后执行操作.
当委托不将请求传递给下一个委托时, 它被称为 "让请求管道短路" . 通常需要短路, 因为这样可以避免不必要的工作.
Run 委托终止管道. 意思就是说, 使用的 Run 委托后, Run 下面的所有方法将不会被执行.
- public class Startup
- {
- private static void HandleMap1(IApplicationBuilder App)
- {
- App.Run(async context =>
- {
- await context.Response.WriteAsync("Map 1");
- });
- }
- private static void HandleMap2(IApplicationBuilder App)
- {
- App.Run(async context =>
- {
- await context.Response.WriteAsync("Map 2");
- });
- }
- public void Configure(IApplicationBuilder App)
- {
- App.Map("/map1", HandleMap1);
- App.Map("/map2", HandleMap2);
- App.Run(async context =>
- {
- await context.Response.WriteAsync("Hello from End Map delegate.");
- });
- }
- }
执行与响应如下:
请求 | 响应 |
localhost:5000 | Hello from End Map delegate. |
localhost:5000/map1 | Map 1 |
localhost:5000/map2 | Map 2 |
4, 总结
1), 中间件 (Middleware) 是由 IApplicationBuilder 来构建的
2), 所有的代码截图都是 IApplicationBuilder F12 后看到的
5, 说明
参考文章:
如果本文有描述不对的地方或者产生误导的地方, 请及时反馈.
来源: https://www.cnblogs.com/haoxiaozhang/p/11179778.html