两种动态代理
1、jdk的动态代理
讲一下动态代理的实现原理-说明白原理的话肯定是要看源码了-不要慌-干就完了!!!
其实在使用动态代理的时候最最核心的就是Proxy.newProxyInstance(loader, interfaces, h);废话不多说-直接干源码。
动态代理的样例代码:
Calculator.java
``java
package com.oi;public interface Calculator { public int add(int i, int j); public int sub(int i, int j); public int mult(int i, int j); public int div(int i, int j);}
`
MyCalculator.java
`java
package com.oi;public class MyCalculator implements Calculator { public int add(int i, int j) { int result = i + j; return result; } public int sub(int i, int j) { int result = i - j; return result; } public int mult(int i, int j) { int result = i * j; return result; } public int div(int i, int j) { int result = i / j; return result; }}
`
CalculatorProxy.java
`java
package com.oi;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class CalculatorProxy { public static Calculator getProxy(final Calculator calculator){ ClassLoader loader = calculator.getClass().getClassLoader(); Class[] interfaces = calculator.getClass().getInterfaces(); InvocationHandler h = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { result = method.invoke(calculator, args); } catch (Exception e) { } finally { } return result; } }; Object proxy = Proxy.newProxyInstance(loader, interfaces, h); return (Calculator) proxy; }}
`
Test.java
`java
package com.oi;public class Test { public static void main(String[] args) { Calculator proxy = CalculatorProxy.getProxy(new MyCalculator()); proxy.add(1,1); System.out.println(proxy.getClass()); }}
`
动态代理的源码:
Proxy.java的newProxyInstance方法:
`java
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) throws IllegalArgumentException { //判断InvocationHandler是否为空-若为空-抛出空指针异常 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. * 使用自定义的InvocationHandler作为参数-调用构造函数获取代理类对象实例 */ 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; } }); } //生成代理类的实例并把InvocationHandlerImpl的实例传给构造方法 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); } }
`
getProxyClass0(ClassLoader loader,Class>… interfaces)
`java
private static Class getProxyClass0(ClassLoader loader, Class... interfaces) { //限定代理的接口不能超过65535个 if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } // If the proxy class defined by the given loader implementing // the given interfaces exists, this will simply return the cached copy; // otherwise, it will create the proxy class via the ProxyClassFactory // 如果缓存中已经存在相应接口的代理类-直接返回-否则-使用ProxyClassFactory创建代理类 return proxyClassCache.get(loader, interfaces);}/** * a cache of proxy classes */private static final WeakCache[], Class> proxyClassCache