Camel運行原理分析


Camel運行原理分析

以一個簡單的例子說明一下camel的運行原理,例子本身很簡單,目的就是將一個目錄下的文件搬運到另一個文件夾,處理器只是將文件(限於文本文件)的內容打印到控制台,首先代碼如下:

public static void main(String[] args) throws Exception {  

    //創建Camel上下文  

    DefaultCamelContext camelContext = new DefaultCamelContext();  

    //添加一個路由,參數為路由建造者  

    camelContext.addRoutes(new RouteBuilder() {  

        @Override  

        public void configure() throws Exception {  

            this.from("file:D:/temp/in").process(new Processor() {  

                @Override  

                public void process(Exchange exchange) throws Exception {  

                    GenericFile<File> gf = exchange.getIn().getBody(GenericFile.class);  

                    File file = gf.getFile();  

                    PrintStream ps = new PrintStream(System.out);  

                    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));  

                    String line = null;  

                    while((line=br.readLine())!=null) {  

                        ps.println(line);  

                    }  

                    ps.close();  

                    br.close();  

                }  

            }).to("file:D:/temp/out");  

        }  

    });  

    //啟動上下文  

    camelContext.start();  

    //防止主線程退出  

    Object object = new Object();  

    synchronized (object) {  

        object.wait();  

    }  

}

 

對於camel來說,其原理核心的部分主要包含路由信息的構建、組件查找、和路由啟動過程三方面,下面結合以上簡單例子對三個方面來對camel的源碼進行分析:

一、路由的構建

其實這里說的路由構建其實是構建路由定義,對應Camel中的RouteDefinition類,一個RouteDefinition對象規定了或者說指定了一個消息從哪里產生,中間要經過什么樣的處理,最后路由到什么地方。RouteDefinitionRouteBuilder進行構建,再具體點就是調用RouteBuilderconfigure()方法,構建完成后再添加到CamelContext中,那么該路由定義就可以運行了。RouteBuilderconfigure()方法是一個抽象方法,所以該方法要由開發者進行實現,其實就是在進行路由定義的構建過程。

首先,調用RouteBuilderfrom方法獲取RouteDefinition,並且根據from傳入的參數將一個FromDefinition類型的實例設置給RouteDefinition的inputs(輸入)列表,然后調用RouteDefinition的process()to()方法,分別生成ProcessDefinition和ToDefinition對象,因為ProcessDefinition和ToDefinition都繼承自ProcessorDefinition,所以都可以看出輸出放到RouteDefinition的outputs(輸出)列表中,至此,整個路由定義就構建完成了,其實該路由定義最重要的就是輸入與輸出,輸入與輸出都可以有多個,默認情況下,在路由運行后,Camel會依賴調用這些輸出處理器並最終將消息路由到指定目的地。

二、組件查找方式

Camel的運行是由組件(component)進行組織的,我們前面的調用from()方法傳個字符串,camel是要根據uri來查找到對應的組件,即要維護uri到組件之間的映射關系,查找組件的過程是調用DefaultCamelContext中的getComponent(String name)方法來完成的,是在DefaultCamelContext啟動的時候調用,獲取相應的組件,生成對應的endPoint,組件的查找是從DefaultCamelContext上下文緩存的components中去找,如果沒有找到,就會去根據uri前綴生成一個component,生成的代碼大致如下:

// 先在注冊表中查找

        Object bean = null;

        try {

            bean = context.getRegistry().lookupByName(name);

            getLog().debug("Found component: {} in registry: {}", name, bean);

        } catch (Exception e) {

            getLog().debug("Ignored error looking up bean: " + name, e);

        }

    //省略了一部分代碼....

  // 注冊表中沒有時,使用Component工廠創建一個

        Class<?> type;

        try {

            type = findComponent(name, context);

            if (type == null) {

                // not found

                return null;

            }

        } catch (NoFactoryAvailableException e) {

            return null;

        } catch (Exception e) {

            throw new IllegalArgumentException("Invalid URI, no Component registered for scheme: " + name, e);

        }

   // 創建Component

        if (Component.class.isAssignableFrom(type)) {

            return (Component) context.getInjector().newInstance(type);

        } else {

            throw new IllegalArgumentException("Type is not a Component implementation. Found: " + type.getName());

        }

 

其中的findComponent方法是在camel包中默認路徑META-INF/services/org/apache/camel/component/+uri前綴名

找對應的Properties(不帶.properties后綴)文件,文件中有Component組件實例化的類名,找到后通過反射機制生成一個component組件,放到緩存中。我們自己也可以按照這個規則來拓展自己的component。

三、路由的啟動原理

 

 

Camel啟動原理圖

四、路由的運行原理

 

 

圖一

 

 

圖二

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM