参考博客:
https://www.cnblogs.com/liuyun1995/p/8144628.html
https://www.cnblogs.com/liuyun1995/p/8157098.html
https://www.cnblogs.com/liuyun1995/p/8144676.html
https://www.cnblogs.com/liuyun1995/p/8144706.html
https://blog.csdn.net/wangqyoho/article/details/77584832
Proxy.newProxyInstance()方法
public class ProxyTest {
public static void main(String[] args) {
Car audi = (Car) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class<?>[] {Car.class},new CarHandler(new Audi()));
audi.drive("name1","audi");
}
}
在JDK动态代理中生成代理类的方法就是Proxy.newProxyInstance , 源码如下:
有几个个关键的步骤:
-
通过代理接口的类加载器和要代理的接口数组得到代理类(这里有一个缓存机制来得到代理类)
ClassLoader.getSystemClassLoader方法无论何时均会返回ApplicationClassLoader,其只加载classpath下的class文件
-
获取代理类的构造器
-
如果类是作用域不是公共的 , 则设置为可访问 , 否则不能使用类的构造器
-
利用构造器实例化代理类
这里其实和静态代理有类似的地方 , 通过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);
}
//该方法先从缓存获取代理类, 如果没有再去生成一个代理类
Class<?> cl = getProxyClass0(loader, intfs);
try {
//进行一些权限检验
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//获取参数类型是InvocationHandler.class的代理类构造器
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
//如果代理类是不可访问的, 就使用特权将它的构造器设置为可访问
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
//传入InvocationHandler实例去构造一个代理类的实例
//所有代理类都继承自Proxy, 因此这里会调用Proxy的构造器将InvocationHandler引用传入
return cons.newInstance(new Object[]{h});
} catch (Exception e) {
//为了节省篇幅, 笔者统一用Exception捕获了所有异常
throw new InternalError(e.toString(), e);
}
}