美文网首页dotnet coreAmazing .NETdotNET
.NET 下基于动态代理的 AOP 框架实现揭秘

.NET 下基于动态代理的 AOP 框架实现揭秘

作者: 天天向上卡索 | 来源:发表于2020-04-16 17:00 被阅读0次

.NET 下基于动态代理的 AOP 框架实现揭秘

Intro

之前基于 Roslyn 实现了一个简单的条件解析引擎,想了解的可以看这篇文章 https://www.cnblogs.com/weihanli/p/roslyn-based-condition-eval-engine.html

执行过程中会根据条件的不同会在运行时创建一个类,每一次创建都会生成一个新的程序集,我觉得这样实现的话可能会导致加载的程序集越来越多,虽然目前我们的使用场景下不会有很多,而且相同的条件只会生成一次,还是觉得这样不是特别好,此时想起来了一些 AOP 框架,Aspect.Core/Castle/DispatchProxy ,他们这些 AOP 框架会生成一些代码类,好像也没有生成很多额外的程序集,于是打算看看这些 AOP 框架的实现,看看它们是如何生成动态代理类的

动态代理实现原理

看了这三个 AOP 框架的实现代码之后,实现原理基本都是一样的

都是通过创建一个 DynamicAssembly 之后在这个 DynamicAssemly 中创建要动态生成代理类,通过 Emit 创建要生成动态代理类的方法/属性等

来个小示例

多说不如来点代码示例:

internal class ProxyUtil
{
    private const string ProxyAssemblyName = "Aop.DynamicGenerated";
    private static readonly ModuleBuilder _moduleBuilder;
    private static readonly ConcurrentDictionary<string, Type> _proxyTypes = new ConcurrentDictionary<string, Type>();

    static ProxyUtil()
    {
        // 定义一个动态程序集
        var asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(ProxyAssemblyName), AssemblyBuilderAccess.Run);
        // 创建一个动态模块,后面创建动态代理类通过这个来创建
        _moduleBuilder = asmBuilder.DefineDynamicModule("Default");
    }

    public static Type CreateInterfaceProxy(Type interfaceType)
    {
        var proxyTypeName = $"{ProxyAssemblyName}.{interfaceType.FullName}";
        var type = _proxyTypes.GetOrAdd(proxyTypeName, name =>
        {
            // 定义要创建的类型,并实现指定类型接口
            var typeBuilder = _moduleBuilder.DefineType(proxyTypeName, TypeAttributes.Public, typeof(object), new[] { interfaceType });
            // 定义一个默认的构造方法
            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
            // 获取接口中定义的方法
            var methods = interfaceType.GetMethods(BindingFlags.Instance | BindingFlags.Public);
            foreach (var method in methods)
            {
                // 在动态类中定义方法,方法名称,返回值和签名与接口方法保持一致
                var methodBuilder = typeBuilder.DefineMethod(method.Name
                    , MethodAttributes.Public | MethodAttributes.Virtual,
                    method.CallingConvention,
                    method.ReturnType,
                    method.GetParameters()
                        .Select(p => p.ParameterType)
                        .ToArray()
                    );                

                // 获取 ILGenerator,通过 Emit 实现方法体
                var ilGenerator = methodBuilder.GetILGenerator();
                ilGenerator.EmitWriteLine($"method [{method.Name}] is invoking...");
                ilGenerator.Emit(OpCodes.Ret);
                
                // 定义方法实现
                typeBuilder.DefineMethodOverride(methodBuilder, method);
            }

            return typeBuilder.CreateType();
        });
        return type;
    }
}

通过上面的定义我们可以创建一个简单的代理类,然后定义一个 ProxyGenerator 来创建代理

public class ProxyGenerator
{
    public static readonly ProxyGenerator Instance = new ProxyGenerator();

    public object CreateInterfaceProxy(Type interfaceType)
    {
        var type = ProxyUtil.CreateInterfaceProxy(interfaceType);
        return Activator.CreateInstance(type);
    }
}
// 定义泛型扩展
public static class ProxyGeneratorExtensions
{
    public static TInterface CreateInterfaceProxy<TInterface>(this ProxyGenerator proxyGenerator) =>
        (TInterface)proxyGenerator.CreateInterfaceProxy(typeof(TInterface));
}

使用示例:

var testService = ProxyGenerator.Instance.CreateInterfaceProxy<ITestService>();
testService.Test();
image image

可以看到这个类型就是我们动态创建的一个类型,输出结果也是我们定义在代理类中的结果

More

.NET 中的基于动态代理的 AOP 也是这样实现的,实现的原理大致就是这样,这个示例比较简单还没有涉及 AOP ,这只是一个简单的动态代理示例 ,AOP 只需要在原始方法执行的逻辑上包装一层拦截器增加对拦截器的处理和调用即可,暂时还没实现,后面有机会再分享

Reference

相关文章

  • .NET 下基于动态代理的 AOP 框架实现揭秘

    .NET 下基于动态代理的 AOP 框架实现揭秘 Intro 之前基于 Roslyn 实现了一个简单的条件解析引擎...

  • 实现一个简单的基于动态代理的 AOP

    实现一个简单的基于动态代理的 AOP Intro 上次看基于动态代理的 AOP 框架实现,立了一个 Flag, 自...

  • Spring AOP 实现原理

    Spring AOP 实现原理 静态代理 众所周知 Spring 的 AOP 是基于动态代理实现的,谈到动态代理就...

  • Spring AOP内部调用失效问题

    Spring AOP基本原理 Spring AOP是基于动态代理机制实现的,通过动态代理机制生成目标对象的代理对象...

  • Spring AOP 与 AspectJ

    spring AOP 基于代理(Proxy)的方式实现AOP实现的方式是运行时代理具体细节可以参考JDK动态代理[...

  • Spring AOP详解

    AOP AOP的实现一般都是基于 代理模式 ,在JAVA中采用JDK动态代理模式,但是我们都知道,JDK动态代理模...

  • Spring中AOP的特性解析

    要了解Spring的AOP就必须要了解动态代理的原理,因为AOP就是基于动态代理实现的。 java.lang....

  • 带你初识Java的代理模式

    Spring AOP是基于动态代理设计模式实现的,相对的就有静态代理 动态代理和静态代理 静态代理 对于静态代理,...

  • Java动态代理简析原理

    说下Java动态代理,Spring的AOP就是基于Java的动态代理实现的。动态代理用到的几个类和接口,Proxy...

  • 5.4 Spring AOP架构

    Spring AOP的核心架构基于代理。ProxyFactory spring代理两种实现 JDK动态实现(spr...

网友评论

    本文标题:.NET 下基于动态代理的 AOP 框架实现揭秘

    本文链接:https://www.haomeiwen.com/subject/kildvhtx.html