消息元注解

从 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 名称使用以下算法生成
  • MessageHandlerMessageSource@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();
}

您也可以将这些注释用作元注释。

建议带注释的端点