首页 > temp > 简明python教程 >
-
轻量级RPC设计与实现第四版
在本版本中引入了SPI机制,关于Java的SPI机制与Dubbo的SPI机制在以前的文章中介绍过。
传送门:Dubbo的SPI机制与JDK机制的不同及原理分析
因为设计的RPC框架是基于Spring的,时常会遇到依赖注入问题。Spring中也有SPI机制,但是它有有个缺点,就是在利用SPI机制实例化具体的服务类时,如果具体的服务类中调用其他的bean,就会实例化失败。主要因为该具体的服务类并没有放入到Spring容器中。本项目将有效解决这个问题。
在设计的RPC框架中加入了该机制,来实现不同序列化方式的切换。
|Spring的SPI机制
我们知道在SprngBoot中好多的配置和实现都有默认的实现,我们只需要修改部分配置,比如数据库配置,我们只要在配置文件中写上对应的url,username,password就可以使用了。其实他这边用的就是SPI的方式实现的。Spring的SPI机制原理与Java的SPI原理是一致的。
SpringBoot会利用SpringFactoriesLoader
加载META-INF/spring.factories文件,从CLASSPATH下的每个Jar包中搜寻所有META-INF/spring.factories配置文件,然后将解析properties文件,找到指定名称的配置后返回。需要注意的是,其实这里不仅仅是会去ClassPath路径下查找,会扫描所有路径下的Jar包,只不过这个文件只会在Classpath下的jar包中。
调用方式:
相关源码:
|改进的SPI机制
该机制有两个缓存变量:
两个Map的key都是扩展服务的接口类的Class对象 cacheClasses
的value也是一个Map,这个map的key是定义的扩展名,即META-INF/roadspi/
目录下文件中的key,value是具体的扩展类的Class对象。 cacheIntances
变量的value也是一个Map,该map的key是定义的扩展名,value是扩展类的具体实例化对象。 该机制的主要逻辑是先获取要实现扩展的接口类Class对象,然后从cacheIntances
变量中根据key查找是否有缓存的实例,如果有直接返回。如果没有,然后根据接口类Class对象和key在cacheClasses
变量中进行查找具体扩展类的Class对象,如果存在,就直接获取对用的Class对象,然后利用BeanDefinitionBuilder
生成bean,并注册到Spring容器中;如果找不到对应的Class对象,则到META-INF/roadspi/扩展接口类全称
文件下进行资源加载。 支持自定义的RoadSpi
注解,来定义默认的具体服务类实现。
最主要部分实现
具体详细代码地址:RoadSPI
__EOF__