所有的dubbo自定义标签都会由DubboNamespaceHandler处理
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
ReferenceBean
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {
public void afterPropertiesSet() throws Exception {
getObject();
}
public Object getObject() throws Exception {
return get();
}
ReferenceConfig
public synchronized T get() {
init();
private void init() {
ref = createProxy(map);
ReferenceConfig
private T createProxy(Map map) {
invoker = refprotocol.refer(interfaceClass, urls.get(0));
...
return (T) proxyFactory.getProxy(invoker);
主要是:invoker = refprotocol.refer(interfaceClass, urls.get(0));
RegistryProtocol
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
//获取到注册中心的配置信息
Registry registry = registryFactory.getRegistry(url);
...
return doRefer(cluster, registry, type, url);
RegistryProtocol
private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) {
// 把当前url信息当做消费者节点注册到注册中心
registry.register(subscribeUrl.addParameters(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY,
Constants.CHECK_KEY, String.valueOf(false)));
// 订阅服务
directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,
Constants.PROVIDERS_CATEGORY
+ "," + Constants.CONFIGURATORS_CATEGORY
+ "," + Constants.ROUTERS_CATEGORY));
//生成invoker对象
return cluster.join(directory);
调用
InvokerInvocationHandler
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return invoker.invoke(new RpcInvocation(method, args)).recreate();
}
MockClusterInvoker
public Result invoke(Invocation invocation) throws RpcException {
//FailoverClusterInvoker集群容错
result = this.invoker.invoke(invocation);
AbstractClusterInvoker
public Result invoke(final Invocation invocation) throws RpcException {
//在注册中心找到能调用的invoker
List> invokers = list(invocation);
//找到负载均衡机制
if (invokers != null && invokers.size() > 0) {
loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
.getMethodParameter(invocation.getMethodName(),Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
}
return doInvoke(invocation, invokers, loadbalance);
FailoverClusterInvoker
public Result doInvoke(Invocation invocation, final List> invokers, LoadBalance loadbalance) throws RpcException {
//根据负载均衡选中一个invoker
Invoker invoker = select(loadbalance, invocation, copyinvokers, invoked);
//invoker中有filter,如果配置了本地伪装mock、缓存cache、统计等会先执行
Result result = invoker.invoke(invocation);
DubboInvoker
protected Result doInvoke(final Invocation invocation) throws Throwable{
//获取客户端,连接哪个nettyip,端口
if (clients.length == 1) {
currentClient = clients[0];
} else {
currentClient = clients[index.getAndIncrement() % clients.length];
}
//调用netty执行
return (Result) currentClient.request(inv, timeout).get();