Dynamic Proxy

本文通过示例详细解析了Java动态代理的实现原理,展示了如何利用ProxyGenerator生成代理类,并提供了具体的代码实现。

对于Dynamic Proxy的原理,很多地方都有介绍,里面最神秘的就是JVM会在运行时动态生成一个类,好奇心驱使,想看看这个生成的类的代码是啥样的。于是,跟踪到Proxy.newProxyInstance()中,发现生成代码的关键语句byte[] ProxyGenerator.generateProxyClass(String proxyname,Class[] instances),写了段代码来输出那个类文件,并得到反编译的结果
----------IPerson .java-----------
package cn.edu.tju.bme;

public interface IPerson {

   public void insertPerson();
    public String getPersonName();
}
----------TestInvocationHandler.java-----------
package cn.edu.tju.bme;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TestInvocationHandler implements InvocationHandler {

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        return null;
    }
}
------------Main.java-----------
package cn.edu;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;

import sun.misc.ProxyGenerator;

import cn.edu.tju.bme.IPerson;
import cn.edu.tju.bme.TestInvocationHandler;

public class Main {
    public static void main(String[] args) throws IOException {
        String proxyName = "proxyName";
        InvocationHandler handler = new TestInvocationHandler();
        byte[] proxyClassFile =    ProxyGenerator.generateProxyClass(  proxyName, new Class[]{IPerson.class});
        FileOutputStream fos = new FileOutputStream(new File("D://ProxyName.class"));
        fos.write(proxyClassFile);
        fos.flush();
        fos.close();
    }
}
---------------------------
反编译生成的ProxyName.class,得到的源文件如下:
----------proxyName.java-----------
import cn.edu.tju.bme.IPerson;
import java.lang.reflect.*;

public final class proxyName extends Proxy
    implements IPerson
{

    public proxyName(InvocationHandler invocationhandler)
    {
        super(invocationhandler);
    }

    public final String toString()
    {
        try
        {
            return (String)super.h.invoke(this, m2, null);
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final int hashCode()
    {
        try
        {
            return ((Integer)super.h.invoke(this, m0, null)).intValue();
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final String getPersonName ()
    {
        try
        {
            return (String)super.h.invoke(this, m4, null);
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final void insertPerson ()
    {
        try
        {
            super.h.invoke(this, m3, null);
            return;
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final boolean equals(Object obj)
    {
        try
        {
            return ((Boolean)super.h.invoke(this, m1, new Object[] {
                obj
            })).booleanValue();
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    private static Method m2;
    private static Method m0;
    private static Method m4;
    private static Method m3;
    private static Method m1;

    static
    {
        try
        {
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
            m4 = Class.forName("cn.edu.tju.bme.IPerson").getMethod("getPersonName", new Class[0]);
            m3 = Class.forName("cn.edu.tju.bme.IPerson").getMethod("insertPerson", new Class[0]);
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
                Class.forName("java.lang.Object")
            });
        }
        catch(NoSuchMethodException nosuchmethodexception)
        {
            throw new NoSuchMethodError(nosuchmethodexception.getMessage());
        }
【SCI一区论文复】基于SLSPC系列的高阶PT-WPT无线电能传输系统研究(Matlab代码实现)内容概要:本文围绕“基于SLSPC系列的高阶PT-WPT无线电能传输系统研究”展开,重点复现SCI一区论文中的核心技术,通过Matlab代码实现高阶无线电能传输系统的建模与仿真。研究聚焦SLSPC拓扑结构在恒压-恒流(CV/CC)输出特性方面的优势,深入分析系统的传输效率、耦合特性、频率分裂现象及参数敏感性,并探讨其在高功率、长距离无线充电场景中的应用潜力。文中详细给出了系统数学建模、参数设计、仿真验证等关键步骤,旨在帮助读者掌握先进无线电能传输技术的核心原理与实现方法。; 适合人群:具备一定电力电子、自动控制理论基础,熟悉Matlab/Simulink仿真工具,从事无线电能传输、新能源充电技术等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①深入理解SLSPC型无线电能传输系统的恒压恒流输出机理;②掌握高阶WPT系统的建模、仿真与性能分析方法;③复现SCI一区论文成果,为后续科研创新提供技术基础和代码参考;④应用于无线充电、电动汽车、植入式医疗设备等领域的系统设计与优化。; 阅读建议:建议读者结合Matlab代码逐段分析系统模型构建过程,重点关注谐振参数设计、传输特性仿真及效率优化策略,同时可拓展研究不同耦合条件下的系统行为,以深化对高阶WPT系统动态特性的理解。
### DynamicProxy 的简介 DynamicProxy 是由 Castle Project 提供的一个强大的动态代理库,用于在运行时生成代理对象并拦截方法调用。它广泛应用于 AOP(面向切面编程)、日志记录、性能监控以及事务管理等领域。 通过 `Castle.DynamicProxy` 库,开发者可以轻松实现对目标类或接口的方法调用进行拦截和扩展功能[^1]。 --- ### 动态代理的核心概念 #### 1. **代理生成** 动态代理允许在不修改原始代码的情况下,为目标对象创建一个代理实例。这个代理可以在方法执行前后插入自定义逻辑。 例如: ```csharp var proxy = new ProxyGenerator() .CreateClassProxy<MyClass>(new Interceptor()); proxy.Flag = true; proxy.Execute(); ``` 上述代码展示了如何使用 `ProxyGenerator` 创建一个针对 `MyClass` 类型的代理,并传入了一个名为 `Interceptor` 的拦截器[^1]。 #### 2. **拦截器机制** 拦截器是一个实现了 `IInterceptor` 接口的对象,负责捕获被代理方法的调用过程。以下是典型的拦截器实现方式: ```csharp public class MyInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine($"Before calling {invocation.Method.Name}"); // 调用实际的目标方法 invocation.Proceed(); Console.WriteLine($"After calling {invocation.Method.Name}"); } } ``` 当某个方法被调用时,拦截器会先执行其内部逻辑(如打印日志),再通过 `invocation.Proceed()` 执行原生方法[^3]。 --- ### 配合 Autofac 使用 `Autofac.Extras.DynamicProxy` 是基于 `Castle.DynamicProxy` 构建的一个扩展包,旨在简化依赖注入框架中的动态代理集成。以下是如何配置 Autofac 来支持动态代理的功能: #### 注册拦截器 首先注册拦截器到容器中: ```csharp builder.RegisterType<UnitOfWorkIInterceptor>(); ``` #### 对服务启用拦截 接着为特定的服务类型启用拦截功能: ```csharp builder.RegisterAssemblyTypes(assemblies) .Where(t => typeof(IAppService).IsAssignableFrom(t) && !t.IsAbstract) .AsImplementedInterfaces() .InstancePerLifetimeScope() .InterceptedBy(typeof(UnitOfWorkIInterceptor)) .EnableInterfaceInterceptors(); ``` 此段代码表示:对于所有继承了 `IAppService` 并非抽象类型的类,都会自动应用 `UnitOfWorkIInterceptor` 拦截器[^3]。 --- ### 异步方法的支持 `Castle.DynamicProxy` 支持拦截异步方法,但需要注意一些细节。例如,如果要拦截返回 `Task<T>` 的方法,则应在拦截器中正确处理任务完成状态。下面是一段示例代码展示如何安全地拦截异步操作: ```csharp public async Task InterceptAsyncMethod(IInvocation invocation) { try { await (Task)invocation.Method.Invoke(invocation.Proxy, invocation.Arguments); } catch (Exception ex) { Console.WriteLine($"Error occurred: {ex.Message}"); throw; } } ``` 注意这里直接调用了反射来触发异步方法的实际执行流程[^3]。 --- ### 总结 `Castle.DynamicProxy` 提供了一种灵活的方式来增强现有业务逻辑而无需侵入原有代码结构。无论是简单的属性访问还是复杂的跨线程场景下的异常捕捉,都可以借助该工具箱达成目的。同时配合像 Autofac 这样的 DI 容器能够进一步提升开发效率与维护便利性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值