第四章 Directory

1、Directory类图

Directory是Dubbo对 集群获取可访问服务列表的一个抽象,共有两个实现类,StaticDirectory的子类是个测试类,RegistryDirectory 是对 通过注册中心获取可访问列表的Directory的实现,StaticDirectory是对多注册中心的封装。StaticDirectory中保存了多个集群的Invoker,ClusterInvoker会在后面讲到。可以这么说,RegistryDirectory才是集群可访问列表注册中心版本实现,Static是一个不变的Invoker保存,目前只用于多注册中心访问。

Directory类图

2、Directory核心方法

鉴于StaticDirectory是比较简单的维护List。下面只讨论RegistryDirectory的实现。

list方法是集群Invoker从Directory获取可访问Invoker的核心方法。

List<Invoker<T>> list(Invocation invocation) throws RpcException;

1、RegistryDirectory的doList方法

可以见到是通过methodInvokerMap获取可访问Invoker。那么methodInvokerMap是如何来维护映射关系的呢。
  public List<Invoker<T>> doList(Invocation invocation) {
        if (forbidden) {
            throw new RpcException(RpcException.FORBIDDEN_EXCEPTION, "Forbid consumer " +  NetUtils.getLocalHost() + " access service " + getInterface().getName() + " from registry " + getUrl().getAddress() + " use dubbo version " + Version.getVersion() + ", Please check registry access list (whitelist/blacklist).");
        }
        List<Invoker<T>> invokers = null;
        Map<String, List<Invoker<T>>> localMethodInvokerMap = this.methodInvokerMap; // local reference
        if (localMethodInvokerMap != null && localMethodInvokerMap.size() > 0) {
            String methodName = RpcUtils.getMethodName(invocation);
            Object[] args = RpcUtils.getArguments(invocation);
            if(args != null && args.length > 0 && args[0] != null
                    && (args[0] instanceof String || args[0].getClass().isEnum())) {
                invokers = localMethodInvokerMap.get(methodName + "." + args[0]); // 可根据第一个参数枚举路由
            }
            if(invokers == null) {
                invokers = localMethodInvokerMap.get(methodName);
            }
            if(invokers == null) {
                invokers = localMethodInvokerMap.get(Constants.ANY_VALUE);
            }
            if(invokers == null) {
                Iterator<List<Invoker<T>>> iterator = localMethodInvokerMap.values().iterator();
                if (iterator.hasNext()) {
                    invokers = iterator.next();
                }
            }
        }
        return invokers == null ? new ArrayList<Invoker<T>>(0) : invokers;
    }

2、NotifyListener接口

RegistryDirectory实现了NotifyListener接口,并且在通过Registry订阅provider,router,configuration等category时,调用RegistryService的subscribe方法,把自己注册到NotifyListener列表中,这样每当被订阅的对象发生改变,都会通知RegistryDirectory重新生成可访问Invoker列表,维护上面所说的Map。
NotifyListener

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值