在第一篇dubbo入门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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="order" />
<!-- 使用multicast广播注册中心暴露服务地址 -->
<dubbo:registry address="N/A"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.order.OrderService" ref="orderService"/>
<!-- 和本地bean一样实现服务 -->
<bean id="orderService" class="com.order.OrderServiceImpl"/>
</beans>
上面的每一项配置项都非常非常重要后面我们慢慢分析。先来分析一下<dubbo:service interface="com.order.OrderService" ref="orderService"/>
这个表示服务端将要暴露OrderService
这个服务想要知道服务端如何暴露服务的需要扎实的Spring基础。我们配置的dubbo服务都是直接嵌入到Spring上下文里面,所以肯定有个东西来衔接dubbo和Spring。从命名空间入手,可以看到我们的dubbo都是使用自己的命名空间。具体Spring自定义命名空间可以参考我的Spring源码系列文章
- XML Schema
- spring自定义命名空间demo
-
Spring如何实现自定义命名空间
有上面3篇文章加持我想你对spring的命名空间应该有了初步的了解。我们可以直接找到dubbo里面的spring.handlers
image.png
所以可以找到处理dubbo命名空间的处理类:DubboNamespaceHandler
public class DubboNamespaceHandler extends NamespaceHandlerSupport {
static {
Version.checkDuplicate(DubboNamespaceHandler.class);
}
@Override
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 AnnotationBeanDefinitionParser());
}
}
上面就是dubbo的所有命名空间。我们是分析暴露服务,所以直接看registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
在Spring容器中所有的dubbo对外暴露的服务都是ServiceBean对象,在注册的时候使用不同的id(采用的是interface作为id进行注册)进行注册不同的ServiceBean对象。在spring容器里面如果需要实例的对象是单例对象那么初始化容器的时候就会实例化。这个动作在finishBeanFactoryInitialization(beanFactory);
的时候处理。让后进行实例化过程。org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
在加载容器的时候会将所有的BeanDefinition注册到DefaultListableBeanFactory
里面所以可以直接获取所有的BeanDefinition数据,
image.png
image.png
网友评论