什么是代理模式
代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。
为什么要用代理模式
中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。
代理模式分类
静态代理:
//定义接口
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());
}
}