什么是AOP?
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点。
总结一下:AOP能在不破坏封装的前提下,去额外扩展程序的功能。
聚焦业务,轻松扩展功能
代码复用,集中管理
面向环形编程
结合.net core的编程模型,其实也可以叫面向环形编程,记住这个图,哈哈。
每一环都可以看作是一个中间件,他们之间可以调整顺序,当然除了一些特定的中间件,顺序换了就达不到效果了,一层套一层,并且过滤器也有着同样的模型。
.NET Core 实现AOP的几种方式
Filter方式:MVC流程部分,流程外处理不了
中间件方式:任何请求最外层到达,提前做些筛选过滤工作。但是中间件没有控制器
第三方容器(Autofac)::可以深入到业务逻辑层做AOP扩展
这三种方式各有不同,可以用在不同的地方,下面来简单剖析下,其实前面都介绍过了。
1. Filter
.net core自带五种过滤器,分别是验证、资源、动作、异常捕获、结果。
Authorization Filter:身份验证
Resource Filter:发生在控制器实例化之前
Action Filter:发生Action在之前
Exception Filter:捕获异常
Result Filter:发生在视图替换环节
通常我们在这些场景下如身份验证、日志记录、异常获取等会使用到过滤器/
过滤器生命周期
注册方式:
控制器注册
Action注册
全局注册
如何使用参数的过滤器
因为特性是编译时确定的,构造函数只能传递常量,所以不能直接传递实例,以下是如何使用带参数的过滤器方法,2,3,4本质是一样的,都是实现了IFilterFactory。
全局注册
ServiceFilter(注入下过滤器)
TypeFilter(不需要注册)
IFilterFactory可自定义扩展
PS:过滤器是基于MVC框架的,所以404是进不了MVC流程,抓不到异常,所以程序在组织中间件的时候,会把404返回加进去。==
2. 中间件
中间件其实前面已经介绍过了,这里就不介绍了
3. Autofac拦截器
之前在讲IOC的时候也讲了拦截器,这里也不讲了。
应用场景
防盗链
中间件:我们可以在中间件中加入判断,如果不是本地网站访问静态的文件,返回一个404等,不让第三方文件盗用我的图片链接等,和下面的白名单类似的。
黑白名单
中间件:通过IP判断是否授权,简单demo
private readonly RequestDelegate _next;
private readonly IList<string> _white;
public HotLinkMiddleware(RequestDelegate next)
{
_next = next;
_white = new List<string> { "localhost"};
}
public async Task Invoke(HttpContext context)
{
if(_white.Contains(context.Request.Host.Host))
{
await _next.Invoke(context);
}
else
{
await context.Response.WriteAsync("Unauthorized 404", Encoding.UTF8);
}
}复制
缓存
几种方式都可以做,只不过原理不一样,有的是把缓存存在本地服务器,有的是存在客户端,看需求选用。
客户端缓存
本质是在http请求头部加上["Cache-Control"]="public,max-age=60"
服务端缓存:
Filter 资源缓存,只能作用于Action层。
Autofac AOP缓存,可以深入到业务逻辑层,可以利用本地缓存,分布式缓存等。
ResponseCaching:需要安装Microsoft.AspNetCore.ResponseCaching
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCaching();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCaching();
}复制
表现出来的结果是:
第一次刷新的时候,会进入中间件,然后进入Action,返回结果,Fiddler记录到了这一次的请求
第二次打开新标签页,直接从浏览器缓存中返回的结果,即没有进入中间件,也没有进入Action,Fiddler也没有记录到相关请求
第三次换了一个浏览器,会进入中间件,直接由缓存返回结果,并没有进入Action,此时Fiddler也将该请求记录了下来,响应头包含了Age
静态文件缓存 对于静态文件,.NET Core有一个单独的StaticFiles中间件,如果想要对它做一些处理,同样需要在管道中进行注册。
合理的利用缓存机制可以有效地降低服务端负载,在微服务应用中尤为重要。