Dubbo之旅--启动解析
来源:互联网 发布:imo是什么软件 编辑:程序博客网 时间:2024/06/13 22:17
通过之前系列文章我们已经对Dubbo已经有了一个整体的印象,接下来我们从其他角度来进一步了解它.Dubbo通过Spring的加载而启动,本文分析了通过注解方式加载的过程.
1.Schema扩展
通过注解加载dubbo,需要在spring的配置文件中添加:
<dubbo:annotationpackage="com.package.to.be.scanned" />
dubbo:annotation是dubbo基于spring的schema扩展。
dubbo的schema描述文件在dubbo-config-spring模块下。我们可以看到在其中定义的xml描述信息。
Spring会默认加载spring.handlers和spring.schemas,从而感知schema描述文档。从中我们可以看到schema的处理器:com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
DubboNamespaceHandler继承了NamespaceHandlerSupport。因此不需要实现所有的解析工作,只要将自定义schema中的元素解析器注册进来就可以。
public void init() {
registerBeanDefinitionParser("application", newDubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", newDubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", newDubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", newDubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("provider", newDubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", newDubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", newDubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", newDubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", newDubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", newDubboBeanDefinitionParser(AnnotationBean.class, true));
}
在代码中我们可以看到被注册的annotation解析器:DubboBeanDefinitionParser。Parser中的privatestaticBeanDefinition parse()方法实现了解析,并返回解析后生成bean的定义。接下来我们就看一下dubbodubbo:annotation的加载过程。
2. Dubbo 自定义元素加载
Spring启动后,加载配置文件信息,得到dubbo的schema元素定义信息:<dubbo:annotation package="com.package.to.be.scanned" />
根据DubboNamespaceHandler中注册的信息,spring找到解析类并调用解析方法:DubboBeanDefinitionParser.Parse()。
第一步,初始化RootBeanDefinition
第二步,获取beanid
第三步,将xml中配置的信息放到beandefinition的PropertyValues中。
最后返回AnnotationBean的BeanDefinition。
至此,annotation对应的bean定义解析完毕,spring知晓了AnnotationBean的存在。
3. AnnotationBean运行
AnnotationBean实现了很多spring的特殊bean接口:DisposableBean,BeanFactoryPostProcessor,BeanPostProcessor,ApplicationContextAware。这保证AnnotationBean能够在spring加载的各个时期实现自己的功能。
注解扫描的功能在beanfactory初始化完成调用接口BeanFactoryPostProcessor.postProcessBeanFactory中实现。
实现代码:
public voidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
if (annotationPackage == null ||annotationPackage.length() == 0) {
return;
}
if (beanFactory instanceofBeanDefinitionRegistry) {
try {
// init scanner
Class<?> scannerClass =ReflectUtils.forName("org.springframework.context.annotation.ClassPathBeanDefinitionScanner");
Object scanner =scannerClass.getConstructor(new Class<?>[] {BeanDefinitionRegistry.class,boolean.class}).newInstance(new Object[] {(BeanDefinitionRegistry) beanFactory,true});
// add filter
Class<?> filterClass =ReflectUtils.forName("org.springframework.core.type.filter.AnnotationTypeFilter");
Object filter =filterClass.getConstructor(Class.class).newInstance(Service.class);
Method addIncludeFilter =scannerClass.getMethod("addIncludeFilter",ReflectUtils.forName("org.springframework.core.type.filter.TypeFilter"));
addIncludeFilter.invoke(scanner, filter);
// scan packages
String[] packages =Constants.COMMA_SPLIT_PATTERN.split(annotationPackage);
Method scan =scannerClass.getMethod("scan", newClass<?>[]{String[].class});
scan.invoke(scanner, newObject[] {packages});
} catch (Throwable e) {
// spring 2.0
}
}
}
AnnotationBean的参数annotationPackage,就是在beandefinition创建时,从xml中读取到spring中。源码通过ClassPathBeanDefinitionScanner.doScan扫描annotationPackage下所有的文件。配置成bean的类会定义成BeanDefinition,注册到spring。
- Dubbo之旅--启动解析
- Dubbo之旅--启动解析
- Dubbo之旅-启动解析-扩展spirng标签-阿里SOA服务化治理方案
- Dubbo之旅-启动解析-扩展spirng标签-阿里SOA服务化治理方案
- dubbo之SPI解析
- dubbo源码解析(二): dubbo服务的启动
- Dubbo之Zookeeper作用解析
- dubbo annocation scan启动过程解析
- dubbo annocation scan启动过程解析
- dubbo annocation scan启动过程解析
- 阿里架构之旅(二)——Dubbo解析
- 阿里架构之旅(二)——Dubbo解析
- 阿里架构之旅(二)——Dubbo解析
- 初识Dubbo 系列之3-Dubbo 快速启动
- 3. Dubbo原理解析-Dubbo内核实现之动态编译
- Dubbo 原理解析-Dubbo 内核实现之 SPI 简单介绍
- 3. Dubbo原理解析-Dubbo内核实现之动态编译
- Dubbo服务之启动时检测
- Core Graphics快速入门
- 编译安装Python
- Maven入门与学习
- js字符串等距替换加密
- 函数式编程
- Dubbo之旅--启动解析
- openstack M版本VPN连接问题总结
- iOS界面规范
- Centos 添加PATH环境变量
- 解决No codesigning identities found:
- 构建财务网报报销模块模型
- 后缀表达式(3)——后缀表达式的计算,递归实现
- Dubbo之旅--扩展协议
- C语言测试题的讲解分析