此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Integration 6.5.1spring-doc.cadn.net.cn

注释支持

除了用于配置消息端点的 XML 命名空间支持外,您还可以使用注释。 首先,Spring Integration 提供了类级@MessageEndpoint作为刻板印象注释,这意味着它本身使用 Spring 的@Component注释,因此被 Spring 的组件扫描自动识别为 bean 定义。spring-doc.cadn.net.cn

更重要的是各种方法级注解。 它们表示带注释的方法能够处理消息。 以下示例演示了类级和方法级注解:spring-doc.cadn.net.cn

@MessageEndpoint
public class FooService {

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

方法“处理”消息的确切含义取决于特定的注释。 Spring Integration 中可用的注释包括:spring-doc.cadn.net.cn

如果将 XML 配置与注释结合使用,则@MessageEndpoint不需要注释。 如果要从ref属性<service-activator/>元素,则只能提供方法级注解。 在这种情况下,即使<service-activator/>元素。

在大多数情况下,带注释的处理程序方法不应要求Messagetype 作为其参数。 相反,方法参数类型可以与消息的有效负载类型匹配,如以下示例所示:spring-doc.cadn.net.cn

public class ThingService {

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

}

当方法参数应从MessageHeaders,另一种选择是使用 parameter-level@Header注解。 通常,使用 Spring Integration 注释 Comments 的方法可以接受Message本身、消息有效负载或标头值(@Header) 作为参数。 事实上,该方法可以接受组合,如以下示例所示:spring-doc.cadn.net.cn

public class ThingService {

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

}

您还可以使用@Headers注释,将所有消息头作为Map,如以下示例所示:spring-doc.cadn.net.cn

public class ThingService {

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

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

对于其中几个注释,当消息处理方法返回非空值时,端点会尝试发送回复。 这在两个配置选项(命名空间和注释)中是一致的,因为使用此类端点的输出通道(如果可用),并且REPLY_CHANNELmessage header 值用作回退。spring-doc.cadn.net.cn

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

除了此处显示的示例外,这些注释还支持inputChanneloutputChannel属性,如以下示例所示:spring-doc.cadn.net.cn

@Service
public class ThingService {

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

}

处理这些注释会创建与相应的 XML 组件相同的 bean——AbstractEndpointinstances 和MessageHandler实例(或MessageSource入站通道适配器的实例)。 看注释@Bean方法. Bean 名称是从以下模式生成的:[componentName].[methodName].[decapitalizedAnnotationClassShortName]. 在前面的示例中,bean 名称为thingService.otherThing.serviceActivator对于AbstractEndpoint和相同的名称,但有一个额外的.handler (.source) 后缀MessageHandler (MessageSource)豆。 可以使用@EndpointId注释以及这些消息传递注释。 这MessageHandler实例 (MessageSource实例)也有资格通过消息历史记录进行跟踪。spring-doc.cadn.net.cn

从 4.0 版开始,所有消息传递注释都提供SmartLifecycle选项 (autoStartupphase) 以允许对应用程序上下文初始化进行端点生命周期控制。 它们默认为true0分别。 要更改端点的状态(例如start()stop()),您可以使用BeanFactory(或自动布线)并调用方法。 或者,您可以向控制总线发送命令消息。 出于这些目的,您应该使用beanName前段所述。spring-doc.cadn.net.cn

在解析上述注释(当未配置特定通道 bean 时)和相应的消费者端点后自动创建的通道在上下文初始化结束时声明为 bean。 这些 bean 可以在其他服务中自动连接,但必须使用@Lazy注释,因为在正常的自动布线处理期间,定义通常尚不可用。spring-doc.cadn.net.cn

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

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

从 6.0 版开始,所有消息传递注释都是@Repeatable现在,可以在同一服务方法上声明多个相同类型的终结点,其含义是创建与重复这些注释一样多的端点:spring-doc.cadn.net.cn

@Transformer(inputChannel = "inputChannel1", outputChannel = "outputChannel1")
@Transformer(inputChannel = "inputChannel2", outputChannel = "outputChannel2")
public String transform(String input) {
    return input.toUpperCase();
}

使用@Poller注解

在 Spring Integration 4.0 之前,消息传递注释要求inputChannel是对SubscribableChannel. 为PollableChannel实例,则<int:bridge/>元素来配置<int:poller/>并使复合端点成为PollingConsumer. 4.0 版引入了@Poller注释以允许配置poller属性,如以下示例所示:spring-doc.cadn.net.cn

public class AnnotationService {

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

@Poller注释仅提供简单的PollerMetadata选项。 您可以配置@Poller注释的属性 (maxMessagesPerPoll,fixedDelay,fixedRatecron) 替换为属性占位符。 此外,从 5.1 版本开始,receiveTimeout选项PollingConsumer还提供了 s。 如果需要提供更多的轮询选项(例如,transaction,advice-chain,error-handler等),您应该配置PollerMetadata作为通用 bean,并将其 bean 名称用作@Pollervalue属性。 在这种情况下,不允许使用其他属性(必须在PollerMetadata豆子)。 请注意,如果inputChannel是一个PollableChannel和没有@Poller已配置,默认PollerMetadata(如果它存在于应用程序上下文中)。 要使用@Configuration注解,请使用类似于以下示例的代码:spring-doc.cadn.net.cn

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

以下示例显示如何使用默认轮询器:spring-doc.cadn.net.cn

public class AnnotationService {

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

以下示例演示如何使用命名轮询器:spring-doc.cadn.net.cn

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

以下示例显示了使用默认轮询器的终结点:spring-doc.cadn.net.cn

public class AnnotationService {

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

从 4.3.3 版本开始,@Poller注释具有errorChannel属性,以便更轻松地配置底层MessagePublishingErrorHandler. 此属性的作用与error-channel<poller>XML 组件。 有关详细信息,请参阅终结点命名空间支持spring-doc.cadn.net.cn

poller()属性与reactive()属性。 有关详细信息,请参阅下一节。spring-doc.cadn.net.cn

@Reactive注解

ReactiveStreamsConsumer自 5.0 版以来一直存在,但仅当端点的输入通道为FluxMessageChannel(或任何org.reactivestreams.Publisher实现)。 从 5.3 版开始,当目标消息处理程序为ReactiveMessageHandler独立于输入通道类型。 这@Reactive子注释(类似于上面提到的@Poller) 已为从 5.5 版开始的所有消息传递注释引入。 它接受可选的Function<? super Flux<Message<?>>, ? extends Publisher<Message<?>>>bean 引用,并且独立于输入通道类型和消息处理程序,将目标端点转换为ReactiveStreamsConsumer实例。 该函数从Flux.transform()运算符来应用一些自定义 (publishOn(),doOnNext(),log(),retry()等等)在来自输入通道的反应流源上。spring-doc.cadn.net.cn

以下示例演示如何将发布线程从输入通道更改为独立于最终订阅者和生产者DirectChannel:spring-doc.cadn.net.cn

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

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

reactive()属性与poller()属性。 看使用@Poller注解反应流支持了解更多信息。spring-doc.cadn.net.cn

使用@InboundChannelAdapter注解

4.0 版引入了@InboundChannelAdapter方法级注释。 它会产生一个SourcePollingChannelAdapter基于MethodInvokingMessageSource对于带注释的方法。 此注释类似于<int:inbound-channel-adapter>XML 组件,并且具有相同的限制:方法不能有参数,返回类型不得为void. 它有两个属性:value(所需的MessageChannelbean name) 和poller(可选的@Poller注释,如前所述)。 如果您需要提供一些MessageHeaders,请使用Message<?>返回类型,并使用MessageBuilder构建Message<?>. 使用MessageBuilder允许您配置MessageHeaders. 以下示例演示如何使用@InboundChannelAdapter注解:spring-doc.cadn.net.cn

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

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

4.3 版引入了channel别名valueannotation 属性,以提供更好的源代码可读性。 此外,目标MessageChannelbean 在SourcePollingChannelAdapter通过提供的名称(由outputChannelName选项)在第一个receive()调用,而不是在初始化阶段。 它允许“后期绑定”逻辑:目标MessageChannelbean 的创建和注册时间晚于@InboundChannelAdapter解析阶段。spring-doc.cadn.net.cn

第一个示例要求在应用程序上下文中的其他地方声明了默认轮询器。spring-doc.cadn.net.cn

使用@MessagingGateway注解spring-doc.cadn.net.cn

使用@IntegrationComponentScan注解

标准的 Spring 框架@ComponentScan注释不会扫描接口的构造型@Component附注。 为了克服此限制并允许配置@MessagingGateway(参见@MessagingGateway注解),我们引入了@IntegrationComponentScan机制。 此注释必须与@Configuration注释并自定义以定义其扫描选项, 如basePackagesbasePackageClasses. 在这种情况下,所有发现的接口都用@MessagingGateway被解析并注册为GatewayProxyFactoryBean实例。 所有其他基于类的组件都由标准解析@ComponentScan.spring-doc.cadn.net.cn