Proxy

作者: 风吹过山 | 来源:发表于2017-07-12 13:59 被阅读0次

参考链接:http://www.jianshu.com/p/3ad3fb560ca1

首先看调用方式:
Subject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxyHandler(realSubject);
Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
.getClass().getInterfaces(), handler);
通过Proxy的
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h);
函数中调用getProxyClass函数,动态生成一个RealSubject类相关的.Class类,newProxyInstance函数中将handler作为回调传递进去,里面调用Proxy类中的static的invoke回调出来也就是到RealSubject的invoke方法中,做一些额外的事情。

// 代理对象是可以序列化
public class Proxy implements Serializable {
一、定义的变量:
1、private static final long serialVersionUID = -2222568056686623797L;
serialVersionUID的作用:
通过判断实体类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。
生成实体类的serialVersionUID方法:1、写上默认的1L,比如:private static final long serialVersionUID = 1L; 2、用idea自动生成。

// maps class loaders to created classes by interface names
/** 将代理类 加载器放在Proxy的maps结构中缓存起来 */
2、private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>> loaderCache = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();

/** 所有代理类的集合,用于isProxyClass方法的实现 */
3、private static final Map<Class<?>, String> proxyCache = new WeakHashMap<Class<?>, String>();

4、private static int NextClassNameIndex = 0;///** 下一个用于生成唯一代理类名字的数字 */

/**
 * The invocation handler on which the method calls are dispatched.
 * 代理实例的invocationHandler对象
 */

5、protected InvocationHandler h;

二:定义的方法:
作用类实现了InvocationHandler接口的代理类,其中主要方法有:
private Proxy() {} ("unused") //禁止实例化
protected Proxy(InvocationHandler h):构造方法,用于给内部的h赋值。

static Class getProxyClass(ClassLoader loader, Class[] interfaces):获得一个动态代理类的Class对象。,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。 从缓存中取,如果没有,则调用本地方法generateProxy(name, interfaces, loader, methodsArray, exceptionsArray);注意其中的几个参数。

static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用。
InvocationHandler.invoke的第一个参数proxy值,是newProxyInstance返回的动态代理类的实例,不是被代理的实例(下方的demo输出的className证明了这一点)。
动态代理类Proxy是结合java底层实现的,通过纯粹的java代码实现比较困难。
需要java动态生成类的支持。

根据class在Map 中查找是否是代理类
public static boolean isProxyClass(Class<?> cl) {}

返回指定代理实例的调用处理程序。
public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException {

两个 native方法
native private static Class generateProxy(String name, Class[] interfaces,ClassLoader loader);

在生成代理类时,VM克隆该方法的描述符。没有实现。
native private static void constructorPrototype(InvocationHandler h);

public static void main(String[] args) {
Subject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxyHandler(realSubject);
Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
.getClass().getInterfaces(), handler);
System.out.println(subject.getClass().getName());
subject.rent();
subject.hello("world");
}
subject.getClass().getName()打印的值是:$Proxy0

相关文章

网友评论

      本文标题:Proxy

      本文链接:https://www.haomeiwen.com/subject/sdwuqxtx.html