Dubbo Wrapper 原理与实例

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> 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的反射机制。

你可能感兴趣的:(Dubbo Wrapper 原理与实例)