Dubbo介绍2- 源码分析,通过schema启动服务

来源:互联网 发布:mac jenkins 使用教程 编辑:程序博客网 时间:2024/06/08 04:57

前言

spring2.5以后,spring支持自定义schema扩展xml配置。具体的spring schema细节,本文就不多说了。这篇文章就拿provider为例,介绍dubbo是如何启动服务的。

 

正文

首先,再把HelloWolrd例子中的 provider.xml的源码放上来

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
  5.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  6.         http://www.springframework.org/schema/beans/spring-beans.xsd  
  7.         http://code.alibabatech.com/schema/dubbo  
  8.         http://code.alibabatech.com/schema/dubbo/dubbo.xsd  
  9.         ">  
  10.     <dubbo:application name="hello-world-app" />  
  11.     <dubbo:registry  protocol="zookeeper" address="10.125.195.174:2181" />  
  12.     <dubbo:protocol name="dubbo" port="20880" />  
  13.     <dubbo:service interface="demo.service.DemoService"  
  14.                    ref="demoService" />       <!-- 和本地bean一样实现服务 -->  
  15.     <bean id="demoService" class="demo.service.DemoServiceImpl" />  
  16. </beans>  

 对应的自定义schema文件,就不解释了。直接在dubbo-{version}.jar 中 META-INF目录下找到对应的handler配置 

spring.handlers 写道
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

 可以看到,对应的handler是 DubboNamespaceHandler。对应的源码如下

Java代码  收藏代码
  1. public class DubboNamespaceHandler extends NamespaceHandlerSupport {  
  2.   
  3.     static {  
  4.         Version.checkDuplicate(DubboNamespaceHandler.class);  
  5.     }  
  6.   
  7.     public void init() {  
  8.         registerBeanDefinitionParser("application"new DubboBeanDefinitionParser(ApplicationConfig.classtrue));  
  9.         registerBeanDefinitionParser("module"new DubboBeanDefinitionParser(ModuleConfig.classtrue));  
  10.         registerBeanDefinitionParser("registry"new DubboBeanDefinitionParser(RegistryConfig.classtrue));  
  11.         registerBeanDefinitionParser("monitor"new DubboBeanDefinitionParser(MonitorConfig.classtrue));  
  12.         registerBeanDefinitionParser("provider"new DubboBeanDefinitionParser(ProviderConfig.classtrue));  
  13.         registerBeanDefinitionParser("consumer"new DubboBeanDefinitionParser(ConsumerConfig.classtrue));  
  14.         registerBeanDefinitionParser("protocol"new DubboBeanDefinitionParser(ProtocolConfig.classtrue));  
  15.         registerBeanDefinitionParser("service"new DubboBeanDefinitionParser(ServiceBean.classtrue));  
  16.         registerBeanDefinitionParser("reference"new DubboBeanDefinitionParser(ReferenceBean.classfalse));  
  17.         registerBeanDefinitionParser("annotation"new DubboBeanDefinitionParser(AnnotationBean.classtrue));  
  18.     }  
  19.   
  20. }  

 从这里也可以看到,对应的支持的标签其实不多。所有的Parser都封装到了DubboBeanDefinitionParser中。对应的class,就是传入的beanClass。比如application的就是ApplicationConfig。module的就是ModuleConfig。经过Parser的转换,provider.xml大概可以变成如下的样子(具体的解析不多解释了)

Xml代码  收藏代码
  1. <bean id="hello-world-app" class="com.alibaba.dubbo.config.ApplicationConfig"/>  
  2.     <bean id="registryConfig" class="com.alibaba.dubbo.config.RegistryConfig">  
  3.         <property name="address" value="10.125.195.174:2181"/>  
  4.         <property name="protocol" value="zookeeper"/>  
  5.     </bean>  
  6.     <bean id="dubbo" class="com.alibaba.dubbo.config.ProtocolConfig">  
  7.         <property name="port" value="20880"/>  
  8.     </bean>  
  9.     <bean id="demo.service.DemoService" class="com.alibaba.dubbo.config.spring.ServiceBean">  
  10.         <property name="interface" value="demo.service.DemoService"/>  
  11.         <property name="ref" ref="demoService"/>  
  12.     </bean>  
  13.     <bean id="demoService" class="demo.service.DemoServiceImpl" />  

 

分别看每一个bean的内容。由于篇幅原因,我就不把每个代码放上来了。总结一下就是

 

写道
ApplicationConfig,RegistryConfig,ProtocolConfig都只是普通的pojo。负责接收数据。真正的处理逻辑在ServiceBean中

 看具体的代码

Java代码  收藏代码
  1. public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware {  
  2.   
  3.     private static final long serialVersionUID = 213195494150089726L;  
  4.   
  5.     private static transient ApplicationContext SPRING_CONTEXT;  
  6.       
  7.     private transient ApplicationContext applicationContext;  
  8.   
  9.     private transient String beanName;  
  10.   
  11.     private transient boolean supportedApplicationListener;  
  12.       
  13.     public ServiceBean() {  
  14.         super();  
  15.     }  
  16.   
  17.     public ServiceBean(Service service) {  
  18.         super(service);  
  19.     }  
  20.   
  21.     public static ApplicationContext getSpringContext() {  
  22.         return SPRING_CONTEXT;  
  23.     }  
  24.     //设置对应的applicationConext  
  25.     public void setApplicationContext(ApplicationContext applicationContext) {  
  26.         this.applicationContext = applicationContext;  
  27.         SpringExtensionFactory.addApplicationContext(applicationContext);  
  28.         if (applicationContext != null) {  
  29.             SPRING_CONTEXT = applicationContext;  
  30.             try {  
  31.                 Method method = applicationContext.getClass().getMethod("addApplicationListener"new Class<?>[]{ApplicationListener.class}); // 兼容Spring2.0.1  
  32.                 method.invoke(applicationContext, new Object[] {this});  
  33.                 supportedApplicationListener = true;  
  34.             } catch (Throwable t) {  
  35.                 if (applicationContext instanceof AbstractApplicationContext) {  
  36.                     try {  
  37.                         Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener"new Class<?>[]{ApplicationListener.class}); // 兼容Spring2.0.1  
  38.                         if (! method.isAccessible()) {  
  39.                             method.setAccessible(true);  
  40.                         }  
  41.                         method.invoke(applicationContext, new Object[] {this});  
  42.                         supportedApplicationListener = true;  
  43.                     } catch (Throwable t2) {  
  44.                     }  
  45.                 }  
  46.             }  
  47.         }  
  48.     }  
  49.   
  50.     public void setBeanName(String name) {  
  51.         this.beanName = name;  
  52.     }  
  53.   
  54.     public void onApplicationEvent(ApplicationEvent event) {  
  55.         //如果容器加载完成以后当前的provider还没export,那么调用一次export方法(这个针对那种延迟export的情况)  
  56.         if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {  
  57.             if (isDelay() && ! isExported() && ! isUnexported()) {  
  58.                 if (logger.isInfoEnabled()) {  
  59.                     logger.info("The service ready on spring started. service: " + getInterface());  
  60.                 }  
  61.                 export();  
  62.             }  
  63.         }  
  64.     }  
  65.     //是否延迟export  
  66.     private boolean isDelay() {  
  67.         Integer delay = getDelay();  
  68.         ProviderConfig provider = getProvider();  
  69.         if (delay == null && provider != null) {  
  70.             delay = provider.getDelay();  
  71.         }  
  72.         return supportedApplicationListener && (delay == null || delay.intValue() == -1);  
  73.     }  
  74.   
  75.     @SuppressWarnings({ "unchecked""deprecation" })  
  76.     public void afterPropertiesSet() throws Exception {  
  77.         //这里的Provider其实就是ProviderConfig对象。如果provider为空,表示spring在创建 当前bean的时候还没有初始化ProtocolConfig bean。这里就是做一个前后顺序保证  
  78.         if (getProvider() == null) {  
  79.             Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null  : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.classfalsefalse);  
  80.             if (providerConfigMap != null && providerConfigMap.size() > 0) {  
  81.                 Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null  : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.classfalsefalse);  
  82.                 if ((protocolConfigMap == null || protocolConfigMap.size() == 0)  
  83.                         && providerConfigMap.size() > 1) { // 兼容旧版本  
  84.                     List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();  
  85.                     for (ProviderConfig config : providerConfigMap.values()) {  
  86.                         if (config.isDefault() != null && config.isDefault().booleanValue()) {  
  87.                             providerConfigs.add(config);  
  88.                         }  
  89.                     }  
  90.                     if (providerConfigs.size() > 0) {  
  91.                         setProviders(providerConfigs);  
  92.                     }  
  93.                 } else {  
  94.                     ProviderConfig providerConfig = null;  
  95.                     for (ProviderConfig config : providerConfigMap.values()) {  
  96.                         if (config.isDefault() == null || config.isDefault().booleanValue()) {  
  97.                             if (providerConfig != null) {  
  98.                                 throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);  
  99.                             }  
  100.                             providerConfig = config;  
  101.                         }  
  102.                     }  
  103.                     if (providerConfig != null) {  
  104.                         setProvider(providerConfig);  
  105.                     }  
  106.                 }  
  107.             }  
  108.         }  
  109.         //这里和上面同样,手动创建ApplicationConfig bean  
  110.         if (getApplication() == null  
  111.                 && (getProvider() == null || getProvider().getApplication() == null)) {  
  112.             Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.classfalsefalse);  
  113.             if (applicationConfigMap != null && applicationConfigMap.size() > 0) {  
  114.                 ApplicationConfig applicationConfig = null;  
  115.                 for (ApplicationConfig config : applicationConfigMap.values()) {  
  116.                     if (config.isDefault() == null || config.isDefault().booleanValue()) {  
  117.                         if (applicationConfig != null) {  
  118.                             throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);  
  119.                         }  
  120.                         applicationConfig = config;  
  121.                     }  
  122.                 }  
  123.                 if (applicationConfig != null) {  
  124.                     setApplication(applicationConfig);  
  125.                 }  
  126.             }  
  127.         }  
  128.         //如果没有创建module,则手动创建 module。 在HelloWorld例子中,没有用到module。  
  129.         if (getModule() == null  
  130.                 && (getProvider() == null || getProvider().getModule() == null)) {  
  131.             Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.classfalsefalse);  
  132.             if (moduleConfigMap != null && moduleConfigMap.size() > 0) {  
  133.                 ModuleConfig moduleConfig = null;  
  134.                 for (ModuleConfig config : moduleConfigMap.values()) {  
  135.                     if (config.isDefault() == null || config.isDefault().booleanValue()) {  
  136.                         if (moduleConfig != null) {  
  137.                             throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);  
  138.                         }  
  139.                         moduleConfig = config;  
  140.                     }  
  141.                 }  
  142.                 if (moduleConfig != null) {  
  143.                     setModule(moduleConfig);  
  144.                 }  
  145.             }  
  146.         }  
  147.         //初始化registiry  
  148.         if ((getRegistries() == null || getRegistries().size() == 0)  
  149.                 && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().size() == 0)  
  150.                 && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {  
  151.             Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.classfalsefalse);  
  152.             if (registryConfigMap != null && registryConfigMap.size() > 0) {  
  153.                 List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();  
  154.                 for (RegistryConfig config : registryConfigMap.values()) {  
  155.                     if (config.isDefault() == null || config.isDefault().booleanValue()) {  
  156.                         registryConfigs.add(config);  
  157.                     }  
  158.                 }  
  159.                 if (registryConfigs != null && registryConfigs.size() > 0) {  
  160.                     super.setRegistries(registryConfigs);  
  161.                 }  
  162.             }  
  163.         }  
  164.         //初始化monitor (HelloWorld例子中没有用到)  
  165.         if (getMonitor() == null  
  166.                 && (getProvider() == null || getProvider().getMonitor() == null)  
  167.                 && (getApplication() == null || getApplication().getMonitor() == null)) {  
  168.             Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.classfalsefalse);  
  169.             if (monitorConfigMap != null && monitorConfigMap.size() > 0) {  
  170.                 MonitorConfig monitorConfig = null;  
  171.                 for (MonitorConfig config : monitorConfigMap.values()) {  
  172.                     if (config.isDefault() == null || config.isDefault().booleanValue()) {  
  173.                         if (monitorConfig != null) {  
  174.                             throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);  
  175.                         }  
  176.                         monitorConfig = config;  
  177.                     }  
  178.                 }  
  179.                 if (monitorConfig != null) {  
  180.                     setMonitor(monitorConfig);  
  181.                 }  
  182.             }  
  183.         }  
  184.         //初始化protocol   
  185.         if ((getProtocols() == null || getProtocols().size() == 0)  
  186.                 && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().size() == 0)) {  
  187.             Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null  : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.classfalsefalse);  
  188.             if (protocolConfigMap != null && protocolConfigMap.size() > 0) {  
  189.                 List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();  
  190.                 for (ProtocolConfig config : protocolConfigMap.values()) {  
  191.                     if (config.isDefault() == null || config.isDefault().booleanValue()) {  
  192.                         protocolConfigs.add(config);  
  193.                     }  
  194.                 }  
  195.                 if (protocolConfigs != null && protocolConfigs.size() > 0) {  
  196.                     super.setProtocols(protocolConfigs);  
  197.                 }  
  198.             }  
  199.         }  
  200.         //设置服务名称。  
  201.         if (getPath() == null || getPath().length() == 0) {  
  202.             if (beanName != null && beanName.length() > 0   
  203.                     && getInterface() != null && getInterface().length() > 0  
  204.                     && beanName.startsWith(getInterface())) {  
  205.                 setPath(beanName);  
  206.             }  
  207.         }  
  208.         //调用export  
  209.         if (! isDelay()) {  
  210.             export();  
  211.         }  
  212.     }  
  213.     //调用unexport  
  214.     public void destroy() throws Exception {  
  215.         unexport();  
  216.     }  
  217.   
  218. }  

 

代码里面已经加了一些注释。虽然很长,逻辑还是很简单的。其中用到了spring的很多特性。非常值得我们学习。

 

很明显,下一篇就要介绍 核心的 export 和unexport方法了。


原文地址:http://chenjingbo.iteye.com/blog/2008325

0 0