JDK动态代理

JDK动态代理

Proxy的静态方法newProxyInstance解析

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.
         */
    	//装载类加载器与接口,获得 $Proxy0 类,
    	//$Proxy0实现了接口,并且里面属性有InvocationHandler的实现类(后面会发现)
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
			//获取$Proxy0的构造器,并且constructorParams是InvocationHandler.class
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            //获得InvocationHandler的实现类
            final InvocationHandler ih = h;
            //开放权限
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        //允许
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            //创建$Proxy0对象,并且传递InvocationHandler的实现类
            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);
        }
    }
posted @ 2021-07-15 16:21  鸭梨的药丸哥  阅读(18)  评论(0)    收藏  举报  来源