訊息元註解

從 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 版本引入了對使用 @InboundChannelAdapter 註解的 @Bean 的支援,該註解傳回 java.util.function.Supplier,它可以產生 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 無法直接在目標端點中使用 (不是 MessageSourceAbstractReplyProducingMessageHandlerAbstractMessageRouter 的實例),則會註冊對應的 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();
}

您也可以將這些註解用作元註解。

為註解端點提供 Advice