• Dubbo源码-Provider服务端ServiceBean初始化和属性注入


    上篇我们介绍了Dubbbo的SPI机制,地址如下

    Dubbo源码解读-dubbo的SPI机制-CSDN博客

            本文主要针对@Service解析Bean初始化和属性注入,从dubbo源码角度解析。本篇文章内容相对比较简单,所以读者可以轻松愉快阅读。

            Dubbo SPI机制,是Dubbo中比较重要的技术手段,也是面试过程中比较常问的技术问题,大家可以好好仔细读一下本文。有疑问欢迎留言。

            接着说明,读Dubbo源码最好是先对Spring源码有一定的了解。如果大家需要,我也可以针对Spring框架做一系列源码的解读专栏。

             不过不用担心,如果需要Spring的源码知识,文章中也会进行Spring源码铺垫介绍的。

            如果内容中有没描述清楚的,或者大家在阅读源代码有疑问的,欢迎留言,看到就会及时回复。

            为了更清楚的分析解释源码,源代码中部分不重要的内容可能会删减,保留重要内容方便大家理解。

    主要内容

    • ServiceBean初始化和属性注入

    ServiceBean初始化和属性注入

    Dubbo源码解读-dubbo启动与Spring整合之@ DubboComponentScan-CSDN博客本文中有介绍依赖的Spring基础知识,感兴趣的同学可以看一下。

    具体流程

    1. @Enable->@DubboComponentScan:注册ServiceAnnotationBeanPostProcessor
    2.  ServiceAnnotationBeanPostProcessor:完成Beandefinition注册
      1. 创建DubboClassPathBeanDefinitionScanner继承自ClassPathBeanDefinitionScanner
      2. doScan对包下面的类进行扫描,获取所有包含@service注解的类,并封装成BeanDefinition,注册到Registry中
      3. 创建ServiceBean类的BeanDefinition(每个@service注解的类都对应一个ServiceBean)
      4. 根据@service注解,填充ServiceBean的BeanDefinition的属性。
      5. 注册ServiceBeanDefinition
    3. ServiceBean继承InitializingBean:在afterPropertiesSet对所有的config属性赋值,服务发布时要用。
      1. ProviderConfig
      2. ApplicaitonConfig
      3. moduleConfig
      4. registryConfigs
      5. monitorConfig
      6. protocolConfigs 

    源码解析

    1. public void afterPropertiesSet() throws Exception {
    2. //ProviderConfig配置处理
    3. if (getProvider() == null) {
    4. Map providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);
    5. if (providerConfigMap != null && providerConfigMap.size() > 0) {
    6. Map protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
    7. if ((protocolConfigMap == null || protocolConfigMap.size() == 0)
    8. && providerConfigMap.size() > 1) { // backward compatibility
    9. List providerConfigs = new ArrayList();
    10. for (ProviderConfig config : providerConfigMap.values()) {
    11. if (config.isDefault() != null && config.isDefault().booleanValue()) {
    12. providerConfigs.add(config);
    13. }
    14. }
    15. if (!providerConfigs.isEmpty()) {
    16. setProviders(providerConfigs);
    17. }
    18. } else {
    19. ProviderConfig providerConfig = null;
    20. for (ProviderConfig config : providerConfigMap.values()) {
    21. if (config.isDefault() == null || config.isDefault().booleanValue()) {
    22. if (providerConfig != null) {
    23. throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);
    24. }
    25. providerConfig = config;
    26. }
    27. }
    28. if (providerConfig != null) {
    29. setProvider(providerConfig);
    30. }
    31. }
    32. }
    33. }
    34. //ApplicationConfig配置处理
    35. if (getApplication() == null
    36. && (getProvider() == null || getProvider().getApplication() == null)) {
    37. Map applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
    38. if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
    39. ApplicationConfig applicationConfig = null;
    40. for (ApplicationConfig config : applicationConfigMap.values()) {
    41. if (config.isDefault() == null || config.isDefault().booleanValue()) {
    42. if (applicationConfig != null) {
    43. throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
    44. }
    45. applicationConfig = config;
    46. }
    47. }
    48. if (applicationConfig != null) {
    49. setApplication(applicationConfig);
    50. }
    51. }
    52. }
    53. //ModuleConfig配置处理
    54. if (getModule() == null
    55. && (getProvider() == null || getProvider().getModule() == null)) {
    56. Map moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
    57. if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
    58. ModuleConfig moduleConfig = null;
    59. for (ModuleConfig config : moduleConfigMap.values()) {
    60. if (config.isDefault() == null || config.isDefault().booleanValue()) {
    61. if (moduleConfig != null) {
    62. throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
    63. }
    64. moduleConfig = config;
    65. }
    66. }
    67. if (moduleConfig != null) {
    68. setModule(moduleConfig);
    69. }
    70. }
    71. }
    72. //Registries多注册中心处理
    73. if ((getRegistries() == null || getRegistries().isEmpty())
    74. && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().isEmpty())
    75. && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
    76. Map registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
    77. if (registryConfigMap != null && registryConfigMap.size() > 0) {
    78. List registryConfigs = new ArrayList();
    79. for (RegistryConfig config : registryConfigMap.values()) {
    80. if (config.isDefault() == null || config.isDefault().booleanValue()) {
    81. registryConfigs.add(config);
    82. }
    83. }
    84. if (registryConfigs != null && !registryConfigs.isEmpty()) {
    85. super.setRegistries(registryConfigs);
    86. }
    87. }
    88. }
    89. //Monitor监控配置处理
    90. if (getMonitor() == null
    91. && (getProvider() == null || getProvider().getMonitor() == null)
    92. && (getApplication() == null || getApplication().getMonitor() == null)) {
    93. Map monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
    94. if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
    95. MonitorConfig monitorConfig = null;
    96. for (MonitorConfig config : monitorConfigMap.values()) {
    97. if (config.isDefault() == null || config.isDefault().booleanValue()) {
    98. if (monitorConfig != null) {
    99. throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
    100. }
    101. monitorConfig = config;
    102. }
    103. }
    104. if (monitorConfig != null) {
    105. setMonitor(monitorConfig);
    106. }
    107. }
    108. }
    109. //Protocols 协议配置处理
    110. if ((getProtocols() == null || getProtocols().isEmpty())
    111. && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().isEmpty())) {
    112. Map protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
    113. if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
    114. List protocolConfigs = new ArrayList();
    115. for (ProtocolConfig config : protocolConfigMap.values()) {
    116. if (config.isDefault() == null || config.isDefault().booleanValue()) {
    117. protocolConfigs.add(config);
    118. }
    119. }
    120. if (protocolConfigs != null && !protocolConfigs.isEmpty()) {
    121. super.setProtocols(protocolConfigs);
    122. }
    123. }
    124. }
    125. if (getPath() == null || getPath().length() == 0) {
    126. if (beanName != null && beanName.length() > 0
    127. && getInterface() != null && getInterface().length() > 0
    128. && beanName.startsWith(getInterface())) {
    129. setPath(beanName);
    130. }
    131. }
    132. //是否延迟发布
    133. if (!isDelay()) {
    134. export();
    135. }
    136. }

    总结:上面内容中,源码角度进行了详细分析,依赖的Spring源码知识点也做了说明,如果大家有疑问或者对文章排版任何方面有建议都可以留言评论,看到都会及时回复大家。

    知识总结,分享不易,全文手敲,欢迎大家点赞评论收藏。

  • 相关阅读:
    FFmpeg常用命令行讲解及实战一
    从0搭建新项目平台后台测试环境
    fft理解-cooley turkey
    【Unity实战】从零手戳一个库存背包系统
    2024年申报国自然项目基金撰写及技巧
    性能测试报告模板
    Vue-单文件组件使用说明
    在uniapp微信小程序中保存图片到本地相册
    【LeetCode刷题笔记】滑动窗口
    课题学习(三)----倾角和方位角的动态测量方法(基于陀螺仪的测量系统)
  • 原文地址:https://blog.csdn.net/u014336799/article/details/136873735