メッセージングメタアノテーション

バージョン 4.0 以降、すべてのメッセージングアノテーションをメタアノテーションとして構成でき、すべてのユーザー定義のメッセージングアノテーションは同じ属性を定義してデフォルト値をオーバーライドできます。さらに、次の例に示すように、メタアノテーションを階層的に構成できます。

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@ServiceActivator(inputChannel = "annInput", outputChannel = "annOutput")
public @interface MyServiceActivator {

    String[] adviceChain = { "annAdvice" };
}

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@MyServiceActivator
public @interface MyServiceActivator1 {

    String inputChannel();

    String outputChannel();
}
...

@MyServiceActivator1(inputChannel = "inputChannel", outputChannel = "outputChannel")
public Object service(Object payload) {
   ...
}

メタアノテーションを階層的に構成すると、ユーザーはさまざまな属性のデフォルトを設定でき、フレームワーク Java のユーザーアノテーションへの依存関係を分離して、ユーザークラスでの使用を回避できます。フレームワークが、フレームワークメタアノテーションを持つユーザーアノテーションを持つメソッドを見つけると、そのメソッドがフレームワークアノテーションで直接アノテーション付けされたかのように扱われます。

@Bean メソッドのアノテーション

バージョン 4.0 以降では、@Configuration クラスの @Bean メソッド定義にメッセージングアノテーションを構成して、メソッドではなく Bean に基づいてメッセージエンドポイントを生成できます。@Bean 定義が「すぐに使える」 MessageHandler インスタンス(AggregatingMessageHandlerDefaultMessageSplitter など)、Transformer インスタンス(JsonToObjectTransformerClaimCheckOutTransformer など)、MessageSource インスタンス(FileReadingMessageSourceRedisStoreMessageSource など)である場合に役立ちます。次の例は、@Bean アノテーションでメッセージングアノテーションを使用する方法を示しています。

@Configuration
@EnableIntegration
public class MyFlowConfiguration {

    @Bean
    @InboundChannelAdapter(value = "inputChannel", poller = @Poller(fixedDelay = "1000"))
    public MessageSource<String> consoleSource() {
        return CharacterStreamReadingMessageSource.stdin();
    }

    @Bean
    @Transformer(inputChannel = "inputChannel", outputChannel = "httpChannel")
    public ObjectToMapTransformer toMapTransformer() {
        return new ObjectToMapTransformer();
    }

    @Bean
    @ServiceActivator(inputChannel = "httpChannel")
    public HttpRequestExecutingMessageHandler httpHandler() {
    HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("https://foo/service");
        handler.setExpectedResponseType(String.class);
        handler.setOutputChannelName("outputChannel");
        return handler;
    }

    @Bean
    @ServiceActivator(inputChannel = "outputChannel")
    public LoggingHandler loggingHandler() {
        return new LoggingHandler("info");
    }

}

バージョン 5.0 では、java.util.function.Supplier を返す @InboundChannelAdapter でアノテーションが付けられた @Bean のサポートが導入されました。これにより、POJO または Message のいずれかを生成できます。次の例は、その組み合わせの使用方法を示しています。

@Configuration
@EnableIntegration
public class MyFlowConfiguration {

    @Bean
    @InboundChannelAdapter(value = "inputChannel", poller = @Poller(fixedDelay = "1000"))
    public Supplier<String> pojoSupplier() {
        return () -> "foo";
    }

    @Bean
    @InboundChannelAdapter(value = "inputChannel", poller = @Poller(fixedDelay = "1000"))
    public Supplier<Message<String>> messageSupplier() {
        return () -> new GenericMessage<>("foo");
    }
}

メタアノテーションルールは @Bean メソッドでも機能します(前述の @MyServiceActivator アノテーションは @Bean 定義に適用できます)。

コンシューマー @Bean 定義でこれらのアノテーションを使用する場合、Bean 定義が適切な MessageHandler を返す場合(アノテーション型に応じて)、MessageHandler@Bean 定義自体に属性(outputChannelrequiresReplyorder など)を設定する必要があります。次のアノテーション属性のみが使用されます: adviceChainautoStartupinputChannelphasepoller。他のすべての属性はハンドラー用です。
Bean 名は、次のアルゴリズムで生成されます。
  • MessageHandler (MessageSource) @Bean は、@Bean のメソッド名または name 属性から独自の標準名を取得します。これは、@Bean メソッドにメッセージングアノテーションがなかったかのように機能します。

  • AbstractEndpoint Bean 名は、[@Bean name].[decapitalizedAnnotationClassShortName] というパターンで生成されます。例: 前に示したconsoleSource() 定義の SourcePollingChannelAdapter エンドポイントは、consoleSource.inboundChannelAdapter という Bean 名を取得します。POJO メソッドとは異なり、Bean メソッド名はエンドポイント Bean 名に含まれません。エンドポイント Bean 名も参照してください。

  • ターゲットエンドポイントで @Bean を直接使用できない場合 ( MessageSourceAbstractReplyProducingMessageHandler または AbstractMessageRouter のインスタンスではない)、それぞれの AbstractStandardMessageHandlerFactoryBean が登録されて、この @Bean に委譲されます。このラッパーの Bean 名は、パターン [@Bean name].[decapitalizedAnnotationClassShortName].[handler (or source)] で生成されます。

@Bean 定義でこれらのアノテーションを使用する場合、inputChannel は宣言された Bean を参照する必要があります。チャネルは、アプリケーションコンテキストにまだ存在しない場合、自動的に宣言されます。

Java 構成では、@Bean メソッドレベルで @Conditional (たとえば @Profile)定義を使用して、何らかの条件付きの理由で Bean 登録をスキップできます。次の例は、その方法を示しています。

@Bean
@ServiceActivator(inputChannel = "skippedChannel")
@Profile("thing")
public MessageHandler skipped() {
    return System.out::println;
}

既存の Spring コンテナーロジックと一緒に、メッセージングエンドポイント Bean(@ServiceActivator アノテーションに基づく)も登録されていません。

アノテーション付きのブリッジを作成する

バージョン 4.0 以降、Java 構成は @BridgeFrom および @BridgeTo@Bean メソッドのアノテーションを提供して、@Configuration クラスの MessageChannel Bean をマークします。これらは完全を期すために実際に存在し、BridgeHandler とそのメッセージエンドポイント構成を宣言するための便利なメカニズムを提供します。

@Bean
public PollableChannel bridgeFromInput() {
    return new QueueChannel();
}

@Bean
@BridgeFrom(value = "bridgeFromInput", poller = @Poller(fixedDelay = "1000"))
public MessageChannel bridgeFromOutput() {
    return new DirectChannel();
}
@Bean
public QueueChannel bridgeToOutput() {
    return new QueueChannel();
}

@Bean
@BridgeTo("bridgeToOutput")
public MessageChannel bridgeToInput() {
    return new DirectChannel();
}

これらのアノテーションは、メタアノテーションとしても使用できます。

アノテーション付きエンドポイントへのアドバイス