首先我们要了解一下类的加载机制,在每创建一个Java类时,都会生产一个.class文件,在内存中对应也会生成一个class对象,来表示该类的类型信
息,我们可以用.class来获取这个类的所有信息,也可以通过getClass()方法来读取这个类的所有信息,比如
getClass().getInterfaces()获取类的接口信息等。在Java类加载时,要通过一个类加载器classloader来将生成的Java类加载到JVM
中才能执行。
理解了类的加载机制后,我们再看代码中的newProxyInstance方法,在这个方法中,我们将被代理对象传进来后,通过
Proxy.newProxyInstance这个方法来动态的创建一个被代理类的一个代理类的实例。
在Proxy.newProxyInstance方法中,共有三个参数:
1、targetObject.getClass().getClassLoader()目标对象通过getClass方法获取类的所有信息后,调用getClassLoader()
方法来获取类加载器。获取类加载器后,可以通过这个类型的加载器,在程序运行时,将生成的代理类加载到JVM即Java虚拟机中,以便运行时需要!
2、targetObject.getClass().getInterfaces()获取被代理类的所有接口信息,以便于生成的代理类可以具有代理类接口中的所有方法。
3、this:我们使用动态代理是为了更好的扩展,比如在方法之前做什么,之后做什么等操作。这个时候这些公共的操作可以统一交给代理类去做。
这个时候需要调用实现了InvocationHandler 类的一个回调方法。由于自身变实现了这个方法,所以将this传递过去。
invoke方法的参数
1、Object proxy生成的代理对象,在这里不是特别的理解这个对象,但是个人认为是已经在内存中生成的proxy对象。
2、Method method:被代理的对象中被代理的方法的一个抽象。
3、Object[] args:被代理方法中的参数。这里因为参数个数不定,所以用一个对象数组来表示。
执行过程
在执行过程中,由于被代理的方法可能有返回值,可能直接就是void来表示,那么为了适应于所有方法,所以定义一个返回值,将返回的值
通过ret来接收,当然会抛出异常。ret = method.invoke(targetObject, args);就是调用被代理对象的方法,来执行最原始的方法。在执行完后,
进行额外的处理操作。