Java动态代理深入解析(2)

@Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.print("say:");
            return method.invoke(target, args);
        }
       
    }
   
    public static void main(String[] args) {
        Subject subject=new SubjectImpl();
        Subject subjectProxy=(Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), new ProxyInvocationHandler(subject));
        subjectProxy.sayHi();
        subjectProxy.sayHello();
       
    }
}
 

只看main方法的话,只有第二行和之前的静态代理不同,同样是生成一个subjectProxy代理对象,只是生成的代码不同了。静态代理是直接new 一个SubjectImplProxy的实例,而动态代理则调用了java.lang.reflect.Proxy.newProxyInstance()方法,我们来看一下这个方法的源码:

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        if (h == null) {
            throw new NullPointerException();
        }

/*
        * Look up or generate the designated proxy class.
        */
        Class<?> cl = getProxyClass(loader, interfaces);  //获取代理类的Class

/*
        * Invoke its constructor with the designated invocation handler.
        */
        try {
            Constructor cons = cl.getConstructor(constructorParams);  //constructorParams是写死的:{ InvocationHandler.class },上边返回的代理类Class一定是extends Proxy的,而Proxy有一个参数为InvocationHandler的构造函数
            return cons.newInstance(new Object[] { h });  //这里通过构造函数将我们自己定义的InvocationHandler的子类传到代理类的实例里,当我们调用代理类的任何方法时,实际上都会调用我们定义的InvocationHandler子类重写的invoke()函数
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString());
        } catch (IllegalAccessException e) {
            throw new InternalError(e.toString());
        } catch (InstantiationException e) {
            throw new InternalError(e.toString());
        } catch (InvocationTargetException e) {
            throw new InternalError(e.toString());
        }
    }

上面的 Class<?> cl = getProxyClass(loader, interfaces);  调用的getProxyClass方法:

public static Class<?> getProxyClass(ClassLoader loader,
                                        Class<?>... interfaces)
        throws IllegalArgumentException
    {
        if (interfaces.length > 65535) {  //因为在class文件中,一个类保存的接口数量是用2个字节来表示的,因此java中一个类最多可以实现65535个接口
            throw new IllegalArgumentException("interface limit exceeded");
        }

Class<?> proxyClass = null;

/* collect interface names to use as key for proxy class cache */
        String[] interfaceNames = new String[interfaces.length];

// for detecting duplicates
        Set<Class<?>> interfaceSet = new HashSet<>();
     //验证interfaces里的接口是否能被类加载器加载,是否是接口,是否有重复的 
        for (int i = 0; i < interfaces.length; i++) {
            /*
            * Verify that the class loader resolves the name of this
            * interface to the same Class object.
            */
            String interfaceName = interfaces[i].getName();
            Class<?> interfaceClass = null;
            try {
                interfaceClass = Class.forName(interfaceName, false, loader);
            } catch (ClassNotFoundException e) {
            }
            if (interfaceClass != interfaces[i]) {
                throw new IllegalArgumentException(
                    interfaces[i] + " is not visible from class loader");
            }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/0dab0fb138c3829c8bf6ef3b552a8a73.html