zoukankan      html  css  js  c++  java
  • 【Autofac打标签模式】Aspect拦截器

    【 Autofac打标签模式】开源DI框架扩展地址:

    https://github.com/yuzd/Autofac.Annotation/wiki

    前提条件

    自己new一个对象不能实现拦截器功能,必须得从DI容器拿到的对象才能具备拦截器功能 可以参考 我写的文章介绍

    拦截器原理简单介绍

    用了Castle.Core组件 把你想要实现拦截器的目标类生成一个代理类。 然后织入拦截器,有2种方式

    1. class + 方法为virtual的方式
      • 这种方式需要 从容器中是根据一个classType来获取到目标实例
    2. interface + 方法重写的方式
      • 这种方式需要 从容器中是根据一个interfaceType来获取到目标实例

    拦截器开关

    在你想要实现拦截的目标类上打上 【Aspect】标签,如上面的解释,Aspect标签可以根据InterceptorType属性值设定你是哪种方式的拦截器

    InterceptorType属性解释
    Class 使用class的虚方法模式 【默认方式】
    Interface 使用接口模式

    目的是打个标签就能够拦截目标方法

    使得我们自定义的方法能够

    • 在指定的目标方法执行之前先执行(比如参数校验)
    • 或者在指定的目标方法执行之后执行(比如说检验返回值,或其他收尾工作)
    • 或者环绕目标的方法,比如事务:TransactionScope或者记录方法执行的时间
    拦截器标签拦截器类型使用说明
    AspectBeforeAttribute(抽象标签类) 前置拦截器 重写Before方法
    AspectAfterAttribute(抽象标签类) 后置拦截器 重写After方法
    AspectAroundAttribute(抽象标签类) 前置+后置拦截器 重写Before和重写After方法
    PointcutAttribute(抽象标签类) 环绕拦截器 重写OnInvocation方法

    拦截器的方法参数 AspectContext 属性说明

    名称说明
    ComponentContext DI容器,可以从中取得你已注册的实例
    InvocationContext 执行上下文,例如被拦截的MethodInfo ,Name, Parameters,ReturnType等
    Exception 异常信息,这个在前置拦截器是肯定为null,在后置拦截器中如果被拦截的方法出现了异常就能通过这个字段拿到异常信息

    Exception说明

    前置拦截器若抛了没有被catch住的异常

    • 如果有后置拦截器,可以在AspectContext的Exception字段获取。
    • 如果没有后置拦截器则抛出

    前置拦截器

    1. 首先要自己写一个类继承 前置拦截器AspectBeforeAttribute(抽象标签类)
    2. 实现该抽象类的Before方法

    image

    1. 然后在被拦截方法的所在类上打上 【Aspect】标签;

    2. 被拦截方法上打上 【TestHelloBefor】标签

    3. 被拦截方法需要有 virtual 关键字

    image

    前置拦截器方法的执行顺序为:先执行 TestHelloBefor的Before方法再执行你的Say方法

    后置拦截器

    1. 首先要自己写一个类继承后置拦截器AspectAfterAttribute(抽象标签类)
    2. 实现该抽象类的After方法

    image

    1. 然后在被拦截方法的所在类上打上 【Aspect】标签;

    2. 被拦截方法上打上 【TestHelloAfter】标签

    3. 被拦截方法需要有 virtual 关键字

    image

    后置拦截器方法的执行顺序为:先执行你的SayAfter方法再执行 TestHelloAfter的After方法

    前置+后置拦截器

    1. 首先要自己写一个类继承拦截器AspectAroundAttribute(抽象标签类)
    2. 实现该抽象类的Before 和 After方法

    image

    1. 然后在被拦截方法的所在类上打上 【Aspect】标签;

    2. 被拦截方法上打上 【TestHelloArround】标签

    3. 被拦截方法需要有 virtual 关键字

    image

    方法的执行顺序为:

    1. 先执行TestHelloArround的Before方法
    2. 然后执行你的SayArround方法
    3. 再执行 先执行TestHelloArround的After方法

    环绕拦截器的前置+后置的另外一种方式(更灵活)

    注意:OnInvocation方法除了AspectContext参数以外 还有一个 AspectDelegate _next 参数, 如果只有一个环绕拦截器的话,那么这个参数就是被拦截方法的本体, 如果有多个环绕拦截器的话,那么最后一个就是被拦截方法的本体。

    1. 首先要自己写一个类继承拦截器PointcutAttribute(抽象标签类)
    2. 实现该抽象类的OnInvocation方法

    image

    1. 然后在被拦截方法的所在类上打上 【Aspect】标签;

    2. 被拦截方法上打上 【TransactionInterceptor】标签

    3. 被拦截方法需要有 virtual 关键字

    image

    方法的执行顺序为:

    1. 先执行TransactionInterceptor的OnInvocation方法
    2. 然后TransactionInterceptor的OnInvocation方法里面执行的 await _next(aspectContext); 就会执行被拦截方法TestInterceptor;

    如果有多个环绕拦截器的话,如下图:

    image

    image

    如上图 代码的执行顺序为:

    image

  • 相关阅读:
    自动布局
    初探 iOS8 中的 Size Class
    iOS数据安全性问题
    iOS应用程序之间的跳转
    iOS 关于xml解析的问题
    iOS中的一些基础知识点
    关于iOS项目中使用ZBarSDK
    iOS中关于google地图的用法
    基于4.5Framework web程序、SQLSERVER数据库打包
    docker私有仓库搭建
  • 原文地址:https://www.cnblogs.com/yudongdong/p/11747235.html
Copyright © 2011-2022 走看看