Java的SPI機(jī)制介紹
SPI的全名為Service Provider Interface.普通開(kāi)發(fā)人員可能不熟悉,因?yàn)檫@個(gè)是針對(duì)廠商或者插件的。在java.util.ServiceLoader的文檔里有比較詳細(xì)的介紹。究其思想,其實(shí)是和"Callback"差不多。“Callback”的思想是在我們調(diào)用API的時(shí)候,我們可以自己寫(xiě)一段邏輯代碼,傳入到API里面,API內(nèi)部在合適的時(shí)候會(huì)調(diào)用它,從而實(shí)現(xiàn)某種程度的“定制”。
典型的是Collections.sort(List<T> list,Comparator<? super T> c)這個(gè)方法,它的第二個(gè)參數(shù)是一個(gè)實(shí)現(xiàn)Comparator接口的實(shí)例。我們可以根據(jù)自己的排序規(guī)則寫(xiě)一個(gè)類(lèi),實(shí)現(xiàn)此接口,傳入此方法,那么這個(gè)方法就會(huì)根據(jù)我們的規(guī)則對(duì)list進(jìn)行排序。
把這個(gè)思想擴(kuò)展開(kāi)來(lái),我們用SPI來(lái)重新實(shí)現(xiàn)上面的例子??蛻舭炎约旱呐判蛞?guī)則寫(xiě)成一個(gè)類(lèi),并且打包成Jar文件,這個(gè)Jar文件里面必須有META-INF目錄,其下又有services目錄,其下有一個(gè)文本文件,文件名即為接口的全名:java.util.Comparator。
--META-INF --services --java.util.Comparator
文件內(nèi)容只有一行:
- com.company1.ComparatorProvider
這一行是你實(shí)現(xiàn)了Comparator接口的類(lèi)的全名,它的代碼如下:
- package com.company1;
- import java.util.Comparator;
- import com.mycompany.myapp.MyItem;
- public class ComparatorProvider implements Comparator<MyItem>{
- @Override
- public int compare(MyItem o1, MyItem o2) {
- //依據(jù)name排序
- return o1.getName().compareTo(o2.getName());
- }
- }
編譯打包后,把它放到你的主程序的class path里。下面是你的主程序:
- //從class path中所有Jar的META-INF目錄中搜索,找到合適的類(lèi)并加載。
- private static ServiceLoader<Comparator> serviceLoader
- = ServiceLoader.load(Comparator.class);
- public static void main(String[] args)
- {
- List<MyItem> myList = new ArrayList<MyItem>();
- myList.add(new MyItem(2,"c","hhh"));
- myList.add(new MyItem(3,"k","ooo"));
- myList.add(new MyItem(4,"d","ppp"));
- myList.add(new MyItem(5,"b","ggg"));
- showList(myList);
- Collections.sort(myList,getCompartor());
- showList(myList);
- }
- @SuppressWarnings("unchecked")
- private static Comparator<MyItem> getCompartor() {
- for(Comparator service : serviceLoader)
- {
- return (Comparator<MyItem>)service;
- }
- return null;
- }
要注意的是serviceLoader開(kāi)始只是加載類(lèi),實(shí)例化要到***次用的時(shí)候。類(lèi)MyItem和方法showList并不重要,所以你不必在意。你可以按照這個(gè)規(guī)則,寫(xiě)另外一個(gè)排序規(guī)則的Jar,隨時(shí)可以更換你的排序規(guī)則。
原文鏈接:http://mars914.iteye.com/blog/1283859
【編輯推薦】