SPI示例和项目结构记录

下面有一个网上的例子,我只是写一些项目结构的东西,这个在网上没找到。
这里写图片描述

这个是一个SPI服务jar包。只定义了Search接口,具体实现交给其他项目。Console类是含Main的测试类,不用理会。
其中,META-INF/searvices/com.study.Search种的内容为com.study.spi.DatabaseSearch。表明只要在项目中创建com.study.spi.DatabaseSearch类,就能由该类提供给search服务。当然,也可以配置为FileSearch,那么其他项目中就要有FileSearch类。

另外的项目,Search服务的实际提供项目。
这里写图片描述这里写图片描述
虽然有DatabaseSearch和FileSearch,但以为jar中声明的是DatabaseSearch,所以由它提供服务。

网上有人说spi不能再本身项目中测试,是不对的。
这里写图片描述
这样的目录结构就能直接运行Console测试了。修改META-INF/searvices/com.study.Search中的内容就能由不同的类提供search服务。
原因需要查看源代码:
在ServiceLoader.$LazyIterator
这里写图片描述
PREFIX = “META-INF/services/”,
loader调用ServiceLoader.load()的类的Loader。所以了,只要META_INF在classpath下能找到,就能加载。
这里写图片描述
这是具体实例化服务类的操作。

下面是网上的例子:

假设有一个内容搜索系统,分为展示和搜索两个模块。展示和搜索基于接口编程。搜索的实现可能是基于文件系统的搜索,也可能是基于数据库的搜索。实例代码如下
Search.java: 搜索接口
Java代码

1. package search;  
2.   
3. import java.util.List;  
4.   
5. import definition.Doc;  
6.   
7. public interface Search {  
8.     List<Doc> search(String keyword);  
9. }  

FileSearch.java:文件系统的搜索实现
Java代码

1. package search;  
2.   
3. import java.util.List;  
4.   
5. import definition.Doc;  
6.   
7. public class FileSearch implements Search {  
8.   
9.     @Override  
10.     public List<Doc> search(String keyword) {  
11.         System.out.println("now use file system search. keyword:" + keyword);  
12.         return null;  
13.     }  
14.   
15. }  

DatabaseSearch.java
Java代码

1. package search;  
2.   
3. import java.util.List;  
4.   
5. import definition.Doc;  
6.   
7. public class DatabaseSearch implements Search {  
8.   
9.     @Override  
10.     public List<Doc> search(String keyword) {  
11.         System.out.println("now use database search. keyword:" + keyword);  
12.         return null;  
13.     }  
14.   
15. }  

SearchTest.java
Java代码

1. package search;  
2.   
3. import java.util.Iterator;  
4. import java.util.ServiceLoader;  
5.   
6. public class SearchTest {  
7.   
8.     public static void main(String[] args) {  
9.         ServiceLoader<Search> s = ServiceLoader.load(Search.class);  
10.         Iterator<Search> searchs = s.iterator();  
11.         if (searchs.hasNext()) {  
12.             Search curSearch = searchs.next();  
13.             curSearch.search("test");  
14.         }  
15.     }  
16. }  

最后创建在META-INF/searvices/search.Search文件。
当search.Search文件内容是”search.FileSearch”时,程序输出是:
now use file system search. keyword:test
当search.Search文件内容是”search.DatabaseSearch”时,程序输出是:
now use database search. keyword:test
可以看出SearchTest里没有任何和具体实现有关的代码,而是基于spi的机制去查找服务的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值