静态代理、动态代理
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对象组成
- 创建WeakCache&Factory
- 赋值 给Supplier
-
调用get,创建 代理类的Class对象
最后由Proxy&ProxyClassFactory 的apply方法,创建代理类的Class对象
在这里插入图片描述
WeakCache$Factory
在这里插入图片描述Proxy&ProxyClassFactory,创建代理类的Class 对象
在这里插入图片描述在这里插入图片描述
**proxyName = “com.sun.proxy. $Proxy0”
ProxyGenerator.generateProxyClass 为生成代理类的 class文件
defineClass0 方法为加载此代理类,生成此代理类的Class 对象**
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述