訊息元註解

從 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 註解並返回 java.util.function.Supplier@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。所有其他屬性都用於 handler。
Bean 名稱按照以下演算法生成
  • MessageHandler (MessageSource) 的 @Bean 根據方法名稱或 @Bean 上的 name 屬性獲取其標準名稱。這就像 @Bean 方法上沒有訊息處理註解一樣工作。

  • AbstractEndpoint bean 名稱按照以下模式生成:[@Bean name].[decapitalizedAnnotationClassShortName]。例如,前面所示的 consoleSource() 定義的 SourcePollingChannelAdapter 端點獲得的 bean 名稱是 consoleSource.inboundChannelAdapter。與 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