一些優(yōu)秀的開源框架表窘,總會給開發(fā)者留一個后門,方便實現(xiàn)對其中某一塊功能甜滨,根據(jù)公司自身生態(tài)進(jìn)行有效的擴展乐严,比如Neflix開源的Hystrix,其實Hystrix的代碼寫的真的很好衣摩,除了RxJava那部分晦澀的實現(xiàn)昂验。
在Hystrix中的插件實現(xiàn)中,提供了5個擴展點,通過實現(xiàn)這些插件接口既琴,可以很好的結(jié)合公司內(nèi)部框架進(jìn)行使用占婉,比如數(shù)據(jù)埋點、動態(tài)配置等等甫恩,下面以事件通知接口為例子逆济,看看Hystrix是如何實現(xiàn)的。
public HystrixEventNotifier getEventNotifier() {
if (notifier.get() == null) {
// check for an implementation from Archaius first
Object impl = getPluginImplementation(HystrixEventNotifier.class);
if (impl == null) {
// nothing set via Archaius so initialize with default
notifier.compareAndSet(null, HystrixEventNotifierDefault.getInstance());
// we don't return from here but call get() again in case of thread-race so the winner will always get returned
} else {
// we received an implementation from Archaius so use it
notifier.compareAndSet(null, (HystrixEventNotifier) impl);
}
}
return notifier.get();
}
通過getEventNotifier
方法獲取事件通知器磺箕,當(dāng)然了奖慌,一開始是沒有初始化的,先嘗試使用getPluginImplementation
方法松靡,看看能不能拿到简僧,拿不到就使用本地默認(rèn)的實現(xiàn)。
private <T> T getPluginImplementation(Class<T> pluginClass) {
T p = getPluginImplementationViaProperties(pluginClass, dynamicProperties);
if (p != null) return p;
return findService(pluginClass, classLoader);
}
這里击困,Hystrix還提供了另外一種實現(xiàn)涎劈,很簡單,就不解釋了阅茶,這里的重點是findService
實現(xiàn)。
private static <T> T findService(Class<T> spi, ClassLoader classLoader) throws ServiceConfigurationError {
ServiceLoader<T> sl = ServiceLoader.load(spi, classLoader);
for (T s : sl) {
if (s != null)
return s;
}
return null;
}
其實谅海,這里的實現(xiàn)是使用Java內(nèi)置的SPI機制脸哀,SPI是什么?
SPI 全稱為 Service Provider Interface)扭吁,是一種服務(wù)提供發(fā)現(xiàn)機制撞蜂,通過ServiceLoader
類的load方法,可以自動找到實現(xiàn)對應(yīng)接口的實現(xiàn)類侥袜,為了更清晰的了解其中原理蝌诡,可以去看看load方法的源碼實現(xiàn)。
一個大概的過程是:load方法會嘗試在classpath下META-INF/services/文件夾下查找一個文件枫吧,其中文件名是接口的全限定名浦旱。
如上圖所述,CacheKeyFilter
是一個接口九杂,在這個文件中颁湖,需要指定接口實現(xiàn)類的全限定名。
當(dāng)然了例隆,你也可以換行指定多個甥捺,找到這些實現(xiàn)類之后,會通過反射機制镀层,即class.newInstance()
進(jìn)行實例化镰禾,這就要求實現(xiàn)類需要有無參構(gòu)造函數(shù),
通過這種方式,我們就可以愉快的對開源框架所提供的接口進(jìn)行擴展吴侦,加入各種騷操作屋休,還不動手試試?