注释支持
除了用于配置消息端点的 XML 名称空间支持之外,您还可以使用注释。
首先,Spring Integration 提供了类级@MessageEndpoint
作为构造型注释,这意味着它本身使用 Spring 的@Component
注解,因此被 Spring 的组件扫描自动识别为 bean 定义。
更重要的是各种方法级 Comments。 它们指示带注释的方法能够处理消息。 以下示例演示了类级和方法级 Comments:
@MessageEndpoint
public class FooService {
@ServiceActivator
public void processMessage(Message message) {
...
}
}
“处理”Message 的方法的确切含义取决于特定的 Comments。 Spring Integration 中可用的 Comments 包括:
-
@Aggregator
(请参阅 聚合器) -
@Filter
(请参阅过滤器) -
@Router
(请参阅 路由器) -
@ServiceActivator
(请参阅 Service Activator) -
@Splitter
(请参阅 Splitter) -
@Transformer
(请参阅 Transformer) -
@InboundChannelAdapter
(请参阅 Channel Adapter) -
@BridgeFrom
(请参阅使用 Java 配置配置 Bridge) -
@BridgeTo
(请参阅使用 Java 配置配置 Bridge) -
@MessagingGateway
(请参阅消息网关) -
@IntegrationComponentScan
(参见Configuration 和@EnableIntegration
)
如果您将 XML 配置与注解结合使用,则@MessageEndpoint 注释不是必需的。
如果要从ref 属性<service-activator/> 元素中,您只能提供方法级注解。
在这种情况下,注解可以防止歧义,即使<service-activator/> 元素。 |
在大多数情况下,带注解的处理程序方法不应要求Message
type 作为其参数。
相反,method 参数类型可以与消息的有效负载类型匹配,如下例所示:
public class ThingService {
@ServiceActivator
public void bar(Thing thing) {
...
}
}
当 method 参数应从MessageHeaders
,另一个选项是使用 parameter-level@Header
注解。
通常,使用 Spring 集成注释注释的方法可以接受Message
本身、消息负载或标头值(使用@Header
) 作为参数。
实际上,该方法可以接受组合,如下例所示:
public class ThingService {
@ServiceActivator
public void otherThing(String payload, @Header("x") int valueX, @Header("y") int valueY) {
...
}
}
您还可以使用@Headers
注解将所有消息标头作为Map
,如下例所示:
public class ThingService {
@ServiceActivator
public void otherThing(String payload, @Headers Map<String, Object> headerMap) {
...
}
}
注释的值也可以是 SPEL 表达式(例如,someHeader.toUpperCase() ),当您希望在注入 header 值之前对其进行作时,这非常有用。
它还提供了一个可选的required 属性,该属性指定属性值是否必须在标头中可用。
的required property 为true . |
对于其中几个注释,当消息处理方法返回非 null 值时,终端节点会尝试发送回复。
这在两个配置选项(namespace 和 annotations)中是一致的,因为使用了这种端点的输出通道(如果可用),并且REPLY_CHANNEL
message header 值用作回退。
端点上的输出通道和回复通道消息头的组合支持管道方法,其中多个组件有一个输出通道,最终组件允许将回复消息转发到回复通道(如原始请求消息中指定)。 换句话说,最终组件取决于原始发送方提供的信息,并且可以动态支持任意数量的客户端。 这是返回地址模式的一个示例。 |
除了此处显示的示例之外,这些注解还支持inputChannel
和outputChannel
属性,如下例所示:
@Service
public class ThingService {
@ServiceActivator(inputChannel="input", outputChannel="output")
public void otherThing(String payload, @Headers Map<String, Object> headerMap) {
...
}
}
这些 Comments 的处理将创建与相应的 XML 组件相同的 bean——AbstractEndpoint
instances 和MessageHandler
实例(或MessageSource
实例)。
看注释@Bean
方法.
Bean 名称由以下模式生成:[componentName].[methodName].[decapitalizedAnnotationClassShortName]
.
在前面的示例中,Bean 名称为thingService.otherThing.serviceActivator
对于AbstractEndpoint
和相同的名称,并附加一个.handler
(.source
) 后缀的MessageHandler
(MessageSource
) bean 的 Bean 中。
这样的名称可以使用@EndpointId
注释以及这些消息注释。
这MessageHandler
实例 (MessageSource
实例)也有资格被消息历史记录跟踪。
从版本 4.0 开始,所有消息收发注释都提供SmartLifecycle
选项 (autoStartup
和phase
) 以允许对应用程序上下文初始化进行终端节点生命周期控制。
它们默认为true
和0
分别。
要更改终端节点的状态(例如start()
或stop()
),您可以使用BeanFactory
(或自动装配)并调用方法。
或者,您可以向 Control Bus 发送命令消息。
为此,您应该使用beanName
前面在上一段中提到过。
在解析上述注释后自动创建的通道(当没有配置特定的通道 bean 时)和相应的消费者端点,在上下文初始化结束时被声明为 bean。
这些 bean 可以在其他服务中自动连接,但它们必须用
|
从版本 6.0 开始,所有消息传递注释都是@Repeatable
现在,可以在同一个 service method 上声明几个相同类型的 Token,其含义是创建与这些 Comments 重复的 Endpoints 一样多的 Endpoints:
@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
属性,如下例所示:
public class AnnotationService {
@Transformer(inputChannel = "input", outputChannel = "output",
poller = @Poller(maxMessagesPerPoll = "${poller.maxMessagesPerPoll}", fixedDelay = "${poller.fixedDelay}"))
public String handle(String payload) {
...
}
}
这@Poller
annotation 仅提供简单的PollerMetadata
选项。
您可以配置@Poller
注解的属性 (maxMessagesPerPoll
,fixedDelay
,fixedRate
和cron
) 替换为属性占位符。
此外,从版本 5.1 开始,receiveTimeout
选项PollingConsumer
s 的
如果需要提供更多轮询选项(例如,transaction
,advice-chain
,error-handler
等),您应该配置PollerMetadata
作为通用 Bean 使用,并使用其 Bean 名称作为@Poller
的value
属性。
在这种情况下,不允许使用其他属性(必须在PollerMetadata
bean) 的 Bean 的
注意,如果inputChannel
是一个PollableChannel
没有@Poller
,则默认的PollerMetadata
(如果它存在于应用程序上下文中)。
要使用@Configuration
annotation 中,请使用类似于以下示例的代码:
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(10));
return pollerMetadata;
}
下面的示例展示了如何使用默认 Poller:
public class AnnotationService {
@Transformer(inputChannel = "aPollableChannel", outputChannel = "output")
public String handle(String payload) {
...
}
}
下面的示例展示了如何使用命名的 Poller:
@Bean
public PollerMetadata myPoller() {
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(1000));
return pollerMetadata;
}
以下示例显示了使用默认 Poller 的终端节点:
public class AnnotationService {
@Transformer(inputChannel = "aPollableChannel", outputChannel = "output"
poller = @Poller("myPoller"))
public String handle(String payload) {
...
}
}
从版本 4.3.3 开始,@Poller
annotation 具有errorChannel
属性,以便更轻松地配置底层MessagePublishingErrorHandler
.
此属性的作用与error-channel
在<poller>
XML 组件。
有关更多信息,请参阅终端节点命名空间支持。
这poller()
属性与reactive()
属性。
有关更多信息,请参阅下一节。
用@Reactive
注解
这ReactiveStreamsConsumer
自 5.0 版本以来一直存在,但仅当端点的输入通道为FluxMessageChannel
(或任何org.reactivestreams.Publisher
实现)。
从版本 5.3 开始,当目标消息处理程序是ReactiveMessageHandler
独立于 input channel type。
这@Reactive
sub-annotation (类似于上面提到的@Poller
) 已针对从版本 5.5 开始的所有消息传递注释引入。
它接受一个可选的Function<? super Flux<Message<?>>, ? extends Publisher<Message<?>>>
Bean 引用,并且独立于输入通道类型和消息处理程序,将目标端点转换为ReactiveStreamsConsumer
实例。
该函数从Flux.transform()
运算符应用一些自定义 (publishOn()
,doOnNext()
,log()
,retry()
等)在来自 input 通道的反应式流源上。
下面的示例演示了如何将发布线程从独立于最终订阅者和生产者的 input 通道更改为该DirectChannel
:
@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
注解和 Reactive Streams Support 了解更多信息。
使用@InboundChannelAdapter
注解
版本 4.0 引入了@InboundChannelAdapter
方法级注解。
它生成一个SourcePollingChannelAdapter
集成组件基于MethodInvokingMessageSource
对于带注释的方法。
此注释类似于<int:inbound-channel-adapter>
XML 组件,并且具有相同的限制:方法不能有参数,并且返回类型不能是void
.
它有两个属性:value
(必需的MessageChannel
Bean 名称)和poller
(可选的@Poller
注释,如前所述)。
如果您需要提供一些MessageHeaders
,请使用Message<?>
return 类型并使用MessageBuilder
构建Message<?>
.
使用MessageBuilder
允许您配置MessageHeaders
.
以下示例演示如何使用@InboundChannelAdapter
注解:
@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
别名的value
annotation 属性,以提供更好的源代码可读性。
此外,目标MessageChannel
bean 在SourcePollingChannelAdapter
通过提供的名称(由outputChannelName
选项)在第一个receive()
调用,而不是在初始化阶段。
它允许 “late binding” 逻辑:目标MessageChannel
从消费者的角度来看,bean 的创建和注册时间比@InboundChannelAdapter
parsing 阶段。
第一个示例要求已在应用程序上下文中的其他位置声明默认 Poller。
使用@MessagingGateway
注解
使用@IntegrationComponentScan
注解
标准的 Spring 框架@ComponentScan
annotation 不扫描接口中的构造型@Component
附注。
为了克服此限制并允许配置@MessagingGateway
(参见@MessagingGateway
注解),我们引入了@IntegrationComponentScan
机制。
此注释必须与@Configuration
注释并自定义以定义其扫描选项,
如basePackages
和basePackageClasses
.
在这种情况下,所有发现的带有@MessagingGateway
被解析并注册为GatewayProxyFactoryBean
实例。
所有其他基于 class 的组件都由标准@ComponentScan
.