当前位置: 代码迷 >> 综合 >> dubbo:学习整理1——简单流程
  详细解决方案

dubbo:学习整理1——简单流程

热度:54   发布时间:2024-02-09 17:51:43.0

一,自动配置-注册相关后置处理器

1,第一种自动配置方式:

dubbo-spring-boot-autocofigure包的Spring.factories中设置了自动配置类和应用监听器的类。

在springboot启动时会自动扫描,然后进行加载对应的类并注入到容器中,需要在配置文件中配置"dubbo.scan.basePackages",

在自动配置类中com.alibaba.boot.dubbo.autoconfigure.DubboAutoConfiguration

直接生成ServiceAnnotationBeanPostProcessor和ReferenceAnnotationBeanPostProcessor两个bean并注册到容器中

2,第二中自动配置方式

@DubboComponentScan(basePackages="com.**.provider.service") 主类中加入这个注解

@DubboComponentScan注解会引入@Import({DubboComponentScanRegistrar.class})注册器

DubboComponentScanRegistrar什么时候会被引入?引入的作用?

1),引入时机,在ioc容器refresh()方法中,容器准备好之后调用invokeBeanFactoryPostProcessors(BeanFactory)方法,调用工厂后置处理器,其中有一个ConfigurationClassPostProcessor(很重要,ioc中被bean就是由此类加载的),就会扫描到@Import的注解,并执行registerBeanDefinitions()方法

2),registerBeanDefinitions()方法中,先找到注解的需要扫描的包packagesToScan="com.*.provider.service"

3),根据扫描包packagesToScan作为参数注入ServiceAnnotationBeanPostProcessor工厂后置处理器,服务暴露后置处理器。

4),注入ReferenceAnnotationBeanPostProcessor后置处理器,服务引用后置处理器

说明:

ServiceAnnotationBeanPostProcessor后置处理器,

是一个BeanFactoryPostProcessor在容器invokeBeanFactoryPostProcessors()过程中,会被执行。

作用:以@Service作为过滤条件,扫描指定scanBasePackages,向容器注册ServiceBean。容器在refresh()完成的时候,会向容器中发送ContextRefershEvent,ServiceBean实例会监听此事件,然后执行服务export过程,暴露服务。

 

ReferenceAnnotationBeanPostProcessor后置处理器

在容器初始化完成后,会实例化容器中的单例非懒初始化Bean。

在实例化Bean以后,初始化Bean属性前会调用populateBean()方法,执行AnnotationInjectedBeanPostProcessor为注入依赖的属性。而ReferenceAnnotationBeanPostProcessor就是继承自AnnotationInjectedBeanPostProcessor,此时它会随着一起执行。

作用:找到@Reference所注解的字段,为其注入值。

注入的值为业务接口的动态代理类,动态代理(InvocationHandler)的逻辑是调用ReferenceBean.get()方法,创建真正的Invoker。

所以最终注入了封装了远程调用逻辑的Invoker。

二,服务暴露过程

AbstractApplicationContext容器refresh之后执行finishRefresh()方法中,发布事件

》》this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));

》》  SimpleApplicationEventMulticaster类中 multicastEvent()处理事情

》》this.invokeListener(listener, event)

》》 this.doInvokeListener(listener, event)

》》使用 listener.onApplicationEvent(event);

而dubbo提供者注册到容器中的bean为ServiceBean 同时是一个监听器,监听ContextRefreshedEvent事件,

public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, BeanNameAware {

在ServiceBean 的onApplicationEvent(ContextRefreshedEvent event)中

》》 调用this.export();

》》转到ServiceConfig的同步方法export(),进行暴露服务

》》如果有延迟则延迟暴露,如果没有延迟则直接暴露服务

》》serviceConfig中doExport()检查各类参数

》》this.doExportUrls() 按照不同的Protocol,比如(dubbo,injvm)暴露服务,在不同的zookeeper集群节点上注册自己的服务

》》this.doExportUrlsFor1Protocol(protocolConfig, registryURLs);会用一个变量map保存URL的所有变量和value值,然后调用代理工程proxyFactory,获取代理类,然后将invoker转换成exporter,暴露服务,

》》DubboProtocol的 protocol.export(wrapperInvoker)

》》this.openServer(URL url)打开服务,如果服务不存在则创建服务

》》this.createServer(URL url)

》》Exchangers.bind(url, this.requestHandler)而在headerExchanger的bind中,调用了Transporters.bind(),一直调用到NettyServer,绑定了端口和链接。

小结:每个服务绑定一个socket端口,等待调用者来调用。一个接口文件对应一个服务,如ITestService对应一个服务

ServiceBean的名称为ServiceBean:testimpl:com.**.serviceinterface.service.ITestService

拼接后的url

provider://192.168.56.1:20882/com.**.serviceinterface.service.ITestService?anyhost=true&application=providerboot_v2&category=configurators&check=false&default.timeout=60000&dubbo=2.6.2&generic=false&interface=com.**.serviceinterface.service.ITestService&methods=getTest&organization=example&owner=admin&pid=15120&side=provider×tamp=1595302400861,

三,服务注册过程