39.2. Component インターフェイスの実装

DefaultComponent クラス

org.apache.camel.impl.DefaultComponent クラスを拡張して新しいコンポーネントを実装します。これにより、一部のメソッドに標準機能とデフォルトの実装が提供されます。特に、DefaultComponent クラスは URI 解析と スケジュール済みエグゼキューター の作成をサポートします (スケジュールされたポーリングパターンに使用されます)。

URI の解析

ベースコンポーネントインターフェイスで定義される createEndpoint(String uri) メソッドは、完全かつ解析されていないエンドポイント URI を唯一の引数として取ります。一方、DefaultComponent クラスは、以下の署名で createEndpoint() メソッドの 3 つの引数バージョンを定義します。

protected abstract Endpoint createEndpoint(
    String uri,
    String remaining,
    Map parameters
)
throws Exception;

uri は、元の解析されていない URI です。remaining は、開始時にコンポーネント接頭辞を削除し、最後のクエリーオプションを削除した後に残る URI の一部で、parameters は解析されたクエリーオプションが含まれます。createEndpoint() から継承時に上書きする必要があるのは、DefaultComponent メソッドのこのバージョンです。これには、エンドポイント URI がすでに解析されているという利点があります。

次の file コンポーネントのサンプルエンドポイント URI は、URI 解析の仕組みを示しています。

file:///tmp/messages/foo?delete=true&moveNamePostfix=.old

この URI では、引数が 3 つのバージョンの createEndpoint() に以下の引数が渡されます。

引数サンプル値

uri

file:///tmp/messages/foo?delete=true&moveNamePostfix=.old

remaining

/tmp/messages/foo

parameters

2 つのエントリーが java.util.Map に設定されています。

  • パラメーター delete はブール値 true です。
  • パラメーター moveNamePostfix には、文字列値 .old があります。

パラメーターの注入

デフォルトでは、URI クエリーオプションから抽出されたパラメーターはエンドポイントの Bean プロパティーに注入されます。DefaultComponent クラスは、ユーザーのパラメーターを自動的に注入します。

たとえば、2 つの URI クエリーオプション (delete および moveNamePostfix) をサポートするカスタムエンドポイントを定義する場合などです。エンドポイントクラスで対応する Bean メソッド (getter と setter) を定義するだけです。

public class FileEndpoint extends ScheduledPollEndpoint {
    ...
    public boolean isDelete() {
        return delete;
    }
    public void setDelete(boolean delete) {
        this.delete = delete;
    }
    ...
    public String getMoveNamePostfix() {
        return moveNamePostfix;
    }
    public void setMoveNamePostfix(String moveNamePostfix) {
        this.moveNamePostfix = moveNamePostfix;
    }
}

URI クエリーオプションを コンシューマーパラメーター に注入することもできます。詳細は、「コンシューマーパラメーターの注入」 を参照してください。

エンドポイントパラメーター注入の無効化

Endpoint クラスにパラメーターが定義されていない場合は、エンドポイントパラメーターの注入を無効にすることで、エンドポイント作成のプロセスを最適化できます。エンドポイントでパラメーターの注入を無効にするには、以下のように useIntrospectionOnEndpoint() メソッドを上書きし、false を返すように実装します。

protected boolean useIntrospectionOnEndpoint() {
  return false;
}
注記

useIntrospectionOnEndpoint() メソッドは、Consumer クラスで実行される可能性のあるパラメーターの注入には影響しません。このレベルのパラメーターの注入は Endpoint.configureProperties() メソッドによって制御されます (「エンドポイントインターフェイスの実装」 を参照)。

スケジュール済みエグゼキューターサービス

スケジュールされたエグゼキューターは、スケジュールされたポーリングパターンで使用されます。ここでは、コンシューマーエンドポイントの定期的なポーリングを行います (スケジュール済みエグゼキューターは、実質的にスレッドプールの実装です)。

スケジュールされたエグゼキューターサービスをインスタンス化するには、CamelContext.getExecutorServiceStrategy() メソッドによって返される ExecutorServiceStrategy オブジェクトを使用します。Apache Camel スレッドモデルの詳細は、「スレッドモデル」 を参照してください。

注記

Apache Camel 2.3 以前、DefaultComponent クラスはスレッドプールインスタンスを作成するための getExecutorService() メソッドを提供していました。ただし、2.3 以降、スレッドプールの作成は ExecutorServiceStrategy オブジェクトによって集中管理されるようになりました。

URI の検証

エンドポイントインスタンスを作成する前に URI を検証する場合は、以下の署名を持つ DefaultComponent クラスから validateURI() メソッドを上書きすることができます。

protected void validateURI(String uri,
                           String path,
                           Map parameters)
   throws ResolveEndpointFailedException;

提供された URI に必要な形式がない場合は、validateURI() の実装によって org.apache.camel.ResolveEndpointFailedException 例外が発生するはずです。

エンドポイントの作成

例39.2「createEndpoint() の実装」 では、オンデマンドでエンドポイントインスタンスを作成する DefaultComponent.createEndpoint() メソッドの実装方法を概説します。

例39.2 createEndpoint() の実装

public class CustomComponent extends DefaultComponent { 1
    ...
    protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { 2
        CustomEndpoint result = new CustomEndpoint(uri, this); 3
        // ...
        return result;
    }
}
1
CustomComponent は、DefaultComponent クラスを拡張することで定義されるカスタムコンポーネントクラスの名前です。
2
DefaultComponent を拡張する場合は、3 つの引数 (「URI の解析」を参照) で createEndpoint() メソッドを実装する必要があります。
3
コンストラクターを呼び出して、カスタムエンドポイントタイプの CustomEndpoint のインスタンスを作成します。少なくとも、このコンストラクターは、元の URI 文字列 uri のコピーと、このコンポーネントインスタンスへの参照 this を取得します。

例39.3「FileComponent 実装」 は、FileComponent クラスの実装例を示しています。

例39.3 FileComponent 実装

package org.apache.camel.component.file;

import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.impl.DefaultComponent;

import java.io.File;
import java.util.Map;

public class FileComponent extends DefaultComponent {
    public static final String HEADER_FILE_NAME = "org.apache.camel.file.name";

    public FileComponent() { 1
    }

    public FileComponent(CamelContext context) { 2
        super(context);
    }

    protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { 3
        File file = new File(remaining);
        FileEndpoint result = new FileEndpoint(file, uri, this);
        return result;
    }
}
1
クラスの自動インスタンス化を容易にするために、コンポーネントクラスの引数なしコンストラクターを常に定義します。
2
プログラミングでコンポーネントを作成する際に、親の CamelContext インスタンスを引数として取るコンストラクターが便利です。
3
FileComponent.createEndpoint() メソッドの実装は、例39.2「createEndpoint() の実装」 に記載のパターンに従います。実装により FileEndpoint オブジェクトが作成されます。

SynchronizationRouteAware インターフェイス

SynchronizationRouteAware インターフェイスを使用すると、エクスチェンジがルーティングされる前および後にコールバックを指定できます。

  • onBeforeRoute: エクスチェンジが指定のルートによってルーティングされる前に呼び出されます。ただし、ルートの起動後に SynchronizationRouteAware 実装を UnitOfWork に追加した場合、このコールバックは呼び出されないことがあります。
  • onAfterRoute: エクスチェンジが指定のルートによってルーティングされた後に呼び出されます。ただし、エクスチェンジが複数のルートでルーティングされる場合は、ルートごとにコールバックを生成します。

    この呼び出しは、以下のコールバックの前に行われます。

    1. ルートのコンシューマーは、すべての応答を呼び出し元に書き込みます (InOut モードの場合)。
    2. UnitOfWork は、Synchronization.onComplete(org.apache.camel.Exchange) または Synchronization.onFailure(org.apache.camel.Exchange) を呼び出すことで行われます。