dubbo是怎么在spring里面解析自定义的标签的
先来了解spring中一个NamespaceHandlerSupport
public abstract class NamespaceHandlerSupport implements NamespaceHandler {
//省略
}
Spring在设计之初就一贯坚持的设计原则:开闭原则:对扩展开放(Open for extension),对修改关闭(Closed for modification)。所以你可以在不修改Spring源代码的情况下扩展Spring的功能。例如新增一个自定义标签
自定义标签的处理流程很简单。
1.获取到命名空间
2.根据命名空间找到对应的命名空间处理器
3.根据用户自定义的处理器进行解析
dubbo中通过DubboNamespaceHandler这个类来解析自定义注解,源码如下
public class DubboNamespaceHandler extends NamespaceHandlerSupport {
public DubboNamespaceHandler() {
}
//使用DubboBeanDefinitionParser作为解析类,把解析出来的标签属性值注入到对应的参数类(每个标签执行一次)(ApplicationConfig,ModuleConfig...)中去
public void init() {
this.registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
this.registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
this.registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
this.registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
this.registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
this.registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
this.registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
this.registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
this.registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
this.registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
}
static {
Version.checkDuplicate(DubboNamespaceHandler.class);
}
}
以dubbo:referencce标签为例,
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean
标签配置的属性,全读出来 ---- set进入ReferenceBean对象,对象实例由IOC容器管理
2.2、ReferenceBean(ServiceBean同理)实现了,initializingBean接口,因此初始化完成时,会调用其afterPropertiesSet方法
2.3、afterPropertiesSet方法内,进行dubbo服务配置(创建消费端的代理对象/服务端的中转对象/向zk注册信息/订阅信息等)
这里会对标签中设置的每个协议,进行一行处理(多个协议时集合大于1)
2.4、协议创建中转对象和消费代理
有几个协议就创建几个中转对象
2.5、dubbo的初始化结构图:主线是ServiceBean和ReferenceBean的初始化
其实就是serviceBean和ReferenceBean实现了spring的InitializingBean接口,在初始化后执行按协议创建中转对象和代理对象的一个过程。