當服務的提供者,提供了服務接口的一種實現之后,在jar包的META-INF/services/目錄里同時創(chuàng)建一個以服務接口命名的文件。
例如:

該文件里就是實現該服務接口的具體實現類。而當外部程序裝配這個模塊的時候,就能通過該jar包META-INF/services/里的配置文件找到具體的實現類名,并裝載實例化,完成模塊的注入。
基于這樣一個約定就能很好的找到服務接口的實現類,而不需要再代碼里制定。
jdk提供服務實現查找的一個工具類:java.util.ServiceLoader
假設有一個內容搜索系統(tǒng),分為展示和搜索兩個模塊。展示和搜索基于接口編程。搜索的實現可能是基于文件系統(tǒng)的搜索,也可能是基于數據庫的搜索。
1.你可能會定義一個搜索接口

2。具體搜索實現,可以是去文件中,也可能是去數據庫搜索


3。一般的調用方法是Class.forName("xxx") 反射加載,那么這里呢,不是通過那種方式加載你想要的實現的,而是通過ServiceLoader.load方法,最后創(chuàng)建在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的機制去查找服務的實現

這樣基本上就理解了spi機制