jdk动态代理的实现原理

本文详细介绍了Java动态代理的实现过程,包括创建接口、实现类、InvocationHandler以及测试代码,展示了如何通过Proxy类生成代理实例。同时,讨论了Spring中的通知机制,并在InvocationHandler的invoke方法中模拟了前置、环绕和后置通知的逻辑。文章指出,由于Java的单继承特性,JDK动态代理仅适用于实现了接口的类。
摘要由CSDN通过智能技术生成

         先写一个jdk动态代理的例子

        1.先定义一个接口

         

public interface MyService {

    void print();
}

        2.定义一个实现类

public class MyServiceImpl implements MyService{
    @Override
    public void print() {
        System.out.println("原始方法");
    }
}

      3.实现InvocationHandler接口,实现增强逻辑

  

public class JdkInvocation implements InvocationHandler {

    private Object object;

    public JdkInvocation(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("处理前");
        Object value = method.invoke(object, args);
        System.out.println("处理后");
        return value;
    }
}

       4.测试

public class TestProxy {

    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

        MyService myService = new MyServiceImpl();
        MyService proxy = (MyService) Proxy.newProxyInstance(myService.getClass().getClassLoader(), new Class[] {MyService.class}
        , new JdkInvocation(myService));
        proxy.print();
    }
}

      5.查看生成的代理类

public final class $Proxy0 extends Proxy implements MyService {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void print() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.example.demo.proxy.MyService").getMethod("print");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

   从生成的代理类的实现可以看到,代理类继承了Proxy类,并实现了我们定义的接口,其中通过构造方法将我们实现InvocationHandler接口的增强类注入进去。

  1.因为java是单继承的,所以jdk动态代理只能适用于实现了接口的类。

  2.spring中是如何实现通知的

     

public class JdkInvocation implements InvocationHandler {

    private Object object;

    public JdkInvocation(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object value = null;
        //beforeAdvise(前置通知)
        try {
            //aroundAdvise(环绕通知)
            value = method.invoke(object, args);
            //aroundAdvise(环绕通知)
            System.out.println("处理后");
        }catch (Throwable t) {
            //afterThrowingAdvise(异常通知)
        }finally {
            //afterReturningAdvise(返回值通知)
        }
        return value;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值