在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口。通过这个类和接口可以生成JDK动态代理类或动态代理对象。
JDK动态代理例子:
// 抽象主题角色public interface Sleep { void sleep();} // 真实主题角色public class SleepImpl implements Sleep { @Override public void sleep() { System.out.println("熟睡中"); }} //动态处理器public class DynamicProxyHandler implements InvocationHandler { private Object obj ; public DynamicProxyHandler(final Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("睡觉前要刷牙"); Object result = method.invoke(obj, args); System.out.println("睡醒后要吃早饭"); return null; }}//测试代码public class ProxyTest { public static void main(String[] args) { Sleep sleep = new SleepImpl(); DynamicProxyHandler dph = new DynamicProxyHandler(sleep); Sleep sleepProxy = (Sleep) Proxy.newProxyInstance(sleep.getClass().getClassLoader(), sleep.getClass().getInterfaces(), dph); sleepProxy.sleep(); }} 结果:睡觉前要刷牙 熟睡中 睡醒后要吃早饭
JDK动态代理源码分析:
生产代理类主要是通过:Proxy.newProxyInstance方法:
@CallerSensitive public static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler h) throws IllegalArgumentException { Objects.requireNonNull(h); final Class [] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /* * Look up or generate the designated proxy class. */ Class cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { if (sm != null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } final Constructor cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction() { public Void run() { cons.setAccessible(true); return null; } }); } return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { throw new InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new InternalError(t.toString(), t); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString(), e); } }