前言

在上一篇的末尾,我们提到了dubbo的spi中增加了IoC和AOP的功能.那么本篇就讲一下这个增加的IoC,spi部分预计会有四篇,因为这东西实在是太重要了.温故而知新,我们先来回顾一下,我们之前都讲了什么.

  • spi(1) 主要讲了spi的基本概念,简单的入门,并以spi为线索讲解了双亲委托模式的弊端以及解决方案
  • spi(2) 主要以dubbo改进了jdk的spi为线索,重点讲分析问题的思路,从实际案例实战从哪里着手分析问题这个大家最喜欢问的问题.

提到IoC,大家第一个想到的就是Spring,所以Spring的IoC也是本篇的一大重点内容.当然毕竟主题是dubbo,所以对于Spring内容,将与dubbo结合,以短小精干,但是又不缺乏深度的介绍.(后期如果大家有需要,也可以开展Spring源码专题)

看到这里可能有同学就会问,肥朝你不是写dubbo源码解析的吗,为什么还要讲Spring呢?dubbo中涉及到很多的边缘知识,其中包括Spring、Netty、Zookeeper等等,我希望的是,大家能通过学习dubbo为主线,全面综合的提高自己,而不是为了看源码而看源码,也不是为了面试而看源码.

插播面试题
你提到了dubbo中spi也增加了IoC,那你先讲讲Spring的IoC,然后再讲讲dubbo里面又是怎么做的
Spring的IoC
容器
Spirng的IoC容器主要有两种,即BeanFactory和ApplicationContext

  • BeanFactory是Spring中最底层的接口,只提供了最简单的IoC功能,负责配置,创建和管理bean.
  • ApplicationContext继承了BeanFactory,拥有了基本的IoC功能外,还支持
  1. 国际化
  2. 消息机制
  3. 统一的资源加载
  4. AOP

另外ApplicationContext在加载的时候就会创建所有的bean(Web应用推荐),BeanFactory需要等到拿bean的时候才会创建bean(桌面应用推荐).所以,我们一般使用ApplicationContext

总体流程
实现IoC的过程,总体可以分为两步,如下图

容器启动阶段

该阶段相当于"根据图纸装配成生产线",也就是对象管理信息的收集.

Bean实例化阶段

拓展

Spring提供了BeanFactoryPostProcessor的容器拓展机制,该机制允许我们在容器实例化相应对象之前,对注册到容器的BeanDefinition所保存的信息做相应的修改.

那我们有哪些实际场景有运用到这个拓展呢?

比如我们配置数据库信息,经常用到占位符

${jdbc.url}

当BeanFactory在第一阶段加载完成所有配置信息时,保存的对象的属性信息还只是以占位符的形式存在.这个解析的工作是在PropertySourcesPlaceholderConfigurer中做的,我们来看看继承体系图就明白了.

PropertySourcesPlaceholderConfigurer实现了该接口,在进入第二阶段时,已经把占位符信息替换完成.

温馨提示:

细心的同学可能发现PropertySourcesPlaceholderConfigurer和PropertyPlaceholderConfigurer名字好像,这两个有什么区别?我们来看源码

敲黑板划重点

为何我反复强调基础、原理,难道是为了骗你关注一下我,多一个粉丝?因为基础扎实,明白原理之后很多东西真的是一通百通的,尤其了Spring Boot简化了配置,很多问题就更考验基础了.我演示一个简单的问题

首先我们发现这个占位符没有被解析,如果不知道原理你可能一脸懵逼,但是看过肥朝博客的你,知道是缺少PropertySourcesPlaceholderConfigurer

于是你高高兴兴补上了PropertySourcesPlaceholderConfigurer,发现有坑,占位符是解析出来了,但是却是null

然后你通过私信联系到了肥朝,肥朝告诉你,加上个static就可以了.于是你一运行,果然是棒棒哒!

但是你却百思不得其解,为啥加上了一个static就可以了呢?

原因很简单,前面都说了,这个拓展机制是在实例化对象之前,你用static修饰方法,是属于类级别的,优先级高,自然在DataSource实例化之前就完成了这个占位符的解析工作.

dubbo spi中的iOC

既然是源码解析类文章,我就尽量避免贴大段代码,否则还不如你直接去看.我用一个图来粗略描述这个大致的过程

除了上一篇中对objectFactory的介绍外,从这里我们知道,objectFactory就是dubbo的IoC提供对象.

public <T> T getExtension(Class<T> type, String name) {
//factories=[SpiExtensionFactory,SpringExtensionFactory]
//遍历获取spi,先从SpiExtensionFactory获取,如果没有,再从SpringExtensionFactory获取
for (ExtensionFactory factory : factories) {
T extension = factory.getExtension(type, name);
if (extension != null) {
return extension;
}
}
return null;
}

SpiExtensionFactory

public <T> T getExtension(Class<T> type, String name) {
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
if (loader.getSupportedExtensions().size() > 0) {
return loader.getAdaptiveExtension();
}
}
return null;
}

SpringExtensionFactory

public <T> T getExtension(Class<T> type, String name) {
for (ApplicationContext context : contexts) {
if (context.containsBean(name)) {
//从容器中获取注入的对象
Object bean = context.getBean(name);
if (type.isInstance(bean)) {
return (T) bean;
}
}
}
return null;
}

dubbo在设计的时候设计了这两种方式,但是截止2.5.4版本,SpringExtensionFactory的方式尚未发现使用,可能像Java的保留字一样,给以后埋下伏笔.据说3.0版本准备出来,到时候可以关注一下SpringExtensionFactory的使用情况.

Ref:

https://www.jianshu.com/p/718acbda838c

dubbo源码解析-spi(3)的更多相关文章

  1. dubbo源码解析-spi(4)

    前言 本篇是spi的第四篇,本篇讲解的是spi中增加的AOP,还是和上一篇一样,我们先从大家熟悉的spring引出AOP. AOP是老生常谈的话题了,思想都不会是一蹴而就的.比如架构设计从All in ...

  2. dubbo源码解析-spi(一)

    前言 虽然标题是dubbo源码解析,但是本篇并不会出现dubbo的源码,本篇和之前的dubbo源码解析-简单原理.与spring融合一样,为dubbo源码解析专题的知识预热篇. 插播面试题 你是否了解 ...

  3. dubbo源码解析-spi(二)

    前言 上一篇简单的介绍了spi的基本一些概念,在末尾也提到了,dubbo对jdk的spi进行了一些改进,具体改进了什么,来看看文档的描述 JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩 ...

  4. Dubbo源码(二) - SPI源码

    前情提要 假设你已经知道Dubbo SPI的使用方式,不知道的请出门左转: Dubbo源码(一) - SPI使用 Dubbo源码地址: apache/dubbo 本文使用版本:2.6.x 测试Demo ...

  5. dubbo源码解析五 --- 集群容错架构设计与原理分析

    欢迎来我的 Star Followers 后期后继续更新Dubbo别的文章 Dubbo 源码分析系列之一环境搭建 博客园 Dubbo 入门之二 --- 项目结构解析 博客园 Dubbo 源码分析系列之 ...

  6. Dubbo 源码解析四 —— 负载均衡LoadBalance

    欢迎来我的 Star Followers 后期后继续更新Dubbo别的文章 Dubbo 源码分析系列之一环境搭建 Dubbo 入门之二 --- 项目结构解析 Dubbo 源码分析系列之三 -- 架构原 ...

  7. dubbo源码解析-zookeeper创建节点

    前言 在之前dubbo源码解析-本地暴露中的前言部分提到了两道高频的面试题,其中一道dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者还能通信吗?在上周的dubbo源码 ...

  8. Dubbo源码解析之SPI(一):扩展类的加载过程

    Dubbo是一款开源的.高性能且轻量级的Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用.智能容错和负载均衡,以及服务自动注册和发现. Dubbo最早是阿里公司内部的RPC框架,于 ...

  9. 【Dubbo 源码解析】02_Dubbo SPI

    Dubbo SPI:(version:2.6.*) Dubbo 微内核 + 插件 模式,得益于 Dubbo SPI .其中 ExtentionLoader是 Dubbo SPI 最核心的类,它负责扩展 ...

随机推荐

  1. P1244 青蛙过河

    P1244 青蛙过河NOI2000主要思想:数学归纳法 递推 压位高精度 化归 理解能力和找规律的能力题意再述:1.青蛙从上到下必须连续递增或者下面是石墩 而不能是1 12 33 4而且每时每刻都要满 ...

  2. 如何利用JMeter模拟超过 5 万的并发用户

    本文将从负载测试的角度,描述了做一次流畅的5万用户并发测试需要做的事情. 你可以在本文的结尾部分看到讨论的记录. 快速的步骤概要 编写你的脚本 使用JMeter进行本地测试 BlazeMeter沙箱测 ...

  3. SpringMVC(八) RequestMapping HiddenHttpMethodFilter

    SpringMVC隐藏方法: 使用PUT和DELETE方法.默认HTML支持GET和POST方法.通过HiddenHttpMethodFilter将POST转成PUT和DELETE方法. 1.将Hid ...

  4. JSP(Servlet)中从连接池获取连接

    1) 建立连接. 2) 执行SQL. 3) 处理结果. 4) 释放资源. Connection pool:连接池 DataSource: LDAP ( Light directory access p ...

  5. IBM MR10i阵列卡配置Raid0/Raid1/Raid5(转)

    RAID5配置: 其实RAID0/RAID1都基本一致,只是选择的类型不同. 1. 开机看到ctrl+h的提示按下相应的键,等ServerRaid 10-i卡初始化完成则进入WebBIOS 配置界面: ...

  6. Redis "MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk"问题的解决(转)

    今天第二次遇到Redis “MISCONF Redis is configured to save RDB snapshots, but is currently not able to persis ...

  7. HDU 4123 Bob’s Race(树形DP,rmq)

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. GO语言基础之method

    方法 method 1. Go 中虽没有 class,但依旧有 method 2. 通过显示说明 receiver 来实现与某个类型的组合 3. 只能为同一个包中的类型定义方法 4. Receiver ...

  9. OpenAI Gym

    https://blog.openai.com/openai-gym-beta/ https://openai.com/

  10. [转]LRU缓存实现(Java)

    LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...