- 浏览: 350138 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
无红墙:
另一种修改,请参考:https://github.com/ta ...
Dubbo不能优雅停机,导致停止服务的时候,业务掉单 -
fish_no7:
if (handler instanceof WrappedC ...
Dubbo不能优雅停机,导致停止服务的时候,业务掉单 -
frankfan915:
lizhou828 写道怎么解决?设置NetTimeoutFo ...
Communications link failure错误分析 -
lizhou828:
怎么解决?
Communications link failure错误分析 -
frankfan915:
ileson 写道 解决办法sh设置NetTimeoutFo ...
Communications link failure错误分析
dubbo的官方網站為:
http://code.alibabatech.com/wiki/display/dubbo/User+Guide#UserGuide-ServiceProvider
这个章节分析Dubbo的configure模块。
Spring启动的时候,会到spring.handlers文件中查找相应的namespacehandler, 并将其存入到mapping中。如Dubbo中的配置为:
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
当我们自定义的namespace中包含xmlns为http://code.alibabatech.com/schema/dubbo时,其相应的bean都会通过DubboNamespaceHandler这个类来构建。例如下面是provider.xml的配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd "> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="hello-world-app" /> <!-- 使用multicast广播注册中心暴露服务地址 --> <dubbo:registry address="multicast://224.5.6.7:1234" /> <!-- 用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 声明需要暴露的服务接口 --> <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" /> <!-- 和本地bean一样实现服务 --> <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" /> </beans>
接下来查看DubboNamespaceHandler的源代码,我们可以知道DubboNamespaceHandler继成了NamespaceHandlerSupport,并且在init方法里面注册了不同configure对象的DubboBeanDefinitionParser.
public class DubboNamespaceHandler extends NamespaceHandlerSupport { static { Version.checkDuplicate(DubboNamespaceHandler.class); } public void init() { registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true)); registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true)); registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true)); registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true)); registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true)); registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true)); registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true)); registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true)); registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false)); registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true)); } }
|
当spring解析provider.xml文件时, 当其解析 <dubbo:application name="hello-world-app" />这句配置时,spring会将这句配置封装成一个element对象,在NamespaceHandlerSupport类中findParserForElement(element, parserContext).parse(element, parserContext); 按照相应的localname查找parser(此时的localname为application)。查找到的对象为DubboNamespaceHandler 中创建的new DubboBeanDefinitionParser(ApplicationConfig.class, true)); 对象。
接下来调用DubboBeanDefinitionParser中的parse函数,将配置设置到beanDefinition中,最后通过spring创建相应的bean。
private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) { RootBeanDefinition beanDefinition = new RootBeanDefinition(); beanDefinition.setBeanClass(beanClass); beanDefinition.setLazyInit(false); String id = element.getAttribute("id"); if ((id == null || id.length() == 0) && required) { String generatedBeanName = element.getAttribute("name"); if (generatedBeanName == null || generatedBeanName.length() == 0) { if (ProtocolConfig.class.equals(beanClass)) { generatedBeanName = "dubbo"; } else { generatedBeanName = element.getAttribute("interface"); } } if (generatedBeanName == null || generatedBeanName.length() == 0) { generatedBeanName = beanClass.getName(); } id = generatedBeanName; int counter = 2; while(parserContext.getRegistry().containsBeanDefinition(id)) { id = generatedBeanName + (counter ++); } } if (id != null && id.length() > 0) { if (parserContext.getRegistry().containsBeanDefinition(id)) { throw new IllegalStateException("Duplicate spring bean id " + id); } //如果ID不冲突,注册bean definition parserContext.getRegistry().registerBeanDefinition(id, beanDefinition); beanDefinition.getPropertyValues().addPropertyValue("id", id); } if (ProtocolConfig.class.equals(beanClass)) { for (String name : parserContext.getRegistry().getBeanDefinitionNames()) { BeanDefinition definition = parserContext.getRegistry().getBeanDefinition(name); PropertyValue property = definition.getPropertyValues().getPropertyValue("protocol"); if (property != null) { Object value = property.getValue(); if (value instanceof ProtocolConfig && id.equals(((ProtocolConfig) value).getName())) { definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id)); } } } } else if (ServiceBean.class.equals(beanClass)) { String className = element.getAttribute("class"); if(className != null && className.length() > 0) { RootBeanDefinition classDefinition = new RootBeanDefinition(); classDefinition.setBeanClass(ReflectUtils.forName(className)); classDefinition.setLazyInit(false); parseProperties(element.getChildNodes(), classDefinition); beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl")); } } else if (ProviderConfig.class.equals(beanClass)) { parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition); } else if (ConsumerConfig.class.equals(beanClass)) { parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition); } Set<String> props = new HashSet<String>(); ManagedMap parameters = null; for (Method setter : beanClass.getMethods()) { String name = setter.getName(); if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(setter.getModifiers()) && setter.getParameterTypes().length == 1) { Class<?> type = setter.getParameterTypes()[0]; String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), "-"); props.add(property); Method getter = null; try { getter = beanClass.getMethod("get" + name.substring(3), new Class<?>[0]); } catch (NoSuchMethodException e) { try { getter = beanClass.getMethod("is" + name.substring(3), new Class<?>[0]); } catch (NoSuchMethodException e2) { } } if (getter == null || ! Modifier.isPublic(getter.getModifiers()) || ! type.equals(getter.getReturnType())) { continue; } if ("parameters".equals(property)) { parameters = parseParameters(element.getChildNodes(), beanDefinition); } else if ("methods".equals(property)) { parseMethods(id, element.getChildNodes(), beanDefinition, parserContext); } else if ("arguments".equals(property)) { parseArguments(id, element.getChildNodes(), beanDefinition, parserContext); } else { String value = element.getAttribute(property); if (value != null) { value = value.trim(); if (value.length() > 0) { if ("registry".equals(property) && RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(value)) { RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress(RegistryConfig.NO_AVAILABLE); beanDefinition.getPropertyValues().addPropertyValue(property, registryConfig); } else if ("registry".equals(property) && value.indexOf(',') != -1) { parseMultiRef("registries", value, beanDefinition, parserContext); } else if ("provider".equals(property) && value.indexOf(',') != -1) { parseMultiRef("providers", value, beanDefinition, parserContext); } else if ("protocol".equals(property) && value.indexOf(',') != -1) { parseMultiRef("protocols", value, beanDefinition, parserContext); } else { Object reference; if (isPrimitive(type)) { if ("async".equals(property) && "false".equals(value) || "timeout".equals(property) && "0".equals(value) || "delay".equals(property) && "0".equals(value) || "version".equals(property) && "0.0.0".equals(value) || "stat".equals(property) && "-1".equals(value) || "reliable".equals(property) && "false".equals(value)) { // 兼容旧版本xsd中的default值 value = null; } reference = value; } else if ("protocol".equals(property) && ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(value) && (! parserContext.getRegistry().containsBeanDefinition(value) || ! ProtocolConfig.class.getName().equals(parserContext.getRegistry().getBeanDefinition(value).getBeanClassName()))) { if ("dubbo:provider".equals(element.getTagName())) { logger.warn("Recommended replace <dubbo:provider protocol=\"" + value + "\" ... /> to <dubbo:protocol name=\"" + value + "\" ... />"); } // 兼容旧版本配置 ProtocolConfig protocol = new ProtocolConfig(); protocol.setName(value); reference = protocol; } else if ("monitor".equals(property) && (! parserContext.getRegistry().containsBeanDefinition(value) || ! MonitorConfig.class.getName().equals(parserContext.getRegistry().getBeanDefinition(value).getBeanClassName()))) { // 兼容旧版本配置 reference = convertMonitor(value); } else if ("onreturn".equals(property)) { int index = value.lastIndexOf("."); String returnRef = value.substring(0, index); String returnMethod = value.substring(index + 1); reference = new RuntimeBeanReference(returnRef); beanDefinition.getPropertyValues().addPropertyValue("onreturnMethod", returnMethod); } else if ("onthrow".equals(property)) { int index = value.lastIndexOf("."); String throwRef = value.substring(0, index); String throwMethod = value.substring(index + 1); reference = new RuntimeBeanReference(throwRef); beanDefinition.getPropertyValues().addPropertyValue("onthrowMethod", throwMethod); } else { if ("ref".equals(property) && parserContext.getRegistry().containsBeanDefinition(value)) { BeanDefinition refBean = parserContext.getRegistry().getBeanDefinition(value); if (! refBean.isSingleton()) { throw new IllegalStateException("The exported service ref " + value + " must be singleton! Please set the " + value + " bean scope to singleton, eg: <bean id=\"" + value+ "\" scope=\"singleton\" ...>"); } } reference = new RuntimeBeanReference(value); } beanDefinition.getPropertyValues().addPropertyValue(property, reference); } } } } } } NamedNodeMap attributes = element.getAttributes(); int len = attributes.getLength(); for (int i = 0; i < len; i++) { Node node = attributes.item(i); String name = node.getLocalName(); if (! props.contains(name)) { if (parameters == null) { parameters = new ManagedMap(); } String value = node.getNodeValue(); parameters.put(name, new TypedStringValue(value, String.class)); } } if (parameters != null) { beanDefinition.getPropertyValues().addPropertyValue("parameters", parameters); } return beanDefinition; }
|
当spring的AbstractApplicationContext类调用方法obtainFreshBeanFactory生成所以的beandefinition。registerListeners方法将注册实现了applicationListener的类,因为ServiceBean类实现了ApplicationListener接口,serviceBean将被预先被实例化。又因为serviceBean实现了initialBean接口,在serviceBean被实例化后,将调用serviceBean的afterPropertiesSet方法。最后将实例化后的serviceBean对象加到添加到applicationListener的类表中。
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); }
|
afterPropertiesSet方法中实例化各个configure对象,如providerConfigure等,并将对象设置到ServiceBean中。
public void afterPropertiesSet() throws Exception { if (getProvider() == null) { Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false); if (providerConfigMap != null && providerConfigMap.size() > 0) { Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false); if ((protocolConfigMap == null || protocolConfigMap.size() == 0) && providerConfigMap.size() > 1) { // 兼容旧版本 List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>(); for (ProviderConfig config : providerConfigMap.values()) { if (config.isDefault() != null && config.isDefault().booleanValue()) { providerConfigs.add(config); } } if (providerConfigs.size() > 0) { setProviders(providerConfigs); } } else { ProviderConfig providerConfig = null; for (ProviderConfig config : providerConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (providerConfig != null) { throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config); } providerConfig = config; } } if (providerConfig != null) { setProvider(providerConfig); } } } } if (getApplication() == null && (getProvider() == null || getProvider().getApplication() == null)) { Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false); if (applicationConfigMap != null && applicationConfigMap.size() > 0) { ApplicationConfig applicationConfig = null; for (ApplicationConfig config : applicationConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (applicationConfig != null) { throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config); } applicationConfig = config; } } if (applicationConfig != null) { setApplication(applicationConfig); } } } if (getModule() == null && (getProvider() == null || getProvider().getModule() == null)) { Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false); if (moduleConfigMap != null && moduleConfigMap.size() > 0) { ModuleConfig moduleConfig = null; for (ModuleConfig config : moduleConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (moduleConfig != null) { throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config); } moduleConfig = config; } } if (moduleConfig != null) { setModule(moduleConfig); } } } if ((getRegistries() == null || getRegistries().size() == 0) && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().size() == 0) && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) { Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false); if (registryConfigMap != null && registryConfigMap.size() > 0) { List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>(); for (RegistryConfig config : registryConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { registryConfigs.add(config); } } if (registryConfigs != null && registryConfigs.size() > 0) { super.setRegistries(registryConfigs); } } } if (getMonitor() == null && (getProvider() == null || getProvider().getMonitor() == null) && (getApplication() == null || getApplication().getMonitor() == null)) { Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false); if (monitorConfigMap != null && monitorConfigMap.size() > 0) { MonitorConfig monitorConfig = null; for (MonitorConfig config : monitorConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (monitorConfig != null) { throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config); } monitorConfig = config; } } if (monitorConfig != null) { setMonitor(monitorConfig); } } } if ((getProtocols() == null || getProtocols().size() == 0) && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().size() == 0)) { Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false); if (protocolConfigMap != null && protocolConfigMap.size() > 0) { List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>(); for (ProtocolConfig config : protocolConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { protocolConfigs.add(config); } } if (protocolConfigs != null && protocolConfigs.size() > 0) { super.setProtocols(protocolConfigs); } } } if (getPath() == null || getPath().length() == 0) { if (beanName != null && beanName.length() > 0 && getInterface() != null && getInterface().length() > 0 && beanName.startsWith(getInterface())) { setPath(beanName); } } if (! isDelay()) { export(); } }
|
当AbstractApplicationContext 类调用finishRefresh方法后,将publish 一个ContextRefreshedEvent的通知。因为serviceBean注册了applicationListener,那么serviceBean将接收到contextRefreshedEvent的通知。将调用ServiceBean的onApplicationEvent方法。最后调用export方法暴露接口。
protected synchronized void doExport() { //检查各种配置 checkApplication(); checkRegistry(); checkProtocol(); appendProperties(this); checkStubAndMock(interfaceClass); if (path == null || path.length() == 0) { path = interfaceName; } //暴露 doExportUrls(); }
private void doExportUrls() {
List<URL> registryURLs = loadRegistries(true);
for (ProtocolConfig protocolConfig : protocols) {
//export
doExportUrlsFor1Protocol(protocolConfig, registryURLs);
}
}
|
|
发表评论
-
concurrent- LinkedBlockingQueue
2014-08-03 16:46 0LinkedBlockingQueue 是用lock和co ... -
flume源码分析-Sink
2014-07-14 17:01 1884Sink 将从channel接收event,然后将event ... -
flume源码分析-SinkProcessor
2014-07-14 15:28 2801flume包括三种sink processor,Defaul ... -
flume源码分析-ChannelSelector
2014-07-14 14:22 1636flume自带两种channelSelector。一种是Mu ... -
Spark源码分析13-Tuning Spark
2014-05-15 17:48 2507We can refer to the link http ... -
Spark源码分析12-yarn部署
2014-05-13 22:08 820明天写 -
Spark源码分析11-BlockManager
2014-05-13 22:06 1148BlockManager主要在deriver和excuto ... -
Spark源码分析9-Excutor
2014-05-11 10:48 3527Excutor主要分为两部分,一是ExecutorBacke ... -
Spark源码分析8-client 如何选择将task提交给那个excutor
2014-05-08 15:33 2758spark中很重要的一点就是task具体分配到哪个excu ... -
Spark源码分析7-Metrics的分析
2014-05-08 11:37 2031spark用metrics-core这个jar包来做spa ... -
Spark源码分析6-Worker
2014-05-08 11:31 1882Worker 主要负责管理excutor和driver,并向 ... -
Spark源码分析5-Master
2014-05-07 11:15 2497本节主要分析Master 的主要功能。 Master主要 ... -
Spark源码分析4-RDD computor
2014-05-06 14:46 977Excutor在接收到task后会调用RDD的comput ... -
Spark源码分析3-The connect between driver,master and excutor
2014-05-06 14:41 733这一节讲述的是driver,master,excu ... -
Spark源码分析2-Driver generate jobs and launch task
2014-05-06 14:34 1372Driver generate jobs and laun ... -
Spark源码分析1-部署与整体架构
2014-05-06 10:26 3557Spark官网:http://spark.apache.o ...
相关推荐
dubbo示例代码dubbo-sample
Dubbo视频教程--基础篇源代码6-10,是新手入门比较好的代码样例
Dubbo视频教程--高级篇--第24节--简易版支付系统介绍Dubbo视频教程--高级篇--第24节--简易版支付系统介绍
jmeter的dubbo插件,jmeter-plugins-dubbo-2.7.8-jar-with-dependencies.jar,适用于JMeter5.4.1版本,将解压后的文件jmeter-plugins-dubbo-2.7.8-jar-with-dependencies放在Jmeter安装目录下的\lib\ext文件夹中,...
Dubbo的源代码打包,dubbo-monitor-simple-2.5.8 本人亲测,可以编译通过。
该包为dubbo-monitor,使用方法请参见博文 《Dubbo进阶(五)—— dubbo-monitor-simple使用》 https://blog.csdn.net/sunhuaqiang1/article/details/80141478
Dubbo视频教程--基础篇--第01节--使用Dubbo对传统工程进行服务化改造的思路介绍--传工程源码.rar Dubbo视频教程--基础篇--第04节--使用Dubbo对传统工程进行服务化改造后的服务调用测试--源码.rar Dubbo视频教程--001...
2.dubbo-admin-2.4.1.war 管理控制台项目 3.dubbo-demo-consumer-2.1.5-assembly.tar.gz dubbo消费者示例项目 4.dubbo-demo-provider-2.1.5-assembly.tar.gz dubbo服务提供者示例项目 5.dubbo-monitor-simple-2.5.3-...
Dubbo视频教程--高可用架构篇
tomcat-dubbo里包含dubbo-admin tomcat-dubbo里包含dubbo-admin
dubbo源码dubbo-dubbo-2.7.3.rardubbo源码dubbo-dubbo-2.7.3.rardubbo源码dubbo-dubbo-2.7.3.rardubbo源码dubbo-dubbo-2.7.3.rardubbo源码dubbo-dubbo-2.7.3.rardubbo源码dubbo-dubbo-2.7.3.rardubbo源码dubbo-dubbo...
jmeter-plugins-dubbo-2.7.1-jar-with-dependencies 系统压测工具包
dobbo源码dubbo-dubbo-2.7.3.rardobbo源码dubbo-dubbo-2.7.3.rardobbo源码dubbo-dubbo-2.7.3.rardobbo源码dubbo-dubbo-2.7.3.rardobbo源码dubbo-dubbo-2.7.3.rardobbo源码dubbo-dubbo-2.7.3.rardobbo源码dubbo-dubbo...
Dubbo(二)------Dubbo入门示例 https://blog.csdn.net/qq_29914837/article/details/102980012
这是Dubbo分布式框架的一个管理监控中心,可以实时监控分布式项目的资源情况
dubbo最新版本dubbo-admin-2.5.5.war控制台 ,谢谢大家
dubbo-admin-2.5.4-SNAPSHOT,dubbo的后台管理war,可以通过这个查看到注册中心的消费提供着和消费者,还有监测着的信息
dubbo官方自带了dubbo-admin及dubbo-simple/dubbo-monitor-simple二个子项目用于服务治理及服务监控。 dubbo-monitor-simple是Alibaba的开源项目,用于监控在dubbo框架下接口暴露,注册情况,也可以看接口的调用...
dubbo-admin-2.5.4提供支持JDK1.7及JDK1.8的War包 Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看...
dubbo-monitor-simple-2.5.8-assembly-DUBBO监控工具,