如何利用spi机制去指定接口具体实现? #java底层
如何利用 spi 机制去指定接口具体实现?
兄弟们,今天来聊一下如何利用 spi 机制去指定接口的具体实现。
1. 为什么要聊这个问题呢?因为在平时的开发过程中可能会经常遇到这样一种场景,比如在程序里面指定了一个接口就是 myService,同时它有两个实现类就是 myService1 和 myService2。
2. 此时有一个需求,想要获取 myService 接口下面的 myService1 实现类,而不想要获取 myService2 的实现类。这时如果写代码,肯定是获取接口下面所有的实现类,并且把 myService2 排除,myService1 暴露出来。
3. 此时过了几天又有了一个新的需求,想要获取 myService2 实现类,同时不想要获取 myService1。此时又要去改代码,去获取接口下面所有的实现类,把 myService1 暴露出来,myService1 屏蔽掉。
4. 有没有想过一个问题,就是在修改的时候可能会引入一个新的异常,所以今天要聊的 spi 机制正好就是通过一个配置文件去指定接口到底使用哪个实现类。同时在单目里面可以看到这个方法就可以从配置文件去获取这里面指定的具体的实现类就是 myService1。
5. 再看一下 myService1 的实现方法,就是这个,获取就是 myService.execute,可以先去执行一下,执行完之后会发现正好获取的就是 myService1 实现类。此时改成 myService2 实现类,再去运行一下代码。
6. 其实这块的使用场景还是很多的,比如 jdbc 既可以整合 oracle 也可以整合 mysql,如何去整合?就是通过 spi 机制,比如去接入了一个 oracle 的包,它的 driver 默认就是 oracle 的 driver,具体的实现也是 oracle 的那一套。如果引用了 mysql 的包,它引用的是买 mysql 那一套具体的实现,所以 SPI 机制用的还是很广的。
7. 问题来了,它有几个重要的点一定要注意一下。首先需要在 resources 文件里面去写一个 META-INF/services 文件夹的名字,一定要注意,一定是这个名字不能写错。同时这里面的文件的名字一定是接口的全类名,它里面写的值一定是接口里面实现的全类名。所以就可以通过这个方法从配置里面去找到接口的具体实现类。