dubbo是基于Spring的IOC实现的,了解其流程有助于更好的把握dubbo的架构脉络,因此对着dubbo的代码整理了需要用到的spring知识。
一、springIOC的初始化流程
spring的ClassPathXmlApplicationContext
在初始化时,工作内容主要在其父类AbstractApplicationContext#refresh
方法,粘贴其实现。
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
和dubbo相关比较大的步骤有:
1.1 obtainFreshBeanFactory 获取beanFactory,并加载配置文件集中的bean。
1.2 finishBeanFactoryInitialization 给单例的且未延迟加载的bean创建实例。如果创建一个bean的时候,继承了
FactoryBean
,那么在实例化的时候会调用其getObject
来获取bean对象。dubbo中正是通过这种方法配合动态代理来生成comsumer中的reference
对象。1.3 finishRefresh 在bean的初始化工作都完成的时候调用,并给实现了
ApplicationListener
接口的bean通知一个ContextRefreshedEvent
事件。应用在dubbo中,provider的ServerBean在完成bean的初始化后,会调用export
来连接注册中心,暴露socket服务。
命名空间
dubbo 在META-INF/spring.handlers
中自定义了自己的命名空间http://code.alibabatech.com/schema/dubbo
,通过其xsd
描述文件或者对应的命名空间处理类初始化方法DubboNamespaceHandler#init
可以看到,dubbo一共支持类型application
,module
,registry
,monitor
,provider
,consumer
,service
,protocol
,service
,reference
,annotation
类型节点的解析。除了annotation
的解析器是AnnotationBeanDefinitionParser
,其他九种节点类型的解析器均是DubboBeanDefinitionParser
。
Spring在步骤1.1obtainFreshBeanFactory
的时候会根据节点名称用对应的解析器(此处为dubbo自定义解析器)的parse
方法,在parse
方法中,调用parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
将beanName和对应的bean模型放入Spring管理。
自定义命名空间的作用:配合dubbo无入侵式rpc的实现,于comsumer:将consumer中配置的接口获取到的bean对象转换为referenceBean
生成的代理,当调用了接口的方法时,实际上借助代理通过网络进行远程接口调用。于provider: