美文网首页
九、spring aop之jdk动态代理

九、spring aop之jdk动态代理

作者: xiaoming_he | 来源:发表于2018-07-09 23:57 被阅读0次

使用

动态代理有两个对象,目标对象和代理对象。使用JDK动态代理,目标对象必须实现一个接口。

public class JdkDynamicProxyTest {

    interface IPerson {
        void say() ;
    }

    static class Person implements IPerson {
        @Override
        public void say() {
            System.out.println("hello world");
        }
    }

    static class JdkProxy implements InvocationHandler {

        //目标对象
        private Object target;

        //得到代理对象
        public Object getProxy(Object target) {
            this.target = target;
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(), this);
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("say before");
            method.invoke(target, args);
            System.out.println("say after");
            return null;
        }
    }

    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        JdkProxy jdkProxy = new JdkProxy();
        IPerson person = (IPerson) jdkProxy.getProxy(new Person());
        person.say();
    }
}

原理

要查看JDK动态代理原理,只需要在运行的时候,增加下面一句话:

 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

会在项目路径下生成一个$Proxy0.class文件,反编译这个文件,就能够明白JDK动态代理原理。

final class $Proxy0 extends Proxy implements IPerson {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    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 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 void say() throws  {
        try {
            super.h.invoke(this, m3, (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"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.ming.aop.IPerson").getMethod("say");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

代理的大概结构包括4部分:
静态字段:被代理的接口所有方法都有一个对应的静态变量;
静态块:主要是通过反射初始化静态变量;
具体每个代理方法:逻辑都差不多就是 h.invoke,h是Proxy的属性。主要是调用我们定义好的invocatinoHandler逻辑,触发目标对象target上对应的方法;

public class Proxy implements java.io.Serializable {
    protected InvocationHandler h;
}

构造函数:从这里传入我们InvocationHandler逻辑;构造函数在newProxyInstance方法中通过反射调用。

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

protected Proxy(InvocationHandler h) {
    Objects.requireNonNull(h);
    this.h = h;
}

相关文章

  • Spring之使用XML配置Spring AOP

    1.aop的原理 Spring AOP底层主要使用了JDK动态代理和cglib动态代理。具体可看文章设计模式之代理...

  • java动态代理

    目录: 简介 jdk动态代理 cglib动态代理 jdk动态代理与cglib的区别 应用spring的aop 简介...

  • Spring AOP DefaultAdvisorAutoPro

    Spring AOP源码目录 Spring AOP源码01:Jdk动态代理底层源码Spring AOP源码02:P...

  • 2018-09-16

    AOP的XML配置: AOP的先关术语: Spring底层的AOP实现原理 动态代理: JDK动态代理:只能对实现...

  • JDK动态代理和CGLIB动态代理的区别

    Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理: JDK动态代理只提供接口的代...

  • Spring AOP

    Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被...

  • 说说 Spring AOP 的底层实现技术(JDK 与 CGLi

    Spring AOP 使用了两种代理机制: 基于 JDK 的动态代理(接口代理)。 基于 CGLib 的动态代理(...

  • AOP代理:

    AOP代理:AOP框架创建的对象,代理就是对目标对象的增强。Spring中的AOP代理可以是JDK动态代理,也可以...

  • Spring Boot 2.5.x能支持Java 17了 - c

    在 Spring Framework 中,AOP 代理是 JDK 动态代理或 CGLIB 代理。 ASM 是 Ja...

  • 5.4 Spring AOP架构

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

网友评论

      本文标题:九、spring aop之jdk动态代理

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