超变态传奇上线65535 超级变态65535手机传奇


关于JDK的动态代理 , 最为人熟知的可能要数Spring AOP的实现 , 默认情况下 , Spring AOP的实现对于接口来说就是使用的JDK的动态代理来实现的 , 而对于类的代理使用CGLIB来实现 。那么 , 什么是JDK的动态代理呢?
JDK的动态代理 , 就是在程序运行的过程中 , 根据被代理的接口来动态生成代理类的class文件 , 并加载运行的过程 。JDK从1.3开始支持动态代理 。那么JDK是如何生成动态代理的呢?JDK动态代理为什么不支持类的代理 , 只支持接口的代理?
首先来看一下如何使用JDK动态代理 。JDK提供了java.lang.reflect.Proxy类来实现动态代理的 , 可通过它的newProxyInstance来获得代理实现类 。同时对于代理的接口的实际处理 , 是一个
java.lang.reflect.InvocationHandler , 它提供了一个invoke方法供实现者提供相应的代理逻辑的实现 。可以对实际的实现进行一些特殊的处理 , 像Spring AOP中的各种advice 。下面来看看如何使用 。
被代理的接口:
package com.mikan.proxy;public interface HelloWorld { void sayHello(String name); }

接口的实现类:
package com.mikan.proxy;public class HelloWorldImpl implements HelloWorld { @Override public void sayHello(String name) { System.out.println("Hello " + name); }}

实现一个
java.lang.reflect.InvocationHandler:
package com.mikan.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class CustomInvocationHandler implements InvocationHandler { private Object target; public CustomInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before invocation"); Object retVal = method.invoke(target, args); System.out.println("After invocation"); return retVal; }}

使用代理:
package com.mikan.proxy;import java.lang.reflect.Proxy;public class ProxyTest { public static void main(String[] args) throws Exception { System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); CustomInvocationHandler handler = new CustomInvocationHandler(new HelloWorldImpl()); HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance( ProxyTest.class.getClassLoader(), new Class[]{HelloWorld.class}, handler); proxy.sayHello("Mikan"); }}

运行的输出结果:
localhost:classes mikan$ java com/mikan/proxy/ProxyTestBefore invocationHello MikanAfter invocation

从上面可以看出 , JDK的动态代理使用起来非常简单 , 但是只知道如何使用是不够的 , 知其然 , 还需知其所以然 。所以要想搞清楚它的实现 , 那么得从源码入手 。这里的源码是1.7.0_79 。首先来看看它是如何生成代理类的:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { if (h == null) { throw new NullPointerException(); } final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } // 这里是生成class的地方 Class<?> cl = getProxyClass0(loader, intfs); // 使用我们实现的InvocationHandler作为参数调用构造方法来获得代理类的实例 try { final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { return AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { return newInstance(cons, ih); } }); } else { return newInstance(cons, ih); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } }


特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。