动态代理浅说

代理应该学习java的都不陌生了,不过之前我学习的时候倒是有疑问的,这么做到底意义在哪里?
它能帮我干些什么?

剥离非业务逻辑

举个例子,例如事务,每次使用的时候都需要打开,然后提交等操作
这些操作如果在每次的业务线上去做的时候,这是一件繁琐的事情,业务代码的人也并不需要关心,对于他这个角色来说,
处理好业务代码应该就可以了。那这部分就可以使用代理让它去帮你完成这部分操作。
当然spring已经封装好了,没必要再实现一遍

制定通用的一些策略

其实这个很笼统,什么样的策略是通用,从业务上理解就是大部分场景需要这些操作,但是又不想多处维护,方式等也都比较统一的策略

实现比较优雅的模式

JDK Proxy

这里其实有很多文章说明
实现接口 -> 实现invocationHandler -> newProxyInstance -> invoke
newProxyInstance 这里会生成字节码 既然是动态代理总得有动态代理的意义 ^_^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
    proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
try {
Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile,
                                 0, proxyClassFile.length,
                                loader, null);
reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
return pc;
} catch (ClassFormatError e) {
// 如果出现 ClassFormatError,很可能是输入参数有问题,比如,ProxyGenerator 有 bug
}

public static Object newProxyInstance(ClassLoader loader,
                                  Class<?>[] interfaces,
                                  InvocationHandler h)

ASM是通过操作字节码来实现对结构的修改和包装的。
如:Visitor
Jdk proxy

CGLIB

基于AMS的CGLIB,应该也没有人陌生
字节码生成子类 -> 动态生成类和方法等-> 包装父类和子类 -> 索引代理方法和被代理方法 -> 调用
字节码文档
cglib