JDK动态代理(2)

参考博客:

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);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值