Dubbo之旅--启动解析

通过之前系列文章我们已经对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。

时间: 2024-10-12 08:31:28

Dubbo之旅--启动解析的相关文章

Dubbo之旅--管理控制台

到现在为止我们的Dubbo之旅让我们对Dubbo跟注册中心有了初步的认识,接下来要分享的是Dubbo的管理控制台,在实际的项目中非常的有用,尤其是在dubbo服务提供数量逐渐加大的情况下,通过Dubbo管理控制台能够很好的被我们所用,从而让我们更好的使用Dubbo提供的服务. 首先需要准备Dubbo-Admin管理控制台程序,本人是通过项目的形式将控制台导入Eclipse中,通过Eclipse的方式来启动tomcat服务.当然也可以直接将程序的war包放入Tomcat的webapps中,直接启动

Dubbo原理和源码解析之服务暴露

一.框架设计 在官方<Dubbo 用户指南>架构部分,给出了服务调用的整体架构和流程: 另外,在官方<Dubbo 开发指南>框架设计部分,给出了整体设计: 以及暴露服务时序图: 本文将根据以上几张图,分析服务暴露的实现原理,并进行详细的代码跟踪与解析. 二.原理和源码解析 2.1 标签解析 从文章<Dubbo原理和源码解析之标签解析>中我们知道,<dubbo:service> 标签会被解析成 ServiceBean. ServiceBean 实现了 Init

dubbo总结(三):dubbo部署和启动

Dubbo管控台可以对注册到zookeeper注册中心的服务或服务消费者进行管理,但管控台是否正常对Dubbo服务没有影响,管控台也不需要高可用,因此可以单节点部署. IP: 192.168.10.101 部署容器:apache-tomcat-7.0.57 端口:8080 1. 下载最新版的Tomcat7: $wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-7/v7.0.57/bin/apache-tomcat-7.0.57.tar.gz

一个面试题引起的SpringBoot启动解析

SpringBoot的故事从一个面试题开始 Spring Boot.Spring MVC 和 Spring 有什么区别? 分开描述各自的特征:Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的ioc和 aop,ioc 提供了依赖注入的容器, aop解决了面向横切面的编程,然后在此两者的基础上实现了其他延伸产品的高级功能. Spring MVC提供了一种轻度耦合的方式来开发web应用.它是Spring的一个模块,是一个web

Dubbo之旅--注册中心

在介绍Dubbo的内部逻辑的时候提到很多次注册中心的概念.实现注册中心的有很多,主要是以下四个注册中心分别是: Multicast注册中心 Zookeeper注册中心 Redis注册中心 Simple注册中心 这里将对注册中心的一个实现Zookeeper跟大家分享,因为Zookeeper是应用比较多,也是我们项目中实际用到的注册中心. ZooKeeper 是一个为分布式应用所设计的分布的.开源的协调服务.分布式的应用可以建立在同步.配置管理.分组和命名等服务的更高级别的实现的基础之上. ZooK

Dubbo之旅--内部逻辑

在没有开始用代码来解释之前,用图最能够表达一些关系,关于Dubbo的内部逻辑调用关系,借用官方的图示来说明一下,如下图 通过上图中的一个个方框我们称之为节点,总共有5个节点,这五个节点可以看成五个角色,每个角色都有一定的功能.每个角色的意思如下: Provider: 暴露服务的服务提供方. 在实际项目中一般称这个角色为提供者.它主要是向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销. Consumer: 调用远程服务的服务消费方. 既然有提供者,对应的这就是消费者.服务

Dubbo之旅--需求

在上篇文章中,我们主要了解了Dubbo的架构路线,并对它有了一个比较简单点的印象和了解,而关于Dubbo基本需求是接下来要介绍的内容. 在大规模服务化之前,应用可能只是通过RMI或Hessian等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过F5等硬件进行负载均衡. 关于F5硬件可以参考 F5 Networks (1)当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大.此时需要一个服务注册中心,动态的注册和发现服务,使服务的位置透明.

Dubbo之旅--Provider示例

在本篇文章中我们将通过集体的示例来对Dubbo的提供和消费进行代码层面的认识.这里所介绍的是基本的提供者和消费者通过Spring容器来进行相关的提供和消费的服务.首先看整个示例的项目结构如下: 我们通过Maven的方式来进行示例,其中dubbo-demo-api为提供者所定义的接口,项目结构如下: 此项目里的内容很简单,为服务的一个接口DemoService: /dubbo-demo/dubbo-demo-api/src/main/java/org/pactera/dubbo/DemoServi

Dubbo之旅--Consumer示例

我们已经对提供者示例进行了详细的阐述,接下来的消费者相对而言比较简单. 1 配置相关pom.xml信息,跟提供者类似,需要相关环境的java包应用. <projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4