对于最新的稳定版本,请使用 Spring Integration 6.3.1Spring中文文档

对于最新的稳定版本,请使用 Spring Integration 6.3.1Spring中文文档

除了用于配置消息端点的 XML 命名空间支持之外,还可以使用注释。 首先,Spring Integration 将类级别作为构造型注解提供,这意味着它本身是用 Spring 的注解注注的,因此被 Spring 的组件扫描自动识别为 Bean 定义。@MessageEndpoint@ComponentSpring中文文档

更重要的是各种方法级注释。 它们指示带批注的方法能够处理消息。 下面的示例演示了类级和方法级批注:Spring中文文档

@MessageEndpoint
public class FooService {

    @ServiceActivator
    public void processMessage(Message message) {
        ...
    }
}

“处理”消息的方法究竟意味着什么取决于特定的注释。 Spring Integration 中可用的注解包括:Spring中文文档

如果将 XML 配置与批注结合使用,则不需要批注。 如果要从元素的属性配置 POJO 引用,则只能提供方法级注释。 在这种情况下,即使元素上不存在方法级属性,注释也可以防止歧义。@MessageEndpointref<service-activator/><service-activator/>

在大多数情况下,带批注的处理程序方法不应要求将类型作为其参数。 相反,方法参数类型可以与消息的有效负载类型匹配,如以下示例所示:MessageSpring中文文档

public class ThingService {

    @ServiceActivator
    public void bar(Thing thing) {
        ...
    }

}

当方法参数应从 中的值映射时,另一个选项是使用参数级注释。 通常,使用 Spring Integration 注释注释的方法可以接受本身、消息有效负载或标头值(带有 )作为参数。 事实上,该方法可以接受组合,如以下示例所示:MessageHeaders@HeaderMessage@HeaderSpring中文文档

public class ThingService {

    @ServiceActivator
    public void otherThing(String payload, @Header("x") int valueX, @Header("y") int valueY) {
        ...
    }

}

您还可以使用注释将所有消息标头作为 提供,如以下示例所示:@HeadersMapSpring中文文档

public class ThingService {

    @ServiceActivator
    public void otherThing(String payload, @Headers Map<String, Object> headerMap) {
        ...
    }

}
注释的值也可以是 SpEL 表达式(例如,),当您希望在注入标头值之前操作标头值时,这很有用。 它还提供了一个可选属性,该属性指定属性值是否必须在标头中可用。 该属性的默认值为 。someHeader.toUpperCase()requiredrequiredtrue

对于其中几个批注,当消息处理方法返回非 null 值时,终结点会尝试发送回复。 这在两个配置选项(命名空间和注释)中是一致的,因为使用此类端点的输出通道(如果可用),并且消息标头值用作回退。REPLY_CHANNELSpring中文文档

端点上的输出通道和回复通道消息标头的组合支持管道方法,其中多个组件具有输出通道,最终组件允许将回复消息转发到回复通道(如原始请求消息中指定的那样)。 换言之,最终组件取决于原始发送方提供的信息,因此可以动态支持任意数量的客户端。 这是返回地址模式的一个示例。

除了此处显示的示例之外,这些批注还支持 and 属性,如以下示例所示:inputChanneloutputChannelSpring中文文档

@Service
public class ThingService {

    @ServiceActivator(inputChannel="input", outputChannel="output")
    public void otherThing(String payload, @Headers Map<String, Object> headerMap) {
        ...
    }

}

这些注释的处理将创建与相应的 XML 组件相同的 Bean,这些组件是实例和实例(或入站通道适配器的实例)。 请参阅有关 @Bean 方法的注释。 Bean 名称由以下模式生成:。 在前面的示例中,Bean 名称是 和 相同的名称,但 () bean 的附加 () 后缀。 可以使用注释以及这些消息传递注释来自定义此类名称。 实例(实例)也有资格通过消息历史记录进行跟踪。AbstractEndpointMessageHandlerMessageSource[componentName].[methodName].[decapitalizedAnnotationClassShortName]thingService.otherThing.serviceActivatorAbstractEndpoint.handler.sourceMessageHandlerMessageSource@EndpointIdMessageHandlerMessageSourceSpring中文文档

从 V4.0 开始,所有消息传递注释都提供选项 ( 和 ),以允许对应用程序上下文初始化进行端点生命周期控制。 它们分别默认为 和 。 要更改端点的状态(例如 或 ),可以使用 (或 autowiring) 获取对端点 Bean 的引用并调用这些方法。 或者,您可以向 (请参阅控制总线) 发送命令消息。 为此,您应该使用上一段前面提到的方法。SmartLifecycleautoStartupphasetrue0start()stop()BeanFactoryControl BusbeanNameSpring中文文档

在解析上述注解后自动创建的通道(当没有配置特定的通道 Bean 时)以及相应的使用者端点,在上下文初始化接近尾声时被声明为 bean。 这些 Bean 可以在其他服务中自动连接,但必须使用注释进行标记,因为在正常的自动连接处理期间,定义通常尚不可用。@LazySpring中文文档

@Autowired
@Lazy
@Qualifier("someChannel")
MessageChannel someChannel;
...

@Bean
Thing1 dependsOnSPCA(@Qualifier("someInboundAdapter") @Lazy SourcePollingChannelAdapter someInboundAdapter) {
    ...
}

从 6.0 版开始,所有消息传递注释现在都已使用,因此可以在相同的服务方法上声明多个相同类型的消息传递注释,其含义是创建与重复这些注释一样多的端点:@RepeatableSpring中文文档

@Transformer(inputChannel = "inputChannel1", outputChannel = "outputChannel1")
@Transformer(inputChannel = "inputChannel2", outputChannel = "outputChannel2")
public String transform(String input) {
    return input.toUpperCase();
}
如果将 XML 配置与批注结合使用,则不需要批注。 如果要从元素的属性配置 POJO 引用,则只能提供方法级注释。 在这种情况下,即使元素上不存在方法级属性,注释也可以防止歧义。@MessageEndpointref<service-activator/><service-activator/>
注释的值也可以是 SpEL 表达式(例如,),当您希望在注入标头值之前操作标头值时,这很有用。 它还提供了一个可选属性,该属性指定属性值是否必须在标头中可用。 该属性的默认值为 。someHeader.toUpperCase()requiredrequiredtrue
端点上的输出通道和回复通道消息标头的组合支持管道方法,其中多个组件具有输出通道,最终组件允许将回复消息转发到回复通道(如原始请求消息中指定的那样)。 换言之,最终组件取决于原始发送方提供的信息,因此可以动态支持任意数量的客户端。 这是返回地址模式的一个示例。

在解析上述注解后自动创建的通道(当没有配置特定的通道 Bean 时)以及相应的使用者端点,在上下文初始化接近尾声时被声明为 bean。 这些 Bean 可以在其他服务中自动连接,但必须使用注释进行标记,因为在正常的自动连接处理期间,定义通常尚不可用。@LazySpring中文文档

@Autowired
@Lazy
@Qualifier("someChannel")
MessageChannel someChannel;
...

@Bean
Thing1 dependsOnSPCA(@Qualifier("someInboundAdapter") @Lazy SourcePollingChannelAdapter someInboundAdapter) {
    ...
}

使用注释@Poller

在 Spring Integration 4.0 之前,消息传递注释要求 be 引用 . 例如,需要一个元素来配置 an 并使复合端点为 . 版本 4.0 引入了注释,以允许直接在消息传递注释上配置属性,如以下示例所示:inputChannelSubscribableChannelPollableChannel<int:bridge/><int:poller/>PollingConsumer@PollerpollerSpring中文文档

public class AnnotationService {

    @Transformer(inputChannel = "input", outputChannel = "output",
        poller = @Poller(maxMessagesPerPoll = "${poller.maxMessagesPerPoll}", fixedDelay = "${poller.fixedDelay}"))
    public String handle(String payload) {
        ...
    }
}

注释仅提供简单的选项。 您可以使用属性占位符配置注释的属性(、、 和 )。 此外,从版本 5.1 开始,还提供了 s 选项。 如果需要提供更多轮询选项(例如,、、 等),则应将其配置为通用 Bean,并使用其 Bean 名称作为 的属性。 在这种情况下,不允许使用其他属性(必须在 Bean 上指定它们)。 请注意,如果配置了 a 且配置了 no,则使用默认值(如果它存在于应用程序上下文中)。 若要使用批注声明默认轮询器,请使用类似于以下示例的代码:@PollerPollerMetadata@PollermaxMessagesPerPollfixedDelayfixedRatecronreceiveTimeoutPollingConsumertransactionadvice-chainerror-handlerPollerMetadata@PollervaluePollerMetadatainputChannelPollableChannel@PollerPollerMetadata@ConfigurationSpring中文文档

@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
    PollerMetadata pollerMetadata = new PollerMetadata();
    pollerMetadata.setTrigger(new PeriodicTrigger(10));
    return pollerMetadata;
}

以下示例演示如何使用默认轮询器:Spring中文文档

public class AnnotationService {

    @Transformer(inputChannel = "aPollableChannel", outputChannel = "output")
    public String handle(String payload) {
        ...
    }
}

以下示例演示如何使用命名轮询器:Spring中文文档

@Bean
public PollerMetadata myPoller() {
    PollerMetadata pollerMetadata = new PollerMetadata();
    pollerMetadata.setTrigger(new PeriodicTrigger(1000));
    return pollerMetadata;
}

以下示例显示了使用默认轮询器的终结点:Spring中文文档

public class AnnotationService {

    @Transformer(inputChannel = "aPollableChannel", outputChannel = "output"
                           poller = @Poller("myPoller"))
    public String handle(String payload) {
         ...
    }
}

从版本 4.3.3 开始,注释具有该属性,以便更轻松地配置基础 。 此属性的作用与 XML 组件中的角色相同。 有关详细信息,请参阅终结点命名空间支持@PollererrorChannelMessagePublishingErrorHandlererror-channel<poller>Spring中文文档

消息传递批注上的属性与属性互斥。 有关详细信息,请参阅下一节。poller()reactive()Spring中文文档

使用批注@Reactive

自 5.0 版以来一直存在,但仅当端点的输入通道是(或任何实现)时才应用它。 从版本 5.3 开始,当目标消息处理程序独立于输入通道类型时,框架也会创建其实例。 从版本 5.5 开始,所有消息传递注释都引入了子注释(类似于上面提到的)。 它接受可选的 Bean 引用,并且独立于输入通道类型和消息处理程序,将目标端点转换为实例。 该函数用于从操作员对来自输入通道的反应式流源应用一些自定义(、、等)。ReactiveStreamsConsumerFluxMessageChannelorg.reactivestreams.PublisherReactiveMessageHandler@Reactive@PollerFunction<? super Flux<Message<?>>, ? extends Publisher<Message<?>>>ReactiveStreamsConsumerFlux.transform()publishOn()doOnNext()log()retry()Spring中文文档

以下示例演示如何将发布线程从独立于最终订阅者和创建者的输入通道更改为该线程:DirectChannelSpring中文文档

@Bean
public Function<Flux<?>, Flux<?>> publishOnCustomizer() {
    return flux -> flux.publishOn(Schedulers.parallel());
}

@ServiceActivator(inputChannel = "directChannel", reactive = @Reactive("publishOnCustomizer"))
public void handleReactive(String payload) {
    ...
}

消息传递批注上的属性与属性互斥。 有关更多信息,请参阅使用 @Poller AnnotationReactive Streams 支持reactive()poller()Spring中文文档

使用注释@InboundChannelAdapter

版本 4.0 引入了方法级注释。 它基于注释方法生成一个集成组件。 此批注是 XML 组件的类似物,具有相同的限制:方法不能有参数,返回类型不得为 。 它有两个属性:(必需的 Bean 名称)和(可选的注释,如前所述)。 如果需要提供一些 ,请使用返回类型并使用 a 来构建 . 使用 a 可以配置 . 以下示例演示如何使用批注:@InboundChannelAdapterSourcePollingChannelAdapterMethodInvokingMessageSource<int:inbound-channel-adapter>voidvalueMessageChannelpoller@PollerMessageHeadersMessage<?>MessageBuilderMessage<?>MessageBuilderMessageHeaders@InboundChannelAdapterSpring中文文档

@InboundChannelAdapter("counterChannel")
public Integer count() {
    return this.counter.incrementAndGet();
}

@InboundChannelAdapter(value = "fooChannel", poller = @Poller(fixed-rate = "5000"))
public String foo() {
    return "foo";
}

版本 4.3 引入了 annotation 属性的别名,以提供更好的源代码可读性。 此外,目标 Bean 在第一次调用时通过提供的名称(由 option 设置)进行解析,而不是在初始化阶段。 它允许“后期绑定”逻辑:从消费者的角度来看,目标 Bean 的创建和注册时间比解析阶段晚一点。channelvalueMessageChannelSourcePollingChannelAdapteroutputChannelNamereceive()MessageChannel@InboundChannelAdapterSpring中文文档

第一个示例要求在应用程序上下文中的其他位置声明了默认轮询器。Spring中文文档

使用注释@MessagingGatewaySpring中文文档

使用注释@IntegrationComponentScan

标准的 Spring Framework 注解不会扫描界面中的构造型注解。 为了克服这个限制并允许配置(参见@MessagingGateway注释),我们引入了该机制。 此注释必须与注释一起放置,并自定义以定义其扫描选项, 如 和 . 在这种情况下,所有发现的带有注释的接口都将被解析并注册为实例。 所有其他基于类的组件都由标准 解析。@ComponentScan@Component@MessagingGateway@IntegrationComponentScan@ConfigurationbasePackagesbasePackageClasses@MessagingGatewayGatewayProxyFactoryBean@ComponentScanSpring中文文档