小更新,可忽略

This commit is contained in:
youthlql
2023-01-06 00:10:22 +08:00
parent b966a7719a
commit 9940569171
6 changed files with 188 additions and 95 deletions

View File

@@ -13,16 +13,18 @@ abbrlink: dbcfef47
date: 2021-09-12 15:21:58
---
## 第三节: Dubbo的可扩展机制SPI源码解析
dubbo源码项目地址[https://gitee.com/archguide/dubbovip](https://gitee.com/archguide/dubbovip)
### 笔记更新地址:
[https://www.yuque.com/books/share/f2394ae6-381b-4f44-819e-c231b39c1497](https://www.yuque.com/books/share/f2394ae6-381b-4f44-819e-c231b39c1497?#)密码kyys 《Dubbo笔记》
### SPI的概念
https://www.cnblogs.com/happyframework/archive/2013/09/17/3325560.html
@@ -44,24 +46,24 @@ spi-demo
| | main/
| | | java/
| | | | com/
| | | | youthlql/
| | | | atguigu/
| | | | mysql/
| | | | MySQLSaveService.java
| | | resources/
| | | META-INF/
| | | services/
| | | com.youthlql.data.DataSaveService
| | | com.atguigu.data.DataSaveService
| | test/
| | java/
| target/
| classes/
| | com/
| | | youthlql/
| | | atguigu/
| | | mysql/
| | | MySQLSaveService.class
| | META-INF/
| | services/
| | com.youthlql.data.DataSaveService
| | com.atguigu.data.DataSaveService
| generated-sources/
| annotations/
api-db-impl-redis/
@@ -71,24 +73,24 @@ spi-demo
| | main/
| | | java/
| | | | com/
| | | | youthlql/
| | | | atguigu/
| | | | redis/
| | | | RedisSaveService.java
| | | resources/
| | | META-INF/
| | | services/
| | | com.youthlql.data.DataSaveService
| | | com.atguigu.data.DataSaveService
| | test/
| | java/
| target/
| classes/
| | com/
| | | youthlql/
| | | atguigu/
| | | redis/
| | | RedisSaveService.class
| | META-INF/
| | services/
| | com.youthlql.data.DataSaveService
| | com.atguigu.data.DataSaveService
| generated-sources/
| annotations/
api-db-interface/
@@ -98,7 +100,7 @@ spi-demo
| | main/
| | | java/
| | | | com/
| | | | youthlql/
| | | | atguigu/
| | | | data/
| | | | DataSaveService.java
| | | resources/
@@ -107,7 +109,7 @@ spi-demo
| target/
| classes/
| | com/
| | youthlql/
| | atguigu/
| | data/
| | DataSaveService.class
| generated-sources/
@@ -119,7 +121,7 @@ spi-demo
| | main/
| | | java/
| | | | com/
| | | | youthlql/
| | | | atguigu/
| | | | redis/
| | | | MainTest.java
| | | resources/
@@ -128,7 +130,7 @@ spi-demo
| target/
| classes/
| | com/
| | youthlql/
| | atguigu/
| | redis/
| | MainTest.class
| generated-sources/
@@ -143,7 +145,7 @@ spi-demo
#### MainTest
```java
import com.youthlql.data.DataSaveService;
import com.atguigu.data.DataSaveService;
import java.util.ServiceLoader;
@@ -222,18 +224,18 @@ public class RedisSaveService implements DataSaveService {
#### SPI文件示例
api-db-impl-redis\src\main\resources\META-INF\services\com.youthlql.data.DataSaveService
api-db-impl-redis\src\main\resources\META-INF\services\com.atguigu.data.DataSaveService
```txt
com.youthlql.redis.RedisSaveService
com.atguigu.redis.RedisSaveService
```
api-db-impl-mysql\src\main\resources\META-INF\services\com.youthlql.data.DataSaveService
api-db-impl-mysql\src\main\resources\META-INF\services\com.atguigu.data.DataSaveService
```txt
com.youthlql.mysql.MySQLSaveService
com.atguigu.mysql.MySQLSaveService
```
你没看错就是这么简单
@@ -253,9 +255,9 @@ com.youthlql.mysql.MySQLSaveService
SPI文件里写了什么,java的`ServiceLoader`都会给你一次性加载完
```java
com.youthlql.RedCar
com.youthlql.BlackCar
com.youthlql,WhiteCar
com.tuling.RedCar
com.tuling.BlackCar
com.tuling,WhiteCar
....
```
@@ -275,8 +277,8 @@ com.youthlql,WhiteCar
spi文件我们可以这样写
```java
red=com.youthlql.RedCar
black=com.youthlql.BlackCar
red=com.tuling.RedCar
black=com.tuling.BlackCar
```
`SpiTest.java`
@@ -354,6 +356,10 @@ System.out.println(http);
### Dubbo SPI 架构图
<img src="https://npm.elemecdn.com/youthlql@1.0.3/rpc/dubbo/v1/03_di_san_jie/Dubbo-SPI架构图.png"/>
### ExtensionLoader源码
@@ -400,6 +406,8 @@ System.out.println(http);
后续在A接口的代理对象被真正用到时才会结合URL信息找到真正的A接口对应的扩展点实例进行调用。
<img src="https://npm.elemecdn.com/youthlql@1.0.3/rpc/dubbo/v1/03_di_san_jie/ExtensionLoader.png"/>
#### getExtension()
@@ -659,9 +667,9 @@ loadResource方法就是完成对文件内容的解析按行进行解析
clazz.getConstructor();
/*
1. 本来应该这样写的 red=com.youthlql.RedCar
2.如果你前面的red这个name没写像这样只写了个全类名com.youthlql.RedCar
3.默认会去com.youthlql.RedCar这个类上找有没有@Extension注解起名了【官方已经标记成废弃了】
1. 本来应该这样写的 red=com.tuling.RedCar
2.如果你前面的red这个name没写像这样只写了个全类名com.tuling.RedCar
3.默认会去com.tuling.RedCar这个类上找有没有@Extension注解起名了【官方已经标记成废弃了】
*/
if (StringUtils.isEmpty(name)) {
name = findAnnotationName(clazz);
@@ -966,9 +974,9 @@ public class SpiExtensionFactory implements ExtensionFactory {
dubbo生成的代理对象代码可以看下面的`自适应扩展点补充`这里应该就知道为什么要用URL了
dubbo生成的代理对象截图这里应该就知道为什么要用URL了
<img src="https://npm.elemecdn.com/youthlql@1.0.3/rpc/dubbo/v1/03_di_san_jie/image-20210904210634167.png"/>
```java
public class DubboIOCTest {
@@ -1044,7 +1052,7 @@ dubbo中也实现了一套非常简单的AOP就是利用Wrapper如果一
```
<img src="https://npm.elemecdn.com/youthlql@1.0.3/rpc/dubbo/v1/03_di_san_jie/createExtension.png"/>
### 自适应扩展点补充
@@ -1067,7 +1075,7 @@ Protocol protocol = extensionLoader.getAdaptiveExtension();
再看个例子Protocol接口的Adaptive类代理:
再看个例子Protocol接口的Adaptive类代理
```java
package org.apache.dubbo.rpc;
@@ -1130,9 +1138,9 @@ public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol {
所以可以发现某个接口的Adaptive对象在调用某个方法时是通过该方法中的URL参数或者getURL方法通过调用ExtensionLoader.getExtensionLoader(com.luban.Car.class).getExtension(extName);得到一个扩展点实例,然后调用该实例对应的方法。
所以可以发现某个接口的Adaptive对象在调用某个方法时是通过该方法中的URL参数或者getUrl方法通过调用ExtensionLoader.getExtensionLoader(com.luban.Car.class).getExtension(extName);得到一个扩展点实例,然后调用该实例对应的方法。
### Activate扩展点