Dubbo Wrapper 可以认为是一种反射机制。它既可以读写目标实例的字段,也可以调用目标实例的方法。比如
- Car是接口;RaceCar是实现类,实现了Car;ferrari和porsche是RaceCar的两个实例
- Dubbo为接口Car生成一个Warpper子类,比如Wrapper0;然后创建Wrapper0的实例wrapper0
- 通过wrapper0#setPropertyValue来修改ferrari的字段,也可以修改porsche的字段
- 通过wrapper0#invokeMethod来调用ferrari的方法,也可以调用porsche的方法
- 优点:通过一个Wrapper0实例就可以操作N个目标接口Car的实例
比如我们有一个Car接口,定义了3个方法:
package org.apache.dubbo.common.bytecode;
public interface Car {
String getBrand();
long getWeight();
void make(String brand, long weight);
}
Wrapper#makeWrapper之后生成的Wrapper子类代码如下:
package org.apache.dubbo.common.bytecode;
public class Wrapper0 extends Wrapper {
// 字段名列表
public static String[] pns;
// 字段名与字段类型的映射关系
public static java.util.Map<String, Class<?>> pts;
// 方法名列表
public static String[] mns;
// 声明的方法名列表
public static String[] dmns;
// 每个public方法的参数类型
public static Class[] mts0;
public static Class[] mts1;
public static Class[] mts2;
public String[] getPropertyNames() {
return pns;
}
public boolean hasProperty(String n) {
return pts.containsKey($1);
}
public Class getPropertyType(String n) {
return (Class) pts.get($1);
}
public String[] getMethodNames() {
return mns;
}
public String[] getDeclaredMethodNames() {
return dmns;
}
public void setPropertyValue(Object o, String n, Object v) {
org.apache.dubbo.common.bytecode.Car w;
try {
w = ((org.apache.dubbo.common.bytecode.Car) $1);
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
throw new org.apache.dubbo.common.bytecode.NoSuchPropertyException("Not found property \"" + $2 + "\" field or setter method in class org.apache.dubbo.common.bytecode.Car.");
}
public Object getPropertyValue(Object o, String n) {
org.apache.dubbo.common.bytecode.Car w;
try {
w = ((org.apache.dubbo.common.bytecode.Car) $1);
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
if ($2.equals("brand")) {
return ($w) w.getBrand();
}
if ($2.equals("weight")) {
return ($w) w.getWeight();
}
throw new org.apache.dubbo.common.bytecode.NoSuchPropertyException("Not found property \"" + $2 + "\" field or setter method in class org.apache.dubbo.common.bytecode.Car.");
}
public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws java.lang.reflect.InvocationTargetException {
org.apache.dubbo.common.bytecode.Car w;
try {
w = ((org.apache.dubbo.common.bytecode.Car) $1);
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
try {
if ("make".equals($2) && $3.length == 2) {
w.make((java.lang.String) $4[0], ((Number) $4[1]).longValue());
return null;
}
if ("getBrand".equals($2) && $3.length == 0) {
return ($w) w.getBrand();
}
if ("getWeight".equals($2) && $3.length == 0) {
return ($w) w.getWeight();
}
} catch (Throwable e) {
throw new java.lang.reflect.InvocationTargetException(e);
}
throw new org.apache.dubbo.common.bytecode.NoSuchMethodException("Not found method \"" + $2 + "\" in class org.apache.dubbo.common.bytecode.Car.");
}
}
可以认为是重写了JDK的反射机制。