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的機制去查找服務的實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章