優(yōu)秀開(kāi)源框架的擴(kuò)展機(jī)制實(shí)現(xiàn)

一些優(yōu)秀的開(kāi)源框架,總會(huì)給開(kāi)發(fā)者留一個(gè)后門(mén),方便實(shí)現(xiàn)對(duì)其中某一塊功能,根據(jù)公司自身生態(tài)進(jìn)行有效的擴(kuò)展,比如Neflix開(kāi)源的Hystrix,其實(shí)Hystrix的代碼寫(xiě)的真的很好,除了RxJava那部分晦澀的實(shí)現(xiàn)。

在Hystrix中的插件實(shí)現(xiàn)中,提供了5個(gè)擴(kuò)展點(diǎn),通過(guò)實(shí)現(xiàn)這些插件接口,可以很好的結(jié)合公司內(nèi)部框架進(jìn)行使用,比如數(shù)據(jù)埋點(diǎn)、動(dòng)態(tài)配置等等,下面以事件通知接口為例子,看看Hystrix是如何實(shí)現(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();
}

通過(guò)getEventNotifier方法獲取事件通知器,當(dāng)然了,一開(kāi)始是沒(méi)有初始化的,先嘗試使用getPluginImplementation方法,看看能不能拿到,拿不到就使用本地默認(rèn)的實(shí)現(xiàn)。

private <T> T getPluginImplementation(Class<T> pluginClass) {
    T p = getPluginImplementationViaProperties(pluginClass, dynamicProperties);
    if (p != null) return p;        
    return findService(pluginClass, classLoader);
}

這里,Hystrix還提供了另外一種實(shí)現(xiàn),很簡(jiǎn)單,就不解釋了,這里的重點(diǎn)是findService實(shí)現(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;
}

其實(shí),這里的實(shí)現(xiàn)是使用Java內(nèi)置的SPI機(jī)制,SPI是什么?

SPI 全稱(chēng)為 Service Provider Interface),是一種服務(wù)提供發(fā)現(xiàn)機(jī)制,通過(guò)ServiceLoader類(lèi)的load方法,可以自動(dòng)找到實(shí)現(xiàn)對(duì)應(yīng)接口的實(shí)現(xiàn)類(lèi),為了更清晰的了解其中原理,可以去看看load方法的源碼實(shí)現(xiàn)。

一個(gè)大概的過(guò)程是:load方法會(huì)嘗試在classpath下META-INF/services/文件夾下查找一個(gè)文件,其中文件名是接口的全限定名。

如上圖所述,CacheKeyFilter是一個(gè)接口,在這個(gè)文件中,需要指定接口實(shí)現(xiàn)類(lèi)的全限定名。

當(dāng)然了,你也可以換行指定多個(gè),找到這些實(shí)現(xiàn)類(lèi)之后,會(huì)通過(guò)反射機(jī)制,即class.newInstance()進(jìn)行實(shí)例化,這就要求實(shí)現(xiàn)類(lèi)需要有無(wú)參構(gòu)造函數(shù),

通過(guò)這種方式,我們就可以愉快的對(duì)開(kāi)源框架所提供的接口進(jìn)行擴(kuò)展,加入各種騷操作,還不動(dòng)手試試?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,555評(píng)論 19 139
  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱(chēng)項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,203評(píng)論 3 119
  • 選項(xiàng)自定義功能區(qū)添加開(kāi)發(fā)工具; 圖形布爾運(yùn)算; 選取、應(yīng)用對(duì)象樣式; 窗口式幻燈片放映。
    狼尾草閱讀 345評(píng)論 0 0
  • 爸爸節(jié),以此文獻(xiàn)給我的爸爸 時(shí)光時(shí)光慢些吧 不要再讓你變老 我愿用我一切 換你歲月長(zhǎng)留 你不在我身邊 ,托清風(fēng)捎去...
    夕顏花開(kāi)又花落閱讀 370評(píng)論 0 0
  • 近日,一個(gè)日本青年在北京街頭求擁抱的視頻在網(wǎng)上傳開(kāi)。 看完這段視頻,感動(dòng)之余,只是覺(jué)得他們侵略過(guò),我們抗擊過(guò),他們...
    暖風(fēng)呦呦閱讀 552評(píng)論 0 0

友情鏈接更多精彩內(nèi)容