zoukankan      html  css  js  c++  java
  • jdk动态代理

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

    • JDK动态代理:其代理对象必须是某个接口的实现,他是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
    • CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生产的代理对象是针对目标类扩展的子类,CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强

    代码示例:

    /**
     * jdk动态代理示例
     */
    public class JdkProxy {
        //定义要被代理的接口
        static interface Subject {
            public void Sayhello();
        }
    
        //定义被代理的接口的实现类
        static class SubjectImp implements Subject {
            public void Sayhello() {
                System.out.print("hello");
            }
        }
    
        //定义被代理接口的处理器类
        static class ProxyHandle implements InvocationHandler {
            private Subject target;
    
            public ProxyHandle(Subject target) {
                this.target = target;
            }
    
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object o = method.invoke(target, args);
                System.out.print(" mayu");
                return o;
            }
        }
    
        public static void main(String[] args) {
            System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
            Subject subject = new SubjectImp();
            //生成代理对象
            Subject subjectProxy = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), new ProxyHandle(subject));
            subjectProxy.Sayhello();
        }
    }

    运行结果:hello mayu

    查看生成的代理类加上System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true"),在项目的根路径上可以找到代理类,如下:

    final class $Proxy0 extends Proxy implements Subject {
        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})).booleanValue();
            } 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 Sayhello() 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)).intValue();
            } 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("AOP.JdkProxy$Subject").getMethod("Sayhello");
                m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            } catch (NoSuchMethodException var2) {
                throw new NoSuchMethodError(var2.getMessage());
            } catch (ClassNotFoundException var3) {
                throw new NoClassDefFoundError(var3.getMessage());
            }
        }
    }

    原理是通过JDK字节码生成技术将给定的目标方法和处理目标方法的处理器在运行期间进行方法提取和拼装生成新的代理类。

  • 相关阅读:
    [转]C#进阶系列——WebApi 接口参数不再困惑:传参详解
    Netty中的三种Reactor(反应堆)
    I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor
    【转】第8章 前摄器(Proactor):用于为异步事件多路分离和分派处理器的对象行为模式
    mysql 数据库 自动截取数据的问题---mysql的sql_model的四种模式:宽松模式、严格模式
    spring-session之四:Spring Session下的Redis存储结构
    Mysql auto_increment总结
    mysql实战优化之一:sql优化
    mysql字符集和校对规则(Mysql校对集)
    Oracle B-tree、位图、全文索引三大索引性能比较及优缺点汇总
  • 原文地址:https://www.cnblogs.com/ll9507/p/11297278.html
Copyright © 2011-2022 走看看