您好,登錄后才能下訂單哦!
這篇文章主要介紹如何實(shí)現(xiàn)回調(diào)和spring的LambdaSafe類,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
在閱讀spring boot源碼時(shí)發(fā)現(xiàn)了WebServerFactoryCustomizerBeanPostProcessor類中有
LambdaSafe.callbacks(WebServerFactoryCustomizer.class, getCustomizers(), webServerFactory) .withLogger(WebServerFactoryCustomizerBeanPostProcessor.class) .invoke((customizer) -> customizer.customize(webServerFactory));
的用法。搜索了一下國內(nèi)網(wǎng)站,發(fā)現(xiàn)沒有相關(guān)資料,所以只能去spring官方網(wǎng)站上查閱文檔學(xué)習(xí)一下。
我們知道一切皆可“類”化的java中沒有函數(shù)指針,而函數(shù)指針可以用來實(shí)現(xiàn)編程中較為普遍使用的“回調(diào)”。所謂“回調(diào)“是和“調(diào)用”相反的過程,如果用類和消息來理解就是,類A調(diào)用類B的方法,可以認(rèn)為是類A向類B發(fā)送了一個(gè)消息,這個(gè)過程被稱為”調(diào)用”。對于類B來說,B
被動(dòng) 接收了這個(gè)消息。但是如果類B的方法在處理這個(gè)消息的過程中,又需要類A才有的數(shù)據(jù)或者類A才有能力拿到的數(shù)據(jù),這時(shí)候類B需要向類A發(fā)送一個(gè)消息(調(diào)用類A的方法),主動(dòng) 請求獲取數(shù)據(jù)。這時(shí)候類B就需要知道類A的方法如何調(diào)用,這個(gè)過程稱為”回調(diào)”。
如果是c/c++,可以直接給類B傳入一個(gè)類A方法的函數(shù)指針。但是java中不存在現(xiàn)成的“函數(shù)指針”可以使用,所以出現(xiàn)了幾種類“函數(shù)指針”的形式。一種是比較常見的使用接口+方法的形式實(shí)現(xiàn)類函數(shù)指針的方式,這種接口被稱為函數(shù)式接口,另一種是java 8中的新特性lambda表達(dá)式,本質(zhì)上也是一種函數(shù)式接口。
Java中定義了一個(gè)
@FunctionalInterface注解來修飾接口實(shí)現(xiàn)的”函數(shù)指針”,但是這個(gè)注解并不是必須的,只要滿足函數(shù)式接口標(biāo)準(zhǔn)的接口都可以作為”函數(shù)指針”。如果一個(gè)接口不滿足函數(shù)式接口標(biāo)準(zhǔn),同時(shí)注解了
@FunctionalInterface,那么編譯器就會報(bào)錯(cuò),這個(gè)注解相當(dāng)于能夠更好的方便編譯器進(jìn)行檢查?,F(xiàn)在我們以上面代碼中涉及的函數(shù)式接口來舉例。
@FunctionalInterface public interface WebServerFactoryCustomizer<T extends WebServerFactory> { void customize(T factory); }
WebServerFactoryCustomizer是一個(gè)提供給用戶用來定制WebServerFactory實(shí)例的接口。這個(gè)函數(shù)式接口的使用是在上面代碼的invoke方法的lambda表達(dá)式中,主要是處理傳入的WebServerFactory實(shí)例的bean,然后繼承這個(gè)函數(shù)式接口就可以對這個(gè)實(shí)例為所欲為。 好了,基礎(chǔ)介紹完了,終于到我們的主角LambdaSafe類了。spring 官方文檔給的解釋是
Utility that can be used to invoke lambdas in a safe way. Primarily designed to help support generically typed callbacks where class cast exceptions need to be dealt with due to class erasure.
。大意就是說LambdaSafe可以用來安全的運(yùn)行l(wèi)ambda表達(dá)式,所謂的安全就是指可以支持處理在“回調(diào)”過程中因?yàn)轭愋筒脸╦ava泛型中的概念)而需要拋出異常的情況。
那么實(shí)際上如何實(shí)現(xiàn)的呢?先看LambdaSafe.callbacks方法。在上面代碼中,LambdaSafe.callbacks傳入了WebServerFactoryCustomizer.class、getCustomizers()和需要被為所欲為的WebServerFactory實(shí)例。getCustomizers()的返回值會獲取所有WebServerFactoryCustomizer函數(shù)式接口的實(shí)現(xiàn)類,可以理解獲取了一堆函數(shù)指針。
private List<WebServerFactoryCustomizer<?>> customizers; private Collection<WebServerFactoryCustomizer<?>> getCustomizers() { if (this.customizers == null) { // Look up does not include the parent context this.customizers = new ArrayList<>(getWebServerFactoryCustomizerBeans()); this.customizers.sort(AnnotationAwareOrderComparator.INSTANCE); this.customizers = Collections.unmodifiableList(this.customizers); } return this.customizers; }
callbacks方法返回的是
public static <C, A> Callbacks<C, A> callbacks(Class<C> callbackType, Collection<? extends C> callbackInstances, A argument, Object... additionalArguments);
LambdaSafe中的內(nèi)部類LambdaSafe.Callback
具體看下invoke的代碼,也挺有意思的。
private final Collection<? extends C> callbackInstances; public void invoke(Consumer<C> invoker) { this.callbackInstances.forEach((callbackInstance) -> { invoke(callbackInstance, () -> { invoker.accept(callbackInstance); return null; }); }); }
Consumer
以上是“如何實(shí)現(xiàn)回調(diào)和spring的LambdaSafe類”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。