Java代理
- Java代理:通过反射和InvocationHandler回调接口实现 Proxy.newProxyInstance(ClassLoader, Class[], InvocationHandler)
- 生成并加载代理类:ProxyGenerator.generateProxyClass()。继承Proxy,实现接口。所有的方法都要通过InvocationHandler
- 获取带有InvocationHandler参数的构造方法
- 创建代理实例
CGLIB
- Java代理只能代理接口,CGLIB可以代理实现类,不能代理声明为final的方法。使用字节码生成框架。通过拦截器织入横切逻辑。
- 拦截器:MethodInterceptor.intercept(Object, Method, Object[], MethodProxy)
- 调用被代理对象的方法:MethodProxy.invokeSuper(Method, Object[])
- 创建代理对象:Enhancer.setSuper(Class), Enhancer.setCallback(MethodInterceptor), Enhancer.create()
Javassit
- 动态代码创建,生成字节码
- 能代理实现类
Dubbo代理
Dubbo提供了ProxyFactory SPI,默认使用Javassist代理,也可以使用JDK代理。
比如我们有一个接口Car:
- 首先生成了Car的实现类proxy0。这是一个代理类,所有的方法都要通过InvocationHandler。
- 然后生成了Proxy的子类Proxy0,并创建了实例。通过newInstance可以创建代理类proxy0的实例。
比如我们有几个接口Car:
package org.apache.dubbo.common.bytecode;
public interface Car {
String getBrand();
long getWeight();
void make(String brand, long weight);
}
Dubbo首先生成Car的一个实现类proxy0,每个方法都代理给InvocationHandler处理:
package org.apache.dubbo.common.bytecode;
public class proxy0 implements org.apache.dubbo.common.bytecode.Car {
// 接口定义的方法
public static java.lang.reflect.Method[] methods;
private java.lang.reflect.InvocationHandler handler;
public proxy0() {
}
public proxy0(java.lang.reflect.InvocationHandler h) {
handler=$1;
}
public void make(String brand, long weight) {
Object[] args = new Object[2];
args[0] = ($w) $1;
args[1] = ($w) $2;
Object ret = handler.invoke(this, methods[0], args);
}
public String getBrand() {
Object[] args = new Object[0];
Object ret = handler.invoke(this, methods[1], args);
return (java.lang.String) ret;
}
public long getWeight() {
Object[] args = new Object[0];
Object ret = handler.invoke(this, methods[2], args);
return ret == null ? (long) 0 : ((Long) ret).longValue();
}
}
然后生成一个Proxy的子类Proxy0,可以用于创建代理类的实例:
public class Proxy0 extends org.apache.dubbo.common.bytecode.Proxy {
public Object newInstance(java.lang.reflect.InvocationHandler h) {
return new proxy0($1);
}
}
谢谢阅读!