如需使用最新稳定版本,请使用 Spring Integration 7.0.4spring-doc.cadn.net.cn

消息元注解

从版本 4.0 开始,所有消息注解都可以配置为元注解,并且所有用户定义的消息注解都可以定义相同的属性以覆盖其默认值。 此外,元注解可以分层配置,如下例所示:spring-doc.cadn.net.cn

@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 依赖隔离到用户注解中,避免在用户类中使用这些依赖。 如果框架发现某个方法上使用了带有框架元注解的用户注解,则该方法将被视为直接标注了该框架注解。spring-doc.cadn.net.cn

注解在@Bean方法

从 4.0 版本开始,您可以在 @Bean 类的方法定义上配置消息注解,从而基于 Bean 而非方法生成消息端点。 这在以下场景非常有用:@Bean 定义是开箱即用的 MessageHandler 实例(AggregatingMessageHandlerDefaultMessageSplitter 等)、Transformer 实例(JsonToObjectTransformerClaimCheckOutTransformer 等)以及 MessageSource 实例(FileReadingMessageSourceRedisStoreMessageSource 等)。 以下示例展示了如何将消息注解与 @Bean 注解配合使用:spring-doc.cadn.net.cn

@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。 以下示例展示了如何使用这种组合:spring-doc.cadn.net.cn

@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 定义)。spring-doc.cadn.net.cn

当您在消费者 @Bean 定义上使用这些注解时,如果 bean 定义返回了适当的 MessageHandler(取决于注解类型),则必须在 MessageHandler @Bean 定义本身上设置属性(例如 outputChannelrequiresReplyorder 等)。 仅使用以下注解属性:adviceChainautoStartupinputChannelphasepoller。 所有其他属性均用于处理器。
Bean 名称按照以下算法生成:
  • The MessageHandler (MessageSource) @Bean 从其方法名或 @Bean 上的 name 属性获取其自身的标准名称。 此行为相当于在 @Bean 方法上没有任何消息注解。spring-doc.cadn.net.cn

  • AbstractEndpoint Bean 的名称使用以下模式生成:[@Bean name].[decapitalizedAnnotationClassShortName]。 例如,前面所示consoleSource() 定义的 SourcePollingChannelAdapter 端点,其 Bean 名称为 consoleSource.inboundChannelAdapter。 与 POJO 方法不同,Bean 方法名不包含在端点 Bean 名称中。 另请参阅 端点 Bean 名称spring-doc.cadn.net.cn

  • 如果@Bean不能直接用于目标端点(即它不是MessageSourceAbstractReplyProducingMessageHandlerAbstractMessageRouter的实例),则会注册一个相应的AbstractStandardMessageHandlerFactoryBean来委托调用此@Bean。 该包装器的 Bean 名称按以下模式生成:[@Bean name].[decapitalizedAnnotationClassShortName].[handler (or source)]spring-doc.cadn.net.cn

当在 @Bean 定义上使用这些注解时,inputChannel 必须引用一个已声明的 Bean。 如果应用上下文中尚未存在通道,则会自动声明它们。

使用 Java 配置,您可以在 @Conditional(例如 @Profile)定义上使用 @Bean 方法级别的注解,以基于某些条件跳过 Bean 注册。 以下示例展示了如何实现这一点:spring-doc.cadn.net.cn

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

与现有的 Spring 容器逻辑一起,消息端点 bean(基于@ServiceActivator注解)也不会被注册。spring-doc.cadn.net.cn

使用注解创建桥接

从版本 4.0 开始,Java 配置提供了 @BridgeFrom@BridgeTo @Bean 方法注解,用于在 MessageChannel 类中标记 @Configuration Bean。 这些注解确实存在以完善功能,提供了一种便捷的机制来声明 BridgeHandler 及其消息端点配置:spring-doc.cadn.net.cn

@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();
}

您也可以将这些注解用作元注解。spring-doc.cadn.net.cn

为注解端点提供建议