首先,我们知道dubbo在以前都是基于zookeeper作为配置中心的,同时是建立在spring基础之上的。因此,就需要思考一些问题:
首先dubbo是怎样和spring集成的,也即dubbo集成在spring上需要具备什么条件?接着dubbo作为一个服务治理的微服务框架,那它的生产者和消费者与注册中心怎样进行交互的。
dubbo是基于spring的基础之上进行开发的RPC框架。需要和spring整合,必然就需要按照Spring解析默认标签和自定义标签的方式进行。而在Spring中,我们知道在Spring中是在ParseBeanDefintions(Element root,BeanDefintonParserDelegate delegate)方法对默认标签parseDefaultElement(ele,delegate)和自定义标签delegate.parseCustomElement(ele)进行了解析。可以看到对自定义标签的解析:
1.首先拿到命名空间namespaceuri
2.根据命名空间找到对应的NamespaceHandler
3.调用自定义的NamespaceHandler进行解析
而自定义标签的步骤:
1.首先创建一个需要进行扩展的组件
2.定义一个xsd文件描述组件内容
3.创建一个文件,实现BeanDefintionParser接口,用来解析xsd文件中的定义和组件定义
4.创建一个handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到spring容器
5..编写Spring.handlers和spring.schemas文件
也即我们可以通过这个找到dubbo的入口--dubbo-config-spring。
接着我们就可以找到解析schemas文件的BeanDefintionParser和NamespceHandlerSupport了。因此我们首先关注NamespaceHandkerSupport。
//dubbo入口publicclassDubboNamespaceHandlerextendsNamespaceHandlerSupportimplementsConfigurableSourceBeanMetadataElement { static { Version.checkDuplicate(DubboNamespaceHandler.class); } //找到入口,解析Dubbo的相关标签的publicvoidinit() { //将解析好的元素的key-value信息放入到BeanDefintionMap中//registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser);//this.parsers.put(elementName, parser);// DubboBeanDefinitionParser(Class<?> beanClass, boolean required),也是key-value的map形式registerBeanDefinitionParser("application", newDubboBeanDefinitionParser(ApplicationConfig.class, true)); registerBeanDefinitionParser("module", newDubboBeanDefinitionParser(ModuleConfig.class, true)); registerBeanDefinitionParser("registry", newDubboBeanDefinitionParser(RegistryConfig.class, true)); registerBeanDefinitionParser("config-center", newDubboBeanDefinitionParser(ConfigCenterBean.class, true)); registerBeanDefinitionParser("metadata-report", newDubboBeanDefinitionParser(MetadataReportConfig.class, true)); registerBeanDefinitionParser("monitor", newDubboBeanDefinitionParser(MonitorConfig.class, true)); registerBeanDefinitionParser("metrics", newDubboBeanDefinitionParser(MetricsConfig.class, true)); registerBeanDefinitionParser("ssl", newDubboBeanDefinitionParser(SslConfig.class, true)); registerBeanDefinitionParser("provider", newDubboBeanDefinitionParser(ProviderConfig.class, true)); registerBeanDefinitionParser("consumer", newDubboBeanDefinitionParser(ConsumerConfig.class, true)); registerBeanDefinitionParser("protocol", newDubboBeanDefinitionParser(ProtocolConfig.class, true)); registerBeanDefinitionParser("service", newDubboBeanDefinitionParser(ServiceBean.class, true)); registerBeanDefinitionParser("reference", newDubboBeanDefinitionParser(ReferenceBean.class, false)); registerBeanDefinitionParser("annotation", newAnnotationBeanDefinitionParser()); } /*** 复写NamespaceHandlerSupport的parse方法,为注解配置服务* @since 2.7.5*/publicBeanDefinitionparse(Elementelement, ParserContextparserContext) { BeanDefinitionRegistryregistry=parserContext.getRegistry(); //注册注解配置处理器registerAnnotationConfigProcessors(registry); //注册上下文监听器registerApplicationListeners(registry); //进行bena的解析BeanDefinitionbeanDefinition=super.parse(element, parserContext); //设置资源setSource(beanDefinition); returnbeanDefinition; } /*** 将{@link ApplicationListener ApplicationListeners}注册为Spring Bean* @since 2.7.5*/privatevoidregisterApplicationListeners(BeanDefinitionRegistryregistry) { //注册bean dubbo生命周期组件上下文监听registerBeans(registry, DubboLifecycleComponentApplicationListener.class); //注册bean dubbo服务器上下文监听registerBeans(registry, DubboBootstrapApplicationListener.class); } /*** 注册注解配置处理器* @since 2.7.5*/privatevoidregisterAnnotationConfigProcessors(BeanDefinitionRegistryregistry) { AnnotationConfigUtils.registerAnnotationConfigProcessors(registry); } }
从入口,我们可以看到相关配置信息:
ApplicationConfig、ModuleConfig、RegistryConfig、ConfigCenterBean、MetadataReportConfig、MonitorConifg、MetricsConfig、SslConfig、ProviderConfig、ConsumerConfig、ProtocolConfig、ServiceBean、ReferenceBean,还有一个注解解析:new AnnotationBeanDefinitionParser()。这里我们需要重点关注:
ServiceBean、ReferenceBean、ConfigCenterBean、new AnnotationBeanDefintionParser()
而对于相关config的配置,我们来看一个ApplicationConfig,关注两个方法,其余带config的信息都是一些实体类的信息:
//进行刷新操作,继承父类的refreshpublicvoidrefresh() { super.refresh(); appendEnvironmentProperties(); } //调用父类AbstractConfig#refresh方法//进行刷新操作publicvoidrefresh() { //拿到环境变量信息Environmentenv=ApplicationModel.getEnvironment(); try { CompositeConfigurationcompositeConfiguration=env.getPrefixedConfiguration(this); //循环方法,将新的value设置到方法中Method[] methods=getClass().getMethods(); for (Methodmethod : methods) { //setter方法if (MethodUtils.isSetter(method)) { try { Stringvalue=StringUtils.trim(compositeConfiguration.getString(extractPropertyName(getClass(), method))); //调用isTypeMatch()方法以避免重复和不正确的更新,例如,//在ReferenceConfig中我们有两个“ setGeneric”方法。if (StringUtils.isNotEmpty(value) &&ClassUtils.isTypeMatch(method.getParameterTypes()[0], value)) { //在具有指定参数的指定对象上,调用此方法对象表示的基础方法。//各个参数将自动展开以匹配原始形式参数,并且必要时对原始//参数和引用参数都进行方法调用转换。method.invoke(this, ClassUtils.convertPrimitive(method.getParameterTypes()[0], value)); } } catch (NoSuchMethodExceptione) { logger.info("Failed to override the property "+method.getName() +" in "+this.getClass().getSimpleName() +", please make sure every property has getter/setter method provided."); } //参数setter } elseif (isParametersSetter(method)) { Stringvalue=StringUtils.trim(compositeConfiguration.getString(extractPropertyName(getClass(), method))); if (StringUtils.isNotEmpty(value)) { Map<String, String>map=invokeGetParameters(getClass(), this); map=map==null?newHashMap<>() : map; map.putAll(convert(StringUtils.parseParameters(value), "")); invokeSetParameters(getClass(), this, map); } } } } catch (Exceptione) { //复写失败logger.error("Failed to override ", e); } } //添加环境变量配置信息privatevoidappendEnvironmentProperties() { if (parameters==null) { parameters=newHashMap<>(); } //通过扩展加载器进行获取适配器Set<InfraAdapter>adapters=ExtensionLoader.getExtensionLoader(InfraAdapter.class).getSupportedExtensionInstances(); if (CollectionUtils.isNotEmpty(adapters)) { Map<String, String>inputParameters=newHashMap<>(); //包含信息:应用名称和hos以及扩展参数信息inputParameters.put(APPLICATION_KEY, getName()); inputParameters.put(HOST_KEY, getHostname()); for (InfraAdapteradapter : adapters) { //同时将SPI的扩展参数信息信息加入Map<String, String>extraParameters=adapter.getExtraAttributes(inputParameters); if (CollectionUtils.isNotEmptyMap(extraParameters)) { parameters.putAll(extraParameters); } } } }
明天,我们关注ServiceBean、ReferenceBean、ConfigCenterBean、new AnnotationBeanDefintionParser()这四个!