深入源码了解JDK动态代理-Proxy

什么是代理模式

代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

为什么要用代理模式

中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。

开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。

代理模式分类

静态代理:

//定义接口
public interface Subject {
    Integer doSomething(Integer var1);
}
//定义接口实现
public class SubjectImpl implements Subject{
    @Override
    public Integer doSomething(Integer var1) {
        System.out.println("目标对象执行...");
        return var1 << 1;
    }
}
//定义代理类(代理类需要和目标类实现共同的接口)
public class StaticProxy implements Subject{
    private Subject subject;
    public StaticProxy(Subject subject){
        this.subject = subject;
    }
    @Override
    public Integer doSomething(Integer var1) {
        System.out.println("静态代理before...");
        Integer result = subject.doSomething(var1);
        System.out.println("静态代理before...");
        return result;
    }
}
//测试
public static void main(String[] args) {
    Subject subject = new SubjectImpl();
    StaticProxy proxy = new StaticProxy(subject);
    Integer result = proxy.doSomething(2);
    System.out.println("代理方法执行完毕...result="+result);
}

动态代理

动态代理分两种,jdk动态代理和cglib动态代理(目前先看jdk动态代理)

//JDK动态代理也是基于接口实现,具体原因看源码分析
public interface Subject {
    Integer doSomething(Integer var1);
}
public class SubjectImpl implements Subject{
    @Override
    public Integer doSomething(Integer var1) {
        System.out.println("目标对象执行...");
        return var1 << 1;
    }
}
//动态代理类,必须实现 <InvocationHandler> 
public class JdkProxy implements InvocationHandler {
    private Subject subject;

    public JdkProxy(Subject subject) {
        this.subject = subject;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before代理对象执行...");
        Object result = method.invoke(subject,args);
        System.out.println("after代理对象执行...");
        return result;
    }
}
public static void main(String[] args) {
	//生成字节码即代理类到本地(com.sum.proxy包下)
    System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
    Subject subject = new SubjectImpl();
    JdkProxy invocationHandler = new JdkProxy(subject);
    Subject proxyInstance = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), invocationHandler);
    Integer result = proxyInstance.doSomething(2);
    System.out.println("代理方法执行完毕。。。。result="+result);
}

运行结果
在这里插入图片描述

JDK Proxy 刨析

Proxy

首先看下Proxy类中有哪些信息
在这里插入图片描述

newProxyInstance 返回代理类的实例

//loader:目标对象类加载器,APP类加载器(或者自定义的类加载器)
//interfaces:目标对象的接口
//h:对目标对象增强的类 必须实现<InvocationHandler>
public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h){
    //验证InvocationHandler 就是咱们的代理类
    Objects.requireNonNull(h);
    final Class<?>[] intfs = interfaces.clone();
    //找到代理类(具体怎么找到的呢???)
    Class<?> cl = getProxyClass0(loader, intfs);
    //选择构造
    //创建实例
    return cons.newInstance(new Object[]{h});
}

getProxyClass0(loader, intfs)

private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
    //验证目标对象接口的数量
    if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }
    //private static final WeakCache<ClassLoader, Class<?>[], Class<?>>proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
    //proxyClassCache是Proxy类的一个静态属性,value是一个ProxyClassFactory
    return proxyClassCache.get(loader, interfaces);
}

ProxyClassFactory

//ProxyClassFactory其实就是一个BiFunction
//BiFunction是一个函数式接口,也是一个生产者模型
//BiFunction<T(param1), U(param2), R(返回值)>
private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>

WeakCache.get(K key, P parameter)

public V get(K key, P parameter) {
	//验证接口
    Objects.requireNonNull(parameter);
    //删除过期的缓存
    expungeStaleEntries();
    //封装key
    Object cacheKey = CacheKey.valueOf(key, refQueue);

    //private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map= new ConcurrentHashMap<>();
    //map的数据结构是Map<cacheKey,ConcurrentHashMap>
    ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
    if (valuesMap == null) {
        ConcurrentMap<Object, Supplier<V>> oldValuesMap= map.putIfAbsent(cacheKey,valuesMap = new ConcurrentHashMap<>());
        //这里只有多线程高并发情况下才会出现
        if (oldValuesMap != null) {
            valuesMap = oldValuesMap;
        }
    }
    //得到map中
    //BiFunction<K, P, ?> subKeyFactory = Objects.requireNonNull(subKeyFactory);
    //subKeyFactory就是KeyFactory,
    Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
    //只要valuesMap不是oldValuesMap必然不会取到值
    //Supplier也是函数式编程,是个消费者模型
    Supplier<V> supplier = valuesMap.get(subKey);
    Factory factory = null;
    while (true) {
    	//第一次不会取到
        if (supplier != null) {
        	//怎么获取的呢???
            V value = supplier.get();
            //取到了之后进行返回
            if (value != null) {
                return value;
            }
        }
        // 如果supplier为空进行重新生成
        if (factory == null) {
            factory = new Factory(key, parameter, subKey, valuesMap);
        }
        if (supplier == null) {
            supplier = valuesMap.putIfAbsent(subKey, factory);
            if (supplier == null) {
                // successfully installed Factory
                supplier = factory;
            }
        } else {
            if (valuesMap.replace(subKey, supplier, factory)) {
                supplier = factory;
            } else {
                supplier = valuesMap.get(subKey);
            }
        }
    }
}
Factory是个Supplier
@Override
public synchronized V get() { // serialize access
    Supplier<V> supplier = valuesMap.get(subKey);
    if (supplier != this) {
        return null;
    }
    V value = null;
    try {
    //valueFactory也是一个BiFunction,具体对象是ProxyClassFactory
    value = Objects.requireNonNull(valueFactory.apply(key, parameter));
    } finally {
        if (value == null) { 
            valuesMap.remove(subKey, this);
        }
    }
    assert value != null;
    CacheValue<V> cacheValue = new CacheValue<>(value);
    //替换原来的对象,失败了重新添加
    if (valuesMap.replace(subKey, this, cacheValue)) {
        reverseMap.put(cacheValue, Boolean.TRUE);
    } else {
        throw new AssertionError("Should not reach here");
    }
    return value;
}
ProxyClassFactory.apply也就是BiFunction
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
    //第一步进行验证
    Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
    for (Class<?> intf : interfaces) {
        Class<?> interfaceClass = null;
        try {
            interfaceClass = Class.forName(intf.getName(), false, loader);
        } catch (ClassNotFoundException e) {
        }
        if (interfaceClass != intf) {
            throw new IllegalArgumentException(
                intf + " is not visible from class loader");
        }
        if (!interfaceClass.isInterface()) {
            throw new IllegalArgumentException(
                interfaceClass.getName() + " is not an interface");
        }
        
        if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
            throw new IllegalArgumentException(
                "repeated interface: " + interfaceClass.getName());
        }
    }

    String proxyPkg = null;     // package to define proxy class in
    int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
	//验证权限控制符,共有的放在哪,私有的放在哪
    for (Class<?> intf : interfaces) {
        int flags = intf.getModifiers();
        if (!Modifier.isPublic(flags)) {
            accessFlags = Modifier.FINAL;
            String name = intf.getName();
            int n = name.lastIndexOf('.');
            String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
            if (proxyPkg == null) {
                proxyPkg = pkg;
            } else if (!pkg.equals(proxyPkg)) {
                throw new IllegalArgumentException(
                    "non-public interfaces from different packages");
            }
        }
    }
    if (proxyPkg == null) {
        //定义包路径 com.sun.proxy.
        proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
    }
    long num = nextUniqueNumber.getAndIncrement();
    //获取代理类名 如:com.sun.proxy.$Proxy0
    String proxyName = proxyPkg + proxyClassNamePrefix + num;
	//获取代理类的字节数据(这是重要生成代理类的方法,里面有一个成员定义是否需要生成代理对象到本地)
	//标识在Main方法中有定义(在系统中配置这个属性为ture就可以生成到本地)
	//saveGeneratedFiles = (Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"));
	//具体生成字节码方法就是在这个方法中,有兴趣的可以了解下
	//在ProxyGenerator.generateClassFile()方法中
    byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
        proxyName, interfaces, accessFlags);
    try {
    	//返回代理对象
        return defineClass0(loader, proxyName,
                            proxyClassFile, 0, proxyClassFile.length);
    } catch (ClassFormatError e) {
        throw new IllegalArgumentException(e.toString());
    }
}

流程图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值