• AOP学习基于Emit和Attribute的简单AOP实现


    关于AOP的介绍,园子里曾经有段时间非常热。

    我也看了很多AOP相关的文章,对AOP的概念有一定的了解,觉得园子里的大牛张逸的AOP介绍很不错:AOP技术基础

    看了很多AOP的介绍之后,很想自己实现一个简单的AOP来感受一下,但是一直苦于不知道怎么实现。

    后来看了园子里的一个介绍Emit的系列(Emit学习系列文章导航),才开始在原作者的基础上实现了简单的AOP框架,仅供学习使用。

    1. ThinAOP的介绍

    此框架非常简单,只有几个文件。但是就是因为简单,所以可以用来学习AOP的思想。

    由于主要部分是有Emit实现的,所以没有Emit基础的话,最好先看一下Emit学习系列文章导航

    具体结构如下:

    image

    2. ThinAOP的介绍-ProxyFactory

    之所以先介绍ProxyFactory,是因为ProxyFactory是ThinAOP对外的接口,对于需要使用AOP的类,需要使用ProxyFactory来生成相应的代理类。

    ProxyFactory类中只有一个静态方法,就是用来生成动态代理类的。

        public class ProxyFactory
        {
            public static T CreateProxy<T>(Type realProxyType)
            {
                var generator = new DynamicProxyGenerator(realProxyType, typeof(T));
                Type type = generator.GenerateType();
    
                return (T)Activator.CreateInstance(type);
            }
        }

    3. ThinAOP的介绍-Metadata

    Metadata中定义了四个类:

    • ExceptionMetadata:用于保存程序中exception的信息
    • MethodMetadata   :用于保存程序中方法的信息(目前只有方法名)
    • ParameterMetadata:用于保存程序中方法的参数信息
    • ResultMetadata:用于保存程序中方法的返回值信息

    通过上面定义的四个类,我们可以看出此AOP框架值主要是针对方法这个级别的拦截。即拦截方法在执行前,执行后,异常时的操作。

    这四个类非常简单,只是定义了一些属性。

    4. ThinAOP的介绍-InvokeContext

    保存了必须的上下文信息,也就是上面定义的那些Metadata

    5. ThinAOP的介绍-DynamicProxyGenerator

    这个类是整个框架的核心,用来生成动态代理,在代理中完成对方法的拦截操作,并在拦截后注入自己的代码。

    核心方法是GenerateType,根据现有type生成新的type

            public Type GenerateType()
            {
                // 构造程序集
                BuildAssembly();
                // 构造模块
                BuildModule();
                // 构造类型
                BuildType();
                // 构造字段
                BuildField();
                // 构造函数
                BuildConstructor();
                // 构造方法
                BuildMethods();
    
                Type type = _typeBuilder.CreateType();
                // 将新建的类型保存在硬盘上(如果每次都动态生成,此步骤可省略)
                _assemblyBuilder.Save(AssemblyFileName);
                return type;
            }

    其中的Emit代码,我已经写了相应的C#代码。

    Emit代码类似IL,我也是先写C#代码,然后用ILSpy转成IL代码,然后参照IL代码来写的Emit部分代码。

    6. ThinAOP的介绍-AspectAttribute

    这个类定义了一系列的Attribute,方便于定义拦截操作。

    主要定义了3中拦截操作:分别是执行前拦截 ,执行后拦截,异常时拦截

        [AttributeUsage(AttributeTargets.Method)]
        public abstract class PreAspectAttribute : AspectAttribute
        {
        }
    
        [AttributeUsage(AttributeTargets.Method)]
        public abstract class PostAspectAttribute : AspectAttribute
        {
        }
    
        [AttributeUsage(AttributeTargets.Method)]
        public abstract class ExceptionAspectAttribute : AspectAttribute
        {
        }

    PS.

    整个框架的实现参考了博客园里很多文章,这里就不一一列举了。

    除了ThinAOP的框架外,我还写了了一个使用这个框架的例子,具体请参见提供的附件:ThinAOP

  • 相关阅读:
    Java中的List转换成JSON报错(一)
    关于侦听的注册
    TCMalloc小记
    ocp|ocm考证系列文章
    开源HTML5 APP开发神器CanTK发布
    实例级别的回滚
    MySQL查询所有数据库表出错
    java.lang.ArrayIndexOutOfBoundsException
    如何修改64位Eclipse中的代码字体大小
    gpt 分区容量错误
  • 原文地址:https://www.cnblogs.com/wang_yb/p/2133405.html
Copyright © 2020-2023  润新知