jdk動態代理

JDK動態代理和CGLIB代理的區別:java

  • 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 mayuthis

查看生成的代理類加上System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true"),在項目的根路徑上能夠找到代理類,以下:spa

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字節碼生成技術將給定的目標方法和處理目標方法的處理器在運行期間進行方法提取和拼裝生成新的代理類。代理

相關文章
相關標籤/搜索