05-《AspNetCore》-AOP

  • 05-《AspNetCore》-AOP已关闭评论
  • 134 次浏览
  • A+
所属分类:.NET技术
摘要

视频讲解
面向切面编程AOP的对面向对象编程OOP的一个补充,它的特点是将系统逻辑和业务逻辑采取《非侵入式》分离。我们把系统封装成一个一个的切面(单一职责)进行顺意编排组合,插入(织入)到业务逻辑的执行过程(织入点)。


AOP

视频讲解
面向切面编程AOP的对面向对象编程OOP的一个补充,它的特点是将系统逻辑和业务逻辑采取《非侵入式》分离。我们把系统封装成一个一个的切面(单一职责)进行顺意编排组合,插入(织入)到业务逻辑的执行过程(织入点)。

系统逻辑:异常处理,身份认证,授权,mvc,数据校验,事务处理。

业务逻辑:就是我们的业务Service。

切面:用于封装系统逻辑,比如身份认证filter,或者中间件

切入点:就是管道的位置。名词

织入:就是插入到管道的切入点的过程。动词

AOP的特点:

1.非侵入式

2.低耦合

3.代码服用

4.单一职责

5.可插拔

实现方式:

1.管道链,比如aspnetcore的中间件,mvc中的Filter

2.静态代理:思考如何加强一个List,使得在插入时打印日志?

3.动态代理:Emit

4.三种模式都需要通过一些技术进行串联,实现链式调用,构成管道。静态代理通过接口进行串联,动态代理通过反射进行串联。管道通过接口获取委托进行串联。委托本质也是接口。

代理:就是增强,代理对象必须尽量实现目标对象的功能,在此基础上进行加强。比如vpn,你的电脑的网络就是目标对象,vpn就是代理服务,代理服务起码得实现联网功能吧,然后对网络进行加强,访问到一些你的本机网络访问不到的东西。

掌握了AOP技术我们可以实现很多好处,做到非侵入式的增强业务逻辑。

//侵入式方案,把这个看懂。后面就是围绕这个开展,高出非侵入式 public static void A() {     Console.WriteLine("A:开始");     B();//A,B的调用关系强行绑定,有侵入性     Console.WriteLine("A:结束"); } public static void B() {     Console.WriteLine("B:开始");     C();     Console.WriteLine("B:结束"); } public static void C() {     Console.WriteLine("Hello World"); } public static void Dobasic() {     A(); } 

静态代理

1.代理就是实现目标对象的标准(接口),在目标方法执行之前和之后进行逻辑织入的过程。代理的目的就是为了加强。代理不负责实现接口,一般通过target来实现接口。即代理除了可以增强之外还能简化接口的实现。

2.静态代理就是在代理之前就已经确定了代理关系。需要自己实现标准并编写代理类。代理类中的逻辑只能代理一些标准(实现多个接口)。无法代理所有标准。

3.静态代理可以实现不改变目标对象的源码的情况下进行加强,完成目标对象的能力,并且在此基础之上进行加强。

4.可以简化实现的成本,不改变业务代码,只需要编写额外的增强逻辑。不需要关系具体的业务实现。

5.代理和代理直接通过接口可以进行互相代理,链式调用,顺意编排组合,实现系统的多样化。

 /// <summary> /// 定义标准1 /// </summary> public interface IPhoneService {      string Mobile { get; set; }     string Message { get; set; }     void Send(); } //实现标准-不是代理模式 public class PhoneService : IPhoneService {     public string Mobile { get; set; }     public string Message { get; set; }      public PhoneService(string mobile, string message)     {         Mobile = mobile;         Message = message;     }      public virtual void Send()     {         Console.WriteLine($"已发送短信:{Message}到{Mobile}");     } } //代理模式: //1.实现目标对象的标准 //2.依赖目标对象(被代理对象) //3.业务织入 public class PhoneServiceProxy : IPhoneService//实现标准 {     private readonly IPhoneService _target;      public PhoneServiceProxy1(IPhoneService target)     {         _target = target;     }      public string Mobile { get => _target.Mobile; set => _target.Mobile = value; }     public string Message { get => _target.Message; set => _target.Message = value; }      /// <summary>     /// 子类重写父类方法     /// </summary>     public void Send()     {         Console.WriteLine("Proxy1:已对手机号进行验证");         _target.Send();         Console.WriteLine("Proxy1:已确认对方已经收到");     } }  
/// <summary> /// 定义标准1 /// </summary> public interface IPhoneService {     string Mobile { get; set; }     string Message { get; set; }     void Send(); } /// <summary> /// 定义标准2 /// </summary> public interface IEmailService {     string Email { get; set; }     string Message { get; set; }     void Send(); } /// <summary> /// 业务逻辑1 /// </summary> public class PhoneService : IPhoneService {     public string Mobile { get; set; }     public string Message { get; set; }      public PhoneService(string mobile, string message)     {         Mobile = mobile;         Message = message;     }      public virtual void Send()     {         Console.WriteLine($"已发送短信:{Message}到{Mobile}");     } } /// <summary> /// 业务逻辑2 /// </summary> public class EmailService : IEmailService {     public string Email { get; set; }     public string Message { get; set; }      public EmailService(string email, string message)     {         Email = email;         Message = message;     }      public virtual void Send()     {         Console.WriteLine($"已发送邮件:{Message}到{Email}");     } }  /// <summary> /// 切面1:校验能力(系统逻辑) /// taget方式 /// </summary> public class PhoneServiceProxy1     : IPhoneService//实现标准1 {     private readonly IPhoneService _target;      public PhoneServiceProxy1(IPhoneService target)     {         _target = target;     }      /// <summary>     /// 子类重写父类方法     /// </summary>     public void Send()     {         Console.WriteLine("Proxy1:已对手机号进行验证");         _target.Send();         Console.WriteLine("Proxy1:已确认对方已经收到");     } } /// <summary> /// 切面2:加速能力(系统逻辑) /// </summary> public class PhoneServiceProxy2    : IPhoneService//实现标准1 {     private readonly IPhoneService _target;      public PhoneServiceProxy2(IPhoneService target)     {         _target = target;     }      /// <summary>     /// 子类重写父类方法     /// </summary>     public void Send()     {         Console.WriteLine("Proxy2:已开启加速通道");         _target.Send();         Console.WriteLine("Proxy2:已关闭加速通道");     } } //test public static void TestStaticProxy() {     //目标对象     IPhoneService target = new PhoneService("10088", "你好啊!");     //切面1:验证,对target进行代理     IPhoneService proxy1 = new PhoneServiceProxy1(target);     //切面2:加速,对proxy1进行代理     IPhoneService proxy2 = new PhoneServiceProxy2(proxy1);     //执行     proxy2.Send();     //思考如果要实现IEmailService标准,是不是要重写实现类了? } 

动态代理

Castle.Core

动态代理和静态代理的区别就是,代理类由工具生成,需要在运行时确认代理类已经代理关系。代理类中的逻辑写到拦截器里面,可以进行复用。缺点是性能差。里面涉及到大量反射技术。

Castle.Core:原理就是通过子类继承父类或者实现父类标准,通过Castle.Core自动帮你生成代理类,通过一个叫拦截器的东西编写代理类要执行的业务逻辑。Castle.Core会帮你生成代理类,并将拦截器织入到代理类中。

动态代理通过invocation进行串联,本质是反射。

/// <summary> /// 定义标准1 /// </summary> public interface IPhoneService {     string Mobile { get; set; }     string Message { get; set; }     void Send(); } /// <summary> /// 定义标准2 /// </summary> public interface IEmailService {     string Email { get; set; }     string Message { get; set; }     void Send(); } /// <summary> /// 业务逻辑1 /// </summary> public class PhoneService : IPhoneService {     public string Mobile { get; set; }     public string Message { get; set; }      public PhoneService(string mobile, string message)     {         Mobile = mobile;         Message = message;     }      public virtual void Send()     {         Console.WriteLine($"已发送短信:{Message}到{Mobile}");     } } /// <summary> /// 业务逻辑2 /// </summary> public class EmailService : IEmailService {     public string Email { get; set; }     public string Message { get; set; }      public EmailService(string email, string message)     {         Email = email;         Message = message;     }      public virtual void Send()     {         Console.WriteLine($"已发送邮件:{Message}到{Email}");     } } /// <summary> /// 代理1:任意标准 /// </summary> public class ShareInterceptor1 : IInterceptor {     public void Intercept(IInvocation invocation)     {         Console.WriteLine("Proxy1:已对接收方进行验证");         invocation.Proceed();//执行下一个拦截器或者目标方法         Console.WriteLine("Proxy1:已确认对方已经收到");     } } /// <summary> /// 代理2:任意标准 /// </summary> public class ShareInterceptor2 : IInterceptor {     public void Intercept(IInvocation invocation)     {         Console.WriteLine("Proxy2:已开启加速通道");         invocation.Proceed();//执行下一个拦截器或者目标方法         Console.WriteLine("Proxy2:已关闭加速通道");     } } //通过Castel生成代理类 public static void TestDynamicProxy1() {     //创建代理生成器     var generator = new ProxyGenerator();     var target1 = new PhoneService("10088", "你好啊!");     var target2 = new EmailService("1123@116.com", "你好啊!");     var interceptor1 = new ShareInterceptor1();//代理1,拦截器1,不需要去实现指定的标准     var interceptor2 = new ShareInterceptor2();//代理2,拦截器2,不需要去实现指定的标准     //使用代理1和代理2去代理手机的标准     IPhoneService dynamicProxy1 = generator.CreateInterfaceProxyWithTarget<IPhoneService>(target1, interceptor1, interceptor2);     dynamicProxy1.Send();     //代理邮件的标准     IEmailService dynamicProxy2 = generator.CreateInterfaceProxyWithTarget<IEmailService>(target2, interceptor1, interceptor2);     dynamicProxy2.Send(); }  

手写Castle.Core的代理类

思考:

generator创建的是什么类型的实列?显然不可能是已有的类型。因为它把拦截器织入进去了。而且没有修改我们的代码,站在面向对象的角度来看只能是实现了我们的接口,Emit动态实现了下面的代码

多个拦截器和目标对象(被代理者)通过Invocation进行串联。Invocation中的Arguments完成链式调用。

手动通过Invocation进行串联

//假设有三个拦截器 //第一个拦截器invocation1:Proxy=interceptor2,Method=Intercept,argument=invocation2 //第二个拦截器invocation2:Proxy=interceptor3,Method=Intercept,argument=invocation3 //第三个拦截器invocation2:Proxy=target,Method=method,argument=arguments //手动实现 public IInvocation GetInvocation(Stack<IInterceptor> stack, object target, Method method, objuect arguments) {     var invocation1 = new Invocation()     {         Proxy = interceptor2,         Method = typeof(IInterceptor).GetMethod(nameof(IInterceptor.Intercept)),         Arguments = new object[]         {             new Invocation()             {                 Proxy = interceptor3,                 Method = typeof(IInterceptor).GetMethod(nameof(IInterceptor.Intercept)),                 Arguments = new object[]                 {                     new Invocation()                     {                         Proxy = target,                         Method = method,                         Arguments = arguments                     }                   }             }         }      } }  //递归实现 public IInvocation GetInvocation(Stack<IInterceptor> stack, object target, Method method, objuect arguments) {     if(stack.Any())     {         var proxy = stack.Pop();         return new Invocation()         {           	Proxy = proxy,              Method = typeof(IInterceptor).GetMethod(nameof(IInterceptor.Intercept)),             Agrumtns = GetInvocation(stack,method,argumtns)         };     }     else      {         return new Invocation()         {           	Proxy = target,              Method = method,             Agrumtns = arguments         };     } } 
 //Castel.Core自动帮我们生成了下面这个类 public class CastelPhoneServiceProxy : IPhoneService {     private IPhoneService _taget;     private IInterceptor[] _interceptors;      public CastelPhoneServiceProxy(IPhoneService taget, IInterceptor[] interceptors)     {         _taget = taget;         _interceptors = interceptors;     }      public string Mobile { get => _taget.Mobile; set => _taget.Mobile = value; }     public string Message { get => _taget.Message; set => _taget.Message = value; }      public void Send()     {         var stack = new Stack<IInterceptor>(_interceptors.Reverse());         if (stack.Any())         {             var item = stack.Pop();             var invocation = GetNextInvocation(stack);             item.Intercept(invocation);         }         else         {             _taget.Send();         }     }     /// <summary>     /// 递归获取Invocaltion     /// </summary>     /// <param name="stack"></param>     /// <returns></returns>     private IInvocation GetNextInvocation(Stack<IInterceptor> stack)     {         if (stack.Any())         {             var next = stack.Pop();             return new Invocaltion             {                 Arguments = new object[]                 {                     //递归                     GetNextInvocation(stack)                 },                 Proxy = next,                 Method = typeof(IInterceptor).GetMethod(nameof(IInterceptor.Intercept)) ?? throw new NullReferenceException()             };         }         else         {             return new Invocaltion             {                 Arguments = new object[]                 {                  },                 Proxy = _taget,                 Method = _taget.GetType().GetMethod(nameof(IPhoneService.Send)) ?? throw new NullReferenceException()             };         }     } } //实现一些castle.core的接口 public class Invocaltion : IInvocation {     public object[] Arguments { get; set; }      public Type[] GenericArguments { get; set; }      public object InvocationTarget { get; set; }      public MethodInfo Method { get; set; }      public MethodInfo MethodInvocationTarget { get; set; }      public object Proxy { get; set; }      public object ReturnValue { get; set; }      public Type TargetType { get; set; }      public IInvocationProceedInfo CaptureProceedInfo()     {         throw new NotImplementedException();     }      public object GetArgumentValue(int index)     {         throw new NotImplementedException();     }      public MethodInfo GetConcreteMethod()     {         throw new NotImplementedException();     }      public MethodInfo GetConcreteMethodInvocationTarget()     {         throw new NotImplementedException();     }      public void Proceed()     {         Method.Invoke(Proxy, Arguments);     }      public void SetArgumentValue(int index, object value)     {         throw new NotImplementedException();     } }  

EMIT实现

//链路器 public class EmitInvocation {     private object? proxy;     private MethodInfo? method;     private object[]? arguments;     public EmitInvocation(object? proxy, MethodInfo? method, object[]? arguments)     {         this.proxy = proxy;         this.method = method;         this.arguments = arguments;     }      public void Proceed()     {         method?.Invoke(proxy, arguments);     }  } //拦截器 public interface IEmitInteceptor {     void Intercept(EmitInvocation invocation); } //实现拦截器1 public class EmitInteceptor1 : IEmitInteceptor {     public void Intercept(EmitInvocation invocation)     {         Console.WriteLine("prox1:start");         invocation.Proceed();         Console.WriteLine("prox1:end");     } } //实现拦截器1 public class EmitInteceptor2 : IEmitInteceptor {     public void Intercept(EmitInvocation invocation)     {         Console.WriteLine("prox2:start");         invocation.Proceed();         Console.WriteLine("prox2:end");     } } //该工具类帮助我们少写emit代码 public static class EmitProxyInvoker {     public static EmitInvocation GetNextInvocation(Stack<IEmitInteceptor> stack, MethodInfo method, object target, object[] arguments)     {         if (stack.Any())         {             var next = stack.Pop();             arguments = new object[]             {                  //递归                 GetNextInvocation(stack, method, target, arguments)             };             return new EmitInvocation(next, typeof(IEmitInteceptor).GetMethod(nameof(IEmitInteceptor.Intercept)), arguments);         }         else         {             return new EmitInvocation(target, method, arguments);         }     }      public static void Invoke(IEmitInteceptor[] interceptors, MethodInfo method, object target, object[] arguments)     {         var stack = new Stack<IEmitInteceptor>(interceptors.Reverse());         if (stack.Any())         {             var item = stack.Pop();             var invocation = GetNextInvocation(stack, method, target, arguments);             item.Intercept(invocation);         }         else         {             method.Invoke(target, arguments);         }     } } //业务接口 public interface IEmitService {     void Send(); } //将来要生成的代理类 public class EmitServiceProxy : IEmitService {     private object _target;     private IEmitInteceptor[] _inteceptors;      public EmitService()     {      }      public void Send()     {         var method = _target.GetType().GetMethod(nameof(EmitService.Send));         var arguments = new object[] { };         EmitProxyInvoker.Invoke(_inteceptors, method, _target, new object[] { });     } }  public static class EmitProxyGenerator {     static AssemblyBuilder _assemblyBuilder;     static ModuleBuilder _moduleBuilder;     static EmitProxyGenerator()     {         //创建一个程序集         var assemblyName = new AssemblyName("DynamicProxies");         _assemblyBuilder = AssemblyBuilder             .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);         //创建一个模块         _moduleBuilder = _assemblyBuilder.DefineDynamicModule("Proxies");     }     public static TInterface Create<TInterface>(object target, params IEmitInteceptor[] inteceptor)         where TInterface : class     {                  #region 定义类型         //定义一个class,如果这个类型已定义直接返回,缓存         var typeName = $"{target.GetType().Name}EmitProxy";         var typeBuilder = _moduleBuilder.DefineType(             typeName,              TypeAttributes.Public,typeof(object),             new Type[]              {                  typeof(TInterface)              });         #endregion          #region 定义字段         //定义字段         var targetFieldBuilder = typeBuilder.DefineField("target", typeof(object), FieldAttributes.Private);         var inteceptorFieldBuilder = typeBuilder.DefineField("inteceptor", typeof(IEmitInteceptor[]), FieldAttributes.Private);         #endregion          #region 定义构造器         //定义构造器         var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.ExplicitThis, new Type[]         {             typeof(object),             typeof(IEmitInteceptor[])         });         //获取IL编辑器         var generator = constructorBuilder.GetILGenerator();         generator.Emit(OpCodes.Ldarg_0);//加载this         generator.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes) ?? throw new InvalidOperationException());         generator.Emit(OpCodes.Nop);         generator.Emit(OpCodes.Nop);         // this.age = age;         generator.Emit(OpCodes.Ldarg_0);//加载this         generator.Emit(OpCodes.Ldarg_1);//加载target参数         generator.Emit(OpCodes.Stfld, targetFieldBuilder);//加载target字段         // this.name = name;         generator.Emit(OpCodes.Ldarg_0);//加载this         generator.Emit(OpCodes.Ldarg_2);//加载inteceptor参数         generator.Emit(OpCodes.Stfld, inteceptorFieldBuilder);//加载inteceptor字段         generator.Emit(OpCodes.Ret);          #endregion          #region 实现接口         var methods = typeof(TInterface).GetMethods();         foreach (var item in methods)         {             var parameterTypes = item.GetParameters().Select(s => s.ParameterType).ToArray();             var methodBuilder = typeBuilder.DefineMethod(item.Name,                 MethodAttributes.Public| MethodAttributes.Final |MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.HideBySig,                 CallingConventions.Standard|CallingConventions.HasThis,                 item.ReturnType,                 parameterTypes);             var generator1 = methodBuilder.GetILGenerator();             //init             var methodInfoLocal = generator1.DeclareLocal(typeof(MethodInfo));             var argumentLocal = generator1.DeclareLocal(typeof(object[]));             generator1.Emit(OpCodes.Nop);             generator1.Emit(OpCodes.Ldarg_0);             generator1.Emit(OpCodes.Ldfld, targetFieldBuilder);             generator1.Emit(OpCodes.Callvirt, typeof(Type).GetMethod(nameof(Type.GetType),Type.EmptyTypes));             generator1.Emit(OpCodes.Ldstr, item.Name);             generator1.Emit(OpCodes.Callvirt, typeof(Type).GetMethod(nameof(Type.GetMethod), new Type[] { typeof(string) }));             generator1.Emit(OpCodes.Stloc, methodInfoLocal);             generator1.Emit(OpCodes.Ldc_I4_0);             generator1.Emit(OpCodes.Newarr, typeof(object));             generator1.Emit(OpCodes.Stloc, argumentLocal);             generator1.Emit(OpCodes.Ldarg_0);             generator1.Emit(OpCodes.Ldfld, inteceptorFieldBuilder);             generator1.Emit(OpCodes.Ldloc_0);             generator1.Emit(OpCodes.Ldarg_0);             generator1.Emit(OpCodes.Ldfld, targetFieldBuilder);             generator1.Emit(OpCodes.Ldc_I4_0);             generator1.Emit(OpCodes.Newarr, typeof(object));             generator1.Emit(OpCodes.Call, typeof(EmitProxyInvoker).GetMethod(nameof(EmitProxyUtil.Invoke)));             generator1.Emit(OpCodes.Nop);             generator1.Emit(OpCodes.Ret);         }         #endregion         //创建:这个type可以用一个线程安全的字典缓存起来,第二次需要这个代理类的时候,就不需要在生成一次emit代码了。         var type = typeBuilder.CreateType() ?? throw new ArgumentException();         var instance = Activator.CreateInstance(type, target, inteceptor);         return (TInterface)instance;     } }  

容器支持

public class DbContext {      }  public class AService {     public DbContext DbContext { get; }          public AService(DbContext context)     {         DbContext = context;     } } public static void Test() {     var services = new ServiceCollection();     services.AddScoped<DbContext>();     var generator = new ProxyGenerator();     //泛型-不支持动态注入     services.AddScoped(sp =>      {         //通过容器解析依赖         var target = ActivatorUtilities.CreateInstance<AService>(sp);         return generator.CreateClassProxyWithTarget(target);     });     //反射-可以扫描批量注入     services.AddScoped(typeof(AService), sp =>     {         //通过容器解析依赖         var target = ActivatorUtilities.CreateInstance(sp, typeof(AService));         return generator.CreateClassProxyWithTarget(target);     }); }  

管道方式

委托方式

1.通过委托构建管道

public delegate Task RequestDelegate(HttpContext context);  public class HttpContext {  }  public class ApplicationBuilder {     private readonly List<Func<RequestDelegate, RequestDelegate>> _componen      public void Use(Func<RequestDelegate, RequestDelegate> middleware)     {         _components.Add(middleware);     }      public void Use(Func<HttpContext, Func<Task>, Task> middleware)     {         _components.Add((next) =>         {             return async c =>             {                 await middleware(c, () => next(c));             };         });     }      public void Use(Func<HttpContext, RequestDelegate, Task> middleware)     {         _components.Add((next) =>         {             return async c =>             {                 await middleware(c, next);             };         });     }      public void Run(RequestDelegate handler)     {         _components.Add((next) =>         {             return async c =>             {                 await handler(c);             };         });     }     //构建管道     public RequestDelegate Build()     {         RequestDelegate app = c =>         {             throw new InvalidOperationException("无效的管道");         };         for (int i = _components.Count - 1; i > -1; i--)         {             app = _components[i](app);         }         return app;     } } 

接口方式

2.通过接口构建管道

有点类型动态代理,动态代理是通过Invocation进行反射,而下面的方式是通过接口的方式。反射更加灵活,性能不行。

public interface IChain {     Task NextAsync(); } public class FilterChain : IChain {     private readonly IFilter _filter;     private readonly HttpContext _context;     private readonly IChain _next;     public FilterChain(IFilter filter, HttpContext context, IChain next)     {         _filter = filter;         _context = context;         _next = next;     }     public async Task NextAsync()     {         await _filter.InvokeAsync(_context, _next);     } } public class ServletChain : IChain {     private readonly IServlet _servlet;     private readonly HttpContext _context;      public ServletChain(IServlet servlet, HttpContext context)     {         _servlet = servlet;         _context = context;     }      public async Task NextAsync()     {         await _servlet.DoPostAsync(_context);     } } public interface IFilter {     Task InvokeAsync(HttpContext context, IChain chain); } public class Filter1 : IFilter {     public async Task InvokeAsync(HttpContext context, IChain chain)     {         Console.WriteLine("身份认证开始");         await chain.NextAsync();         Console.WriteLine("身份认证结束");     } }  public class Filter2 : IFilter {     public async Task InvokeAsync(HttpContext context, IChain chain)     {         Console.WriteLine("授权认证开始");         await chain.NextAsync();         Console.WriteLine("授权认证结束");     } }  public interface IServlet {     Task DoPostAsync(HttpContext context); }  public class HelloServlet : IServlet {     public Task DoPostAsync(HttpContext context)     {         Console.WriteLine("Hello World");         return Task.CompletedTask;     } }  public class WebHost {     private readonly List<IFilter> _filters = new List<IFilter>();      public void AddFilter(IFilter filter)     {         _filters.Add(filter);     }      public void Exeucte(HttpContext context, IServlet servlet)     {         //自行处理filter为空的情况,就是直接执行serlvet就好了         var stack = new Stack<IFilter>(_filters);         var filter = stack.Pop();         var chain = GetFilterChain(context, servlet,stack);         filter.InvokeAsync(context, chain);     }      private IChain GetFilterChain(HttpContext context, IServlet servlet, Stack<IFilter> filters)     {         if (filters.Any())         {             var filter = filters.Pop();             var chain = GetFilterChain(context, servlet, filters);             return new FilterChain(filter, context, chain);         }         else         {             return new ServletChain(servlet, context);         }     } }  

AOP总结

1.代理分为静态代理和动态代理,静态代理需要自己编写代理类,动态代理由框架生成代理类。

2.代理和管道都需要通过接口(委托)进行链接,串联,形成链式调用。

3.动态代理慎用,因为涉及到反射技术,而且对异步支持不友好。

4.静态代理常用于加强已有类型,比如接口要求一个IList,我们已经拥有了一个list实列,我们需要在在list.Add方法时打印日志,此时我们可以不改变原有的list,通过静态代理实现IList接口来进行对原有的list加强。这个方法在更改框架的时候很有用。我们可以对原有的HttpContext,进行加强。