Camel運行原理分析

Camel運行原理分析

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

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

    //建立Camel上下文  ide

    DefaultCamelContext camelContext = new DefaultCamelContext();  ui

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

    camelContext.addRoutes(new RouteBuilder() {  spa

        @Override  線程

        public void configure() throws Exception {  debug

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

                @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的源碼進行分析:

1、路由的構建

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

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

2、組件查找方式

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。

3、路由的啓動原理

 

 

Camel啓動原理圖

4、路由的運行原理

 

 

圖一

 

 

圖二

相關文章
相關標籤/搜索