SPI的全名為Service Provider Interface.普通開(kāi)發(fā)人員可能不熟悉,因?yàn)檫@個(gè)是針對(duì)廠商或者插件的伟端。在java.util.ServiceLoader的文檔里有比較詳細(xì)的介紹。
簡(jiǎn)單來(lái)說(shuō)就是通過(guò)配置文件指定接口的實(shí)現(xiàn)類(lèi)壮不。
當(dāng)我們開(kāi)發(fā)一套框架泰讽、一套機(jī)制、一個(gè)插件或一套API時(shí)候降宅,如果需要第三方的服務(wù)支持,可以直接寫(xiě)死到代碼里面囚霸,但這種方式耦合太強(qiáng)腰根,不利于切換到其它服務(wù),好的方法是寫(xiě)一個(gè)配置文件指定服務(wù)的實(shí)現(xiàn)方拓型,幸運(yùn)的是java的spi機(jī)制已經(jīng)幫我們做好了额嘿,示例用法如下:
一個(gè)接口:
1. package testws;
2
3. public interface TestEJB {
4. void test(String data) throws Exception;
5. void test0(String data) throws Exception;
6. }
第一個(gè)實(shí)現(xiàn)類(lèi):
1. package testws;
3. public class MyTest implements TestEJB {
4. public void test(String data) throws Exception {
5. System.out.println("my test:" + data);
6. }
8. public void test0(String data) throws Exception {
9. System.out.println("test0:" + data);
10. }
11. }
第二個(gè)實(shí)現(xiàn)類(lèi):
1. package testws;
3. public class MyTest2 implements TestEJB {
4. public void test(String data) throws Exception {
5. System.out.println("my test2222:" + data);
6. }
8. public void test0(String data) throws Exception {
9. System.out.println("test02222222:" + data);
10. }
11. }
建立 META-INF 文件夾,在其里面建立 services 文件夾劣挫,在services文件夾下建立一個(gè)文件册养,名稱為我們需要實(shí)現(xiàn)的服務(wù)的全類(lèi)名,即:testws.TestEJB
文件testws.TestEJB的內(nèi)容如下:(PS:如果我們只需要一個(gè)實(shí)現(xiàn)類(lèi)压固,下面可以只寫(xiě)一個(gè)球拦,每一個(gè)實(shí)現(xiàn)類(lèi)占一行)
testws.MyTest
testws.MyTest2
最后一個(gè)步驟:將三個(gè)java類(lèi)和META-INF 文件夾打包到一個(gè)jar中,就可以使用了,使用方式:
public class TestSPI {
public static void main(String[] args) {
ServiceLoader<TestEJB> loadedImpl = ServiceLoader.load(TestEJB.class);
for (TestEJB testEJB : loadedImpl) {
System.out.println(testEJB.getClass());
try {
testEJB.test("a");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
打印如下:
1. class testws.MyTest
2. my test:a
3. class testws.MyTest2
4. my test2222:a
轉(zhuǎn):https://blog.csdn.net/conquer0715/article/details/50728458