web-dev-qa-db-ja.com

ApacheCamel-起動時にタスクをトリガーして1回だけ実行する

CamelとSpringを使用してJavaプロジェクトに取り組んでいます。Springが処理を終了し、Camelがすべてのルートの構築を完了した後、シングルトンBeanで初期化メソッドをトリガーしたいと思います。

@Component springアノテーションから取得する他のクラスへの動的リンクがあり、これらのクラスがまだロードされているかどうかがわからないため、クラスの作成時にメソッドを呼び出すことはできません。コンストラクタ。

Camelの起動が完了した直後に1つまたは複数のメソッドを呼び出して1回だけ実行するにはどうすればよいですか?

ありがとう!

17
NightWolf

CamelContextがすべてのルートなどを開始した後にBeanmustを呼び出す必要がある場合は、Benが提案するように、タイマー付きのルートを使用できます。

考えられるより良い代替策は、CamelのEventNotifierAPIを使用することです。次に、起動されるCamelContextStartedEventのロジックを呼び出します。 EventNotifier APIの詳細はこちら: http://camel.Apache.org/eventnotifier-to-log-details-about-all-sent-exchanges.html

10
Claus Ibsen

もう少し柔軟性を与えるもう1つの簡単なオプションは、 camel-timer をrepeatCount = 1と、すべてを初期化するのに十分な長さの遅延値とともに使用することです。遅延/再試行などに基本的な例外処理を追加することもできます...

from("timer://runOnce?repeatCount=1&delay=5000").to("bean:runOnceBean");
22
Ben ODay

Beanのメソッドにロジックを追加し、@ PostConstructでアノテーションを付けます。このBeanが完全に初期化され、すべての依存関係が設定されると、springはこのメソッドを呼び出します。

@Component
class SomeClass {

 @PostConstruct
 void init() {
 }

}

Springアプリケーションコンテキスト全体が完全に初期化された後でロジックを呼び出す必要がある場合は、 LifeCycle インターフェイスを実装することで呼び出すことができます。

3
gkamal

1つの解決策は、いくつかのファイルにパッチを適用することです(PR https://github.com/Apache/camel/pull/684 を参照):CamelContextConfiguration.JavaおよびRoutesCollector.Java。

CamelContextConfigurationで、次のメソッドを追加します。

_void afterApplicationStart(CamelContext camelContext);
_

そして、onApplicationEventRoutesCollectorに次のようなものを追加します。

_        if (camelContextConfigurations != null) {
            for (CamelContextConfiguration camelContextConfiguration : camelContextConfigurations) {
                camelContextConfiguration.afterApplicationStart(camelContext);
            }
        }
_

この日付の最新バージョンを使用している場合は、if (camelContextConfigurations != null)を省略できます。

次に、次のようにSpring Beanを作成して、コードを追加します。

_@Bean
CamelContextConfiguration contextConfiguration() {
    return new CamelContextConfiguration() {

        @Override
        public void beforeApplicationStart(CamelContext camelContext) {
        }

        @Override
        public void afterApplicationStart(CamelContext camelContext) {
            // Put your code here
        }
    };
}
_

更新:このプルリクエストはマージされました。

3
user2066936

前に答えですでに示唆されたように、これはラクダの問題というよりはむしろ春です。 Springでは、InitializingBeanを実装し、menthodafterPropertiesSetを実装するだけです。これは、配線が完了したときに呼び出されます。

1

ラクダのコンテキストをシングルトンBeanに注入してみてください。コンテキストが完全に初期化されるまで、インジェクションは発生しません...すべてのルートの構築を含みます。欠点は、Bean内のコンテキストを実際に必要としない可能性があることです。シングルトンBeanの依存関係をSpring構成ファイルのcamelContext初期化にリンクするというアイデアを頭の中でいじっていますが、それが実際に機能するかどうかはわかりません。

1
Perception

http://camel.Apache.org/configuring-route-startup-ordering-and-autostartup.html :-に記載されているCamelの起動順序機能を使用できます。

<route startupOrder="1" id="thisOneGoesFirst">    
  <from uri="seda:foo"/>
  <to uri="mock:result"/>
</route>
<route startupOrder="2" id="thisOneGoesSecond">
  <from uri="direct:start"/>
  <to uri="seda:foo"/>
</route> 
<route id="thisOneGoesLast">
  <from uri="direct:bar"/>
  <to uri="seda:bar"/>
</route>

ここで、startupOrder属性を持つルートは、startupOrderを持たないすべてのルートの前に順番に実行されます。したがって、ルートが開始される前または後の任意の時点で、タイマーコンシューマーを使用してルートを設定できます。

1
mekondelta