dubbo分析
dubbo 与spring 整合提供全spring 的配置,下面分析。这一过程。
通过spring 的obtainBeanFactory 方法的解析,了解到在 doLoadBeanDefinition 的时候,在遇到非基础明明空间下的 元素的时候,需要先找到相应的明明空间,这一过程大概是 spring 命名解析器通过伪 SPI 获取到所有的命名空间处理器,并将其缓存在 map中,根据命名空间名称,获取到 命名空间Handler,然后调用其 init 方法,这个方法会注册与该命名空间相关的所有的 BeanDefinitionPhaser。然后遍历所有phaser 通过sport 方法,获取该元素的解析器,对该元素进行处理。
知道了这些,我们可以直接在 dubbo 的 com.alibaba.dubbo.config.spring.schema 包下面 找到这个 dubboNameSpaceHandler。
java
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());
}
}
可以看到,所有的元素解析器,在这个类下进行注册。
在配置 xml的时候,首先都是把 application 元素放在上方。那么就把它当做切入点分析。元素解析器都要在 phaser 方法里面进行处理逻辑。但是dubbo 把除了处理注解的所有逻辑都放到一起了。这么做的好处就是,这些元素谁在前面都会执行 dubbo 的初始化逻辑。。。
parse 方法将近 200 行,分段分析。
java
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++);
}
}
开头这一部分创建了 RootBeanDefinition。然后获取元素的 name 属性,为beanDefinition 的名称赋值。如果已经注册了该名称的beanDefinition,则通过 counter 解决重名问题。
java
if (id != null && id.length() > 0) {
if (parserContext.getRegistry().containsBeanDefinition(id)) {
throw new Ille
