当前位置:数据分析 > 【第301期】面试官:为什么dubbo不使用jdk的spi机制?

【第301期】面试官:为什么dubbo不使用jdk的spi机制?

  • 发布:2023-10-05 03:01

2022年5月17日下午4:11 • 面试问题 • 阅读 6 1.jdk中的spi机制 1.1 spi的设计目标 在面向对象设计中,模块是基于接口进行编程的,模块之间不硬编码实现类。 一旦代码中涉及到具体的实现类,就违反了可插拔性原则。如果需要替换实现,则需要修改代码。为了达到组装模块时不硬编码模块内代码的目的,需要有服务发现机制。 Java SPI 提供了这样一种机制:一种查找某个接口的服务实现的机制。有点类似于IOC的思想,就是把汇编的控制权移到代码之外。即SPI机制有一个接口和几个实现类。代码运行时,需要确定运行哪个实现类,而这些实现类也是可插拔的。 1.2 spi具体协议 当服务提供者提供某个接口的多个实现时,一般会在jar包的META-INF/services/目录下创建一个与该接口同名的文件。该文件中的内容是服务接口的具体实现类的名称。 外部加载该模块时,可以通过jar包META-INF/services/中的配置文件获取具体的实现类名,并实例化加载,完成模块的组装。 下面是两个例子: 1、例如加载MySQL等特定sql驱动包:mysql-connector-java-5.1.35.jarMETA-INFservicesjava.sql.Driver为spi扩展点oracle:ojdbc6-11.2.0.1.0.jarMETA-INFservicesjava .sql.驱动程序 2、例如加载spring-web的ServletContainerInitializer:spring-web-4.2.0.RELEASE.jar!META-INFservicesjavax.servlet.ServletContainerInitializer 1.3 jdk实际例子 1. 编写接口命令 公共接口命令{公共无效执行(); } 2、分别编写两个接口的实现类:TurnOnCommand和TurnOffCommand公共类 TurnOnCommand 实现 Command { public voidexecute() { System.out.println("Trun on...."); } } public class TurnOffCommand 实现 Command { public voidexecute() { System.out.println("Trun off...."); } } 3、在项目的resources\META-ING\services目录下新建com.abc.spi.Command的spi配置文件。内容是接口的两个实现类。 内容是: com.abc.spi.TurnOnCommandcom.abc.spi.TurnOffCommand 4.编写测试类Test 公开课测试{ public static void main(String[] args) { // 加载jdk的spi接口Command.class ){ command.execute(); } } } 下图为测试结果: 1.4、JDK的SPI机制的缺点 1. JDK标准SPI将立即实例化所有扩展点实现。如果有扩展实现,初始化是非常耗时的,但如果不使用而加载的话,又会造成资源的浪费。 2、JDK的SPI机制没有对Ioc和AOP的支持,所以dubbo使用了自己的spi机制:增加了对扩展点IoC和AOP的支持,一个扩展点可以直接向其他扩展点注入setter。 2.Dubbo的spi约定 2.1 dubbo的spi文件存放在哪里?生成的dubbo jar包下的dubbo-2.5.3.jarMETA-INFdubbointernal目录下的文件都是spi扩展机制。 2.2 dubbo的SPI约定有哪些? 1、spi文件的存放路径在META-INFdubbointernal目录下,文件名是接口的全路径名,即=接口的包名+接口名,例如:dubbo-2.5 .3.jarMETA-INFdubbointernalcom.alibaba.dubbo.rpc.协议 2、每个spi文件中的格式定义为:扩展名=具体类名,例如registries=com.alibaba.dubbo.registry.RegistriesPageHandlerpages。推荐:250 个面试问题 3、如何扩展dubbo的spi 例如,如果要扩展dubbo的Protocol,需要经过以下步骤: 1、新建一个工程,在src/main/resources/META-INF/dubbo目录下新建文件,如org.apache.dubbo.rpc.Protocol,写入以下内容:xxProtocal=www.sychzs.cn。 Xxx协议 项目目录如下: 2、然后在本项目中新建XxxProtocol类,实现Protocol接口,并实现相关方法 www.sychzs.cn: 包www.sychzs.cn; 导入 org.apache.dubbo.rpc.Protocol; public class Invokerrefer(Class type, URL url) throws RpcException { return new XxxInvoker(type, url); } }} www.sychzs.cn:包www.sychzs.cn;导入 org.apache.dubbo.rpc.support.AbstractExporter;公共类 XxxExporter 扩展 AbstractExporter { 公共调用者); // . .. } 公共无效 unexport() { super.unexport(); // ... }} www.sychzs.cn: 包www.sychzs.cn;导入 org.apache.dubbo.rpc.support.AbstractInvoker; public class XxxInvoker extends AbstractInvoker { public super(type, url ); } protected abstract Object doInvoke(Invocal invoice) throws Throwable { } // ... }} 3、你可以把这个项目打包成jar包,然后在你的dubboprovider项目中依赖刚才的spijar包,并在spring配置文件中配置如下: 感谢您的阅读,希望对您有所帮助:) 来源:www.sychzs.cn/post/6844904045803470855 结尾 题外话推荐 推荐一个“钓鱼程序员”的聚集地 推荐十期【第281期】滴滴2:try-catch-finally和return是按照什么顺序执行的? 【第282期】面试官:能谈谈Nacos的实现原理吗? 【第283期】熊达先生访谈回忆录(2.5年开发经验)【第284期】共享锁、排它锁、互斥锁、悲观锁、乐观锁、行锁、表锁、页锁、不可重复读、loss 修改和读取脏数据【第285期】如何实现Spring的@Transactional(必考)【第286期】面试时被问到,Flutter/Dart的HashMap该怎么办? 【问题287】使用forEach遍历删除ArrayList中的元素会报错吗? 【第288期】面试官:什么是CAP定理?为什么CAP不能同时得到满足? 【第289期】面试官:谈谈常用的JVM垃圾收集器的特点、优缺点、使用场景和参数设置【第290期】为什么不建议使用Java序列化? 而不是在网上搜索问题?还不赶快关注我们吧~ 版权声明:本文内容由网友自愿贡献,本文所表达的观点仅代表作者自己的观点。本网站仅提供信息存储空间服务,不拥有任何所有权,也不承担相关法律责任。如果您发现本站有任何涉嫌侵权/非法内容,请发送邮件举报。一经核实,该网站将立即删除。 本文由斑马博客整理。本文链接为:https://www.sychzs.cn/index.php/post/8380.html

相关文章