前言
图片来自https://www.cnblogs.com/maohuidong/p/7992894.html
代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对这个对象的访问。为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性
正题
首先,我们先来看下代理的实现,直接看Proxy类的介绍,如图所示,展示了创建代理的两种方式,第一种是先获取代理类,然后获取构造器,最后构造实例;第二种直接就是创建实例,调用更加的方便。
从代理的使用上发现了InvocationHandler、Class、Constructor等,反射构建实例不就是使用的这些东西吗?难道代理类也是用反射实现的?这里我们先不做回答,继续进行分析
Dynamic Proxy
我们先说下动态代理怎么来的哈!我们还有中代理叫静态代理,所谓静态代理就是将接口、实现类、代理类都手动的完成,比如:
public interface People {
void position();
}
public class TeacherPeople implements People {
@Override
public void position() {
System.out.println("teacher");
}
}
public class PeopleProxy implements People {
private People people = new TeacherPeople();
@Override
public void position() {
System.out.println("before method");
people.position();
System.out.println("after method");
}
@Test
public void proxyTest(){
PeopleProxy peopleProxy = new PeopleProxy();
peopleProxy.position();
}
}
如果我们每需要代理一个类就需要写一个代理就会产生很多的重复代理,因此就有了动态代理,在运行的过程中,动态的创建我们的代理类来完成相关的操作
整个动态代理的框架我在网上找了一个图,来自于:https://blog.csdn.net/qq_36285943/article/details/80152640
走进Proxy.newProxyInstance方法,先看前半部分的生成代理类:
那到底是怎样的生成的代理类,走进getProxyClass0查看:
我们先进入proxyClassCache看下这是个什么东西
proxyClassCache维护了一个subKeyFacory和valueFacory,且都是BiFunction类型的,我们分别看下KeyFactory和ProxyClassFactory
KeyFactory
ProxyClassFactory
apply的代码比较长,我筛选出几行关键的代码
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
//获取每个代理的接口的Class对象,存到set集合中
for (Class<?> intf : interfaces) {
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
//确定包以及权限相关的操作吧
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) {
// if no non-public proxy interfaces, use com.sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
//原子递增属于代理类名的一部分
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
//生成代理类的class文件,返回最后的Class
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
}
看完了WeakCache的构造,我们继续回到get方法:return proxyClassCache.get(loader, interfaces);
Factory与Supplier的关系也就是图中这样,其实也就是Factory
通过这一串的分析我们我们已经获取到了要生成代理的Factory,然后调用get方法去生成ProxyClass,生成的方法就是上面我们分析的ProxyClassFactory的apply方法
这里有点绕,各位一定要自己进入代码查看分析,通过一连串的方法我们就拿到了代理类的Class对象,也就是Proxy。newinstance的前部分 ,然后我们再来看后半部分,后半部分就简单多了。