Dubbo 代理对象的创建过程

243 阅读1分钟

Dubbo代理对象的过程是在注入Dubbo的Service过程中实现的,比如我们的Controller中注入了一个Dubbo服务,如下

@RestController
@RequestMapping("/demo")
public class DemoController {
    static final String demoUrl = "dubbo://127.0.0.1:20880";


    /**
     * loadbalance:轮询策略
     * cluster:失败策略
     */
    @Reference(loadbalance = "roundrobin", timeout = 6000, cache = "lru"
//            , methods = {
//        @Method(name = "queryInfo", oninvoke = "eventNotifyServiceImpl.oninvoke",
//                onreturn = "eventNotifyServiceImpl.onreturn",
//                onthrow = "eventNotifyServiceImpl.onthrow")
//    }
    )
    private UserService demoService;

    @RequestMapping("/hello")
    public String hello() throws InterruptedException, ExecutionException {
        ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setInterface("com.doukill.dubbo.UserService");
//        referenceConfig.setVersion("1.0.0");
        referenceConfig.setGeneric("true");

        GenericService genericService = referenceConfig.get();
        Object result = genericService.$invoke("queryInfo", new String[]{"java.lang.String"},
                new Object[]{"nihao"});

//        return demoService.queryInfo("nihao");
        return (String) result;
    }


}

源码中,起点的位置是在ReferenceConfig中,

1 ReferenceConfig

public synchronized T get() {
    checkAndUpdateSubConfigs();

    if (destroyed) {
        throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!");
    }
    if (ref == null) {
        //重点
        init();
    }
    return ref;
}
private void init() {
    if (initialized) {
        return;
    }
    //这里,创建代理
    ref = createProxy(map);

    String serviceKey = URL.buildKey(interfaceName, group, version);
    ApplicationModel.initConsumerModel(serviceKey, buildConsumerModel(serviceKey, attributes));
    initialized = true;
}
private T createProxy(Map<String, String> map) {
    // create service proxy 这里创建代理
    //使用的是自适应扩展SPI机制
    return (T) PROXY_FACTORY.getProxy(invoker);
}

最终根据SPI默认机制,会调用到JavassistProxyFactory中。

2 JavassistProxyFactory

public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
    return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}

3 Proxy

public static Proxy getProxy(ClassLoader cl, Class<?>... ics) {
    if (ics.length > MAX_PROXY_COUNT) {
        throw new IllegalArgumentException("interface limit exceeded");
    }

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < ics.length; i++) {
        String itf = ics[i].getName();
        if (!ics[i].isInterface()) {
            throw new RuntimeException(itf + " is not a interface.");
        }

        Class<?> tmp = null;
        try {
            //加载该类对象,比如:com.doukill.UserService
            tmp = Class.forName(itf, false, cl);
        } catch (ClassNotFoundException e) {
        }

        if (tmp != ics[i]) {
            throw new IllegalArgumentException(ics[i] + " is not visible from class loader");
        }

        sb.append(itf).append(';');
    }

    // use interface class name list as key.
    String key = sb.toString();

    // get cache by class loader.
    final Map<String, Object> cache;
    synchronized (PROXY_CACHE_MAP) {
        cache = PROXY_CACHE_MAP.computeIfAbsent(cl, k -> new HashMap<>());
    }

    Proxy proxy = null;
    synchronized (cache) {
        do {
            Object value = cache.get(key);
            if (value instanceof Reference<?>) {
                proxy = (Proxy) ((Reference<?>) value).get();
                if (proxy != null) {
                    return proxy;
                }
            }

            if (value == PENDING_GENERATION_MARKER) {
                try {
                    cache.wait();
                } catch (InterruptedException e) {
                }
            } else {
                cache.put(key, PENDING_GENERATION_MARKER);
                break;
            }
        }
        while (true);
    }

    long id = PROXY_CLASS_COUNTER.getAndIncrement();
    //下面很长的代码都是在组装一个代理对象
    String pkg = null;
    ClassGenerator ccp = null, ccm = null;
    try {
        ccp = ClassGenerator.newInstance(cl);

        Set<String> worked = new HashSet<>();
        List<Method> methods = new ArrayList<>();

        for (int i = 0; i < ics.length; i++) {
            if (!Modifier.isPublic(ics[i].getModifiers())) {
                String npkg = ics[i].getPackage().getName();
                if (pkg == null) {
                    pkg = npkg;
                } else {
                    if (!pkg.equals(npkg)) {
                        throw new IllegalArgumentException("non-public interfaces from different packages");
                    }
                }
            }
            ccp.addInterface(ics[i]);
            //包装方法
            for (Method method : ics[i].getMethods()) {
                String desc = ReflectUtils.getDesc(method);
                if (worked.contains(desc)) {
                    continue;
                }
                if (ics[i].isInterface() && Modifier.isStatic(method.getModifiers())) {
                    continue;
                }
                worked.add(desc);

                int ix = methods.size();
                Class<?> rt = method.getReturnType();
                Class<?>[] pts = method.getParameterTypes();

                StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];");
                for (int j = 0; j < pts.length; j++) {
                    code.append(" args[").append(j).append("] = ($w)$").append(j + 1).append(";");
                }
                code.append(" Object ret = handler.invoke(this, methods[").append(ix).append("], args);");
                if (!Void.TYPE.equals(rt)) {
                    code.append(" return ").append(asArgument(rt, "ret")).append(";");
                }

                methods.add(method);
                ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());
            }
        }

        if (pkg == null) {
            pkg = PACKAGE_NAME;
        }

        // create ProxyInstance class.
        //创建代理的实例
        String pcn = pkg + ".proxy" + id;
        ccp.setClassName(pcn);
        ccp.addField("public static java.lang.reflect.Method[] methods;");
        ccp.addField("private " + InvocationHandler.class.getName() + " handler;");
        ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{InvocationHandler.class}, new Class<?>[0], "handler=$1;");
        ccp.addDefaultConstructor();
        Class<?> clazz = ccp.toClass();
        clazz.getField("methods").set(null, methods.toArray(new Method[0]));

        // create Proxy class.
        String fcn = Proxy.class.getName() + id;
        ccm = ClassGenerator.newInstance(cl);
        ccm.setClassName(fcn);
        ccm.addDefaultConstructor();
        ccm.setSuperClass(Proxy.class);
        ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
        Class<?> pc = ccm.toClass();
        //这里创建了代理的实例
        proxy = (Proxy) pc.newInstance();
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new RuntimeException(e.getMessage(), e);
    } finally {
        // release ClassGenerator
        if (ccp != null) {
            ccp.release();
        }
        if (ccm != null) {
            ccm.release();
        }
        synchronized (cache) {
            if (proxy == null) {
                cache.remove(key);
            } else {
                cache.put(key, new WeakReference<Proxy>(proxy));
            }
            cache.notifyAll();
        }
    }
    //返回
    return proxy;
}