静态代理、动态代理

2019-12-16  本文已影响0人  sunpengshujun

[TOC]

静态代理

/**
 * 接口
 */
public interface IUserDao {
    void save();
}

/**
 * 接口实现
 * 目标对象
 */
public class UserDao implements IUserDao {
    public void save() {
        System.out.println("----已经保存数据!----");
    }
}

/**
 * 代理对象,静态代理
 */
public class UserDaoProxy implements IUserDao{
    //接收保存目标对象
    private IUserDao target;
    public UserDaoProxy(IUserDao target){
        this.target=target;
    }

    public void save() {
        System.out.println("开始事务...");
        target.save();//执行目标对象的方法
        System.out.println("提交事务...");
    }
}

/**
 * 静态代理
 * UserDao 和UserDaoProxy 都实现了同一个接口
 * 静态代理, 其实跟  controller 调用service, service调用dao,几乎差不多,
 * 主要是为了模拟的像,所以代理类也使用了  被代理类 的接口
 */
public class App {
    public static void main(String[] args) {
        //目标对象
        IUserDao target = new UserDao();

        //代理对象,把目标对象传给代理对象,建立代理关系
        IUserDao proxy = new UserDaoProxy(target);

        proxy.save();//执行的是代理的方法
    }
}

动态代理

动态代理:在程序运行期间根据被代理的类 动态创建代理类及其实例来 完成具体的功能。
其实所谓的代理,其实本质还是 通过代理类,去调用被代理类。
不管是 静态代理还是动态代理。
静态代理的问题在于,将代理类与被代理类,被绑定死。
这就使得代码的功能特别局限,不灵活。
动态代理的思路:是根据需要代理的类的接口,在内存中动态生成代理类。
告诉接口,告诉类加载器。可以在内存中动态生成接口的实现类(代理类)

根据源码查看

Proxy.newProxyInstance(ClassLoader,Interfaces,InvocationHandler)

这里返回的对象便是在内存中生成的 代理类的 实例

在这里插入图片描述
在这里插入图片描述

getProxyClass0 生成代理类的 Class对象

在这里插入图片描述

WeakCache.get()

如何保存的对象
**proxyClassCache 为 WeakCache 类的实例 **
WeakCache几个非常重要的属性

BiFunction<K, P, ?> subKeyFactory = new KeyFactory()
BiFunction<K, P, V> valueFactory = new ProxyClassFactory()
ConcurrentMap<CacheKey<>(key, refQueue), ConcurrentMap<Object, Supplier<V>>> map = new ConcurrentHashMap<>();

先了解map
map是一个双层集合
第一层的key 为 Proxy&CacheKey(ClassLoader,Interfaces)
第二层的key 为 Proxy&Key1 ,由 subKeyFactory 创建
第二层的value 为由 Proxy&ProxyClassFactory 创建的 代理类的Class对象组成

在这里插入图片描述
  1. 创建WeakCache&Factory
  2. 赋值 给Supplier
  3. 调用get,创建 代理类的Class对象
    最后由Proxy&ProxyClassFactory 的apply方法,创建代理类的Class对象


    在这里插入图片描述

WeakCache$Factory

在这里插入图片描述

Proxy&ProxyClassFactory,创建代理类的Class 对象

在这里插入图片描述
在这里插入图片描述

**proxyName = “com.sun.proxy. $Proxy0”

ProxyGenerator.generateProxyClass 为生成代理类的 class文件

defineClass0 方法为加载此代理类,生成此代理类的Class 对象**


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上一篇下一篇

猜你喜欢

热点阅读