通过分析 dubbo demo 的spring xml 配置,初步了解 dubbo的类加载和回顾spring的加载信息
Demo
<?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-2.5.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 和本地bean一样实现服务 -->
<xsi:bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="demo-provider"/>
<!-- 使用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"/>
</beans>
说明
XML Schema命名空间作用:
1、避免命名冲突,像Java中的package一样
2、将不同作用的标签分门别类(像Spring中的tx命名空间针对事务类的标签,context命名空间针对组件的标
签,dubbo 则是dubbo服务的命名空间)
代码解释
1、xmlns="http://www.springframework.org/schema/beans"
声明xml文件默认的命名空间,表示未使用其他命名空间的所有标签的默认命名空间。
2、xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
声明XML Schema 实例,声明后就可以使用 schemaLocation 属性
3、xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
声明前缀为dubbo的命名空间,后面的URL用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用
是赋予命名空间一个惟一的名称。当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与
同一个命名空间相关联。
4、xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
这个从命名可以看出个大概,指定Schema的位置这个属性必须结合命名空间使用。这个属性有两个值,第一个
值表示需要使用的命名空间。第二个值表示供命名空间使用的 XML schema 的位置。
需要什么样的标签的时候,就引入什么样的命名空间和Schema。
spring 加载dubbo 的入口
在dubbo-{version}.jar 中 META-INF/spring.handlers 中可以看到
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
DubboNamespaceHandler 即dubbo 通过spring的handler处理类
DubboNamespaceHandler代码
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));
}
}
上述xml 解析完后,可以大概的看做是如下spring bean 的加载
<bean id="demo-provider" class="com.alibaba.dubbo.config.ApplicationConfig"/>
<bean id="registryConfig" class="com.alibaba.dubbo.config.RegistryConfig">
<property name="address" value="multicast://224.5.6.7:1234"/>
</bean>
<bean id="dubbo" class="com.alibaba.dubbo.config.ProtocolConfig">
<property name="port" value="20880"/>
</bean>
<bean id="com.alibaba.dubbo.demo.DemoService" class="com.alibaba.dubbo.config.spring.ServiceBean">
<property name="interface" value="com.alibaba.dubbo.demo.DemoService"/>
<property name="ref" ref="demoService"/>
</bean>
<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />