publicvoidinit(Stringrule){try{if(rule==null||rule.trim().length()==0){thrownewIllegalArgumentException("Illegal route rule!");}// step1 分割规则,得到匹配器和过滤器rule=rule.replace("consumer.","").replace("provider.","");inti=rule.indexOf("=>");StringwhenRule=i<0?null:rule.substring(0,i).trim();StringthenRule=i<0?rule.trim():rule.substring(i+2).trim();// step2 解析规则,存放为MatchPairMap<String,MatchPair>when=StringUtils.isBlank(whenRule)||"true".equals(whenRule)?newHashMap<String,MatchPair>():parseRule(whenRule);Map<String,MatchPair>then=StringUtils.isBlank(thenRule)||"false".equals(thenRule)?null:parseRule(thenRule);// NOTE: It should be determined on the business level whether the `When condition` can be empty or not.this.whenCondition=when;this.thenCondition=then;}catch(ParseExceptione){thrownewIllegalStateException(e.getMessage(),e);}}
// step1 首先判断当前Consumer是否匹配当前规则if(!matchWhen(url,invocation)){returnnewRouterResult<>(invokers);}// step2 如果过滤规则为空,说明禁用当前的调用者,直接返回空列表List<Invoker<T>>result=newArrayList<Invoker<T>>();if(thenCondition==null){logger.warn("The current consumer in the service blacklist. consumer: "+NetUtils.getLocalHost()+", service: "+url.getServiceKey());returnnewRouterResult<>(result);}// step3 遍历所有Invoker,如果符合规则条件则加入到结果中for(Invoker<T>invoker:invokers){if(matchThen(invoker.getUrl(),url)){result.add(invoker);}}// step4 返回结果if(!result.isEmpty()){returnnewRouterResult<>(result);}elseif(this.isForce()){logger.warn("The route result is empty and force execute. consumer: "+NetUtils.getLocalHost()+", service: "+url.getServiceKey()+", router: "+url.getParameterAndDecoded(RULE_KEY));returnnewRouterResult<>(result);}
// ...BitList<Invoker<T>>result=invokers;Stringtag=StringUtils.isEmpty(invocation.getAttachment(TAG_KEY))?url.getParameter(TAG_KEY):invocation.getAttachment(TAG_KEY);// 如果consumer在调用时指定了tagif(StringUtils.isNotEmpty(tag)){// 获取动态标签规则(配置中心配置)中匹配该tag的所有invoker地址List<String>addresses=tagRouterRuleCopy.getTagnameToAddresses().get(tag);if(CollectionUtils.isNotEmpty(addresses)){result=filterInvoker(invokers,invoker->addressMatches(invoker.getUrl(),addresses));// if result is not null OR it's null but force=true, return result directlyif(CollectionUtils.isNotEmpty(result)||tagRouterRuleCopy.isForce()){returnnewStateRouterResult<>(result,needToPrintMessage?"Use tag "+tag+" to route. Reason: result is not null OR it's null but force=true":null);}}else{// 从invoker的url参数中获取代码指定的标签,获取所有匹配当前标签的路由result=filterInvoker(invokers,invoker->tag.equals(invoker.getUrl().getParameter(TAG_KEY)));}// 如果路由结果不为空或强制使用标签路由,则直接返回过滤结果if(CollectionUtils.isNotEmpty(result)||isForceUseTag(invocation)){returnnewStateRouterResult<>(result,needToPrintMessage?"Use tag "+tag+" to route. Reason: result is not empty or ForceUseTag key is true in invocation":null);}else{// 如果没有找到对应标签的provider,那么返回所有不含标签的providerBitList<Invoker<T>>tmp=filterInvoker(invokers,invoker->addressNotMatches(invoker.getUrl(),tagRouterRuleCopy.getAddresses()));returnnewStateRouterResult<>(filterInvoker(tmp,invoker->StringUtils.isEmpty(invoker.getUrl().getParameter(TAG_KEY))),needToPrintMessage?"FAILOVER: return all Providers without any tags":null);}}else{// 对于调用时不指定标签的情况,将invoker中包含静态标签和动态标签的provider过滤掉List<String>addresses=tagRouterRuleCopy.getAddresses();if(CollectionUtils.isNotEmpty(addresses)){result=filterInvoker(invokers,invoker->addressNotMatches(invoker.getUrl(),addresses));// 1. all addresses are in dynamic tag group, return empty list.if(CollectionUtils.isEmpty(result)){returnnewStateRouterResult<>(result,needToPrintMessage?"all addresses are in dynamic tag group, return empty list":null);}// 2. if there are some addresses that are not in any dynamic tag group, continue to filter using the// static tag group.}returnnewStateRouterResult<>(filterInvoker(result,invoker->{StringlocalTag=invoker.getUrl().getParameter(TAG_KEY);returnStringUtils.isEmpty(localTag)||!tagRouterRuleCopy.getTagNames().contains(localTag);}),needToPrintMessage?"filter using the static tag group":null);}