Dubbo的xml命名空间解析关键

在Spring中的applicationContext.xml经常看到如下标签

<dubbo:service ref="userInfoService" interface="com.kxtry.dubbo.service.UserInfoService" />
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<dubbo:registry address="zookeeper://mysql.vmware.com:2181" ></dubbo:registry>
<dubbo:application name="com.kxtry.dubbo.demo"/>

1.Dubbo创建了一个dubbo.xsd文件。
2.并为dubbo.xsd创建了另外两个文件:spring.handlers和spring.schemas(这是Spring的命名解析规范要求),Spring在解析过程中会主动搜索这两资源文件。

3.spring.handlers文件内容如下

http://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

4.spring.schemas文件内容如下

http://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd

5.在执行下面代码时,会主动触发相关文件解析。

String configure = "provider-applicationContext.xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(configure);



6.具体如下:

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));
    }
}

7.上述步骤,已经完成了beanmap列表的建立,但仍需要下述代码,触发Dubbo的建立RPC服务,其中xxxConfig是在xxxBean之前先创建的。

context.start();
context.registerShutdownHook();

8.在6步骤中的的ServiceBean中监听了ApplicationEvent如下:

public void onApplicationEvent(ApplicationEvent event) {
        if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
        	if (isDelay() && ! isExported() && ! isUnexported()) {
                if (logger.isInfoEnabled()) {
                    logger.info("The service ready on spring started. service: " + getInterface());
                }
                会把xxxConfig的内容,初始化ServiceBean里的对象。
                export();
            }
        }
    }

9.serviceBean是多个的,每个service对象,对应一个,故每个对象都监听了ApplicationEvent。

<dubbo:service ref="userInfoService" interface="com.kxtry.dubbo.service.UserInfoService" />
    <dubbo:service ref="boyInfoService" interface="com.kxtry.dubbo.service.BoyInfoService" />
    <dubbo:service ref="girlInfoService" interface="com.kxtry.dubbo.service.GirlInfoService" />
    <bean id="userInfoService" class="com.kxtry.dubbo.service.impl.UserInfoServiceImpl" />
    <bean id="girlInfoService" class="com.kxtry.dubbo.service.impl.GirlInfoServiceImpl" />
    <bean id="boyInfoService" class="com.kxtry.dubbo.service.impl.BoyInfoServiceImpl" />