在上篇博文Apache Camel源碼研究之啓動中,我們在分析
DefaultCamelContext.start()
中回調的DefaultCamelContext.startRouteDefinitions(routeDefinitions);
方法時候,只是簡單地列出了其調用堆棧,並因其中所包含的ProcessorDefinition.addRoutes(RouteContext routeContext, Collection<Route> routes)
調用裏的邏輯比較複雜,我們只是對其進行了說明,沒有作進一步的分析。本文就將針對該類中的一些重要方法進行探究。
1. 概述
ProcessorDefinition
作爲一個泛型抽象類,其是幾乎所有Route定義節點類的基類(諸如 from()
對應的FromDefinition
,to()
對應的ToDefinition
,setProperty()
對應的SetPropertyDefinition
等等都是直接或間接繼承自該類),因此其內部所聲明的方法,重要性自然是不言而喻。本文接下來的部分將對其內部所定義的一些關鍵性的方法進行探討,以加深對於Apache Camel源碼的理解。
2. 相關繼承鏈
限於筆者屏幕的大小,無法將所有的節點展開,但從上圖中我們已經可以看到一些熟悉的面孔——OnExceptionDefinition
,OnCompletionDefinition
,ChoiceDefinition
等等。甚至還有與Route直接相關的RouteDefinition
。
3. 相關方法
3.1 ProcessorDefinition.addRoutes()
方法
定義如下:
// 最終由 RouteDefinition.addRoutes(CamelContext camelContext, Collection<Route> routes, FromDefinition fromType)回調
public void addRoutes(RouteContext routeContext, Collection<Route> routes) throws Exception {
...
}
總結如下:
- 該方法將被外界直接調用。將由
RouteDefinition.addRoutes()
直接調用。 - 作爲
ProcessorDefinition
類中對外的重要門面之一,其擔負着構建自身定義所代表的Route Processor節點(例如to()
對應的ToDefinition
之於SendProcessor
,setBody()
對應的SetBodyDefinition
之於SetBodyProcessor
等),並將該Processor節點實例添加到代表着Route的RouteContext
之中。
3.2 ProcessorDefinition.createProcessor
方法
定義如下:
/**
* Override this in definition class and implement logic to create the processor
* based on the definition model.
*/
public Processor createProcessor(RouteContext routeContext) throws Exception {
throw new UnsupportedOperationException("Not implemented yet for class: " + getClass().getName());
}
總結如下:
- 此方法雖然並沒有被標識爲
abstract
,但正如代碼實現所示,若直接調用將直接拋出異常。這就暗示了所有有需要的子類都必須實現本方法(注意這裏的用詞,上面提到的RouteDefinition
正是一個例外)。 - 每個
ProcessorDefinition
只負責自身對應的Processor的構建過程,這種“誰家孩子誰抱走"的設計思路有效隔離了關注點,使得構建邏輯變得清晰。
3.3 ProcessorDefinition.makeProcessorImpl
方法
定義如下:
private Processor makeProcessorImpl(RouteContext routeContext) throws Exception {
...
}
總結如下:
- 該方法作爲一個私有方法,能夠被單獨列出來,足以說明其重要性。
- 正是在此方法中,上面提到的
createProcessor(RouteContext routeContext)
方法被回調。並在此之後進行了一項非常關鍵性的操作 —— 對每個ProcessorDefinition
實現類所構建出來的Processor
實例進行Wrap,將其進行增強,詳見下方專門的小節。
3.4 ProcessorDefinition.wrapChannel
定義如下:
protected Processor wrapChannel(RouteContext routeContext, Processor processor, ProcessorDefinition<?> child) throws Exception {
...
}
總結如下:
- 本方法名就說明了其會對傳入的
Processor
實例作增強處理,附加上一些額外的功能。事實也確實如此。 - 在本方法中,Apache Camel會將傳入的
Processor
實例Wrap爲一個相應的Channel
實例,並根據配置爲其”披“上一層層的額外功能——例如Tracer,StreamCache,Delayer,MessageHistory,BacklogDebugger等。這些功能猶如Apache Tomcat中的Valve一樣,使得用戶編排的Processor
之間彼此隔離,避免直接接觸,爲擴展和優化提供緩衝,保證了架構內部的彈性。
4. 一些典型的Processor
WrapProcessor
。包裹原始的Processor,使其參與到Apache Camel的lifecycle中來。
5. 參考
- 《Apache Camel Developer’s Cookbook》
- 《Camel In Action》