对于最新的稳定版本,请使用 Spring Integration 6.3.4! |
对于最新的稳定版本,请使用 Spring Integration 6.3.4! |
除了用于配置消息端点的 XML 名称空间支持之外,您还可以使用注释。
首先, Spring 集成提供类级别作为原型注释,这意味着它本身使用 Spring 的注释进行注释,因此被 Spring 的组件扫描自动识别为 bean 定义。@MessageEndpoint
@Component
更重要的是各种方法级 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
(请参阅配置和@EnableIntegration
)
如果将 XML 配置与注释结合使用,则不需要注释。
如果要从元素的属性配置 POJO 引用,则只能提供方法级 Comments。
在这种情况下,即使元素上不存在方法级属性,注释也可以防止歧义。@MessageEndpoint ref <service-activator/> <service-activator/> |
在大多数情况下,带 Comments 的处理程序方法不应要求 type 作为其参数。
相反,method 参数类型可以与消息的有效负载类型匹配,如下例所示:Message
public class ThingService {
@ServiceActivator
public void bar(Thing thing) {
...
}
}
当 method 参数应从 中的值映射时,另一个选项是使用参数级注释。
通常,使用 Spring 集成注释注释的方法可以接受自身、消息有效负载或 Headers 值(带有)作为参数。
实际上,该方法可以接受组合,如下例所示:MessageHeaders
@Header
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 表达式(例如, ),当您希望在注入 Headers 值之前对其进行操作时,这非常有用。
它还提供了一个可选属性,用于指定属性值是否必须在标头中可用。
该属性的默认值为 .someHeader.toUpperCase() required required true |
对于其中几个注释,当消息处理方法返回非 null 值时,终端节点会尝试发送回复。
这在两个配置选项(命名空间和注释)中是一致的,因为使用此类终端节点的输出通道(如果可用),并且消息头值用作回退。REPLY_CHANNEL
端点上的输出通道和回复通道消息头的组合支持管道方法,其中多个组件有一个输出通道,最终组件允许将回复消息转发到回复通道(如原始请求消息中指定)。 换句话说,最终组件取决于原始发送方提供的信息,并且可以动态支持任意数量的客户端。 这是返回地址模式的一个示例。 |
除了此处显示的示例之外,这些注释还支持 and 属性,如下例所示:inputChannel
outputChannel
@Service
public class ThingService {
@ServiceActivator(inputChannel="input", outputChannel="output")
public void otherThing(String payload, @Headers Map<String, Object> headerMap) {
...
}
}
这些 Comments 的处理将创建与相应的 XML 组件相同的 bean——实例和实例(或入站通道适配器的实例)。
请参见 @Bean
方法上的注释。
Bean 名称由以下模式生成: .
在前面的示例中,bean 名称是 和 相同的名称,但 () bean 带有附加的 () 后缀。
可以使用注释和这些消息传递注释来自定义此类名称。
实例 ( instances) 也有资格被消息历史记录跟踪。AbstractEndpoint
MessageHandler
MessageSource
[componentName].[methodName].[decapitalizedAnnotationClassShortName]
thingService.otherThing.serviceActivator
AbstractEndpoint
.handler
.source
MessageHandler
MessageSource
@EndpointId
MessageHandler
MessageSource
从版本 4.0 开始,所有消息传递注释都提供了选项 ( 和 ),以允许对应用程序上下文初始化进行终端节点生命周期控制。
它们分别默认为 和 。
要更改端点的状态(例如 或 ),可以使用(或自动装配)获取对端点 Bean 的引用并调用方法。
或者,您可以向 发送命令消息(请参阅 Control Bus)。
为此,您应该使用上一段前面提到的。SmartLifecycle
autoStartup
phase
true
0
start()
stop()
BeanFactory
Control Bus
beanName
在解析上述注释后自动创建的通道(当没有配置特定的通道 bean 时)和相应的消费者端点,在上下文初始化结束时被声明为 bean。
这些 bean 可以在其他服务中自动装配,但是必须用 Comments 标记它们,因为在正常的自动装配处理期间,定义通常还不可用。
|
从版本 6.0 开始,现在所有的消息传递注释都是,因此可以在同一个服务方法上声明几个相同类型的注释,这意味着创建与这些注释重复的端点一样多的端点:@Repeatable
@Transformer(inputChannel = "inputChannel1", outputChannel = "outputChannel1")
@Transformer(inputChannel = "inputChannel2", outputChannel = "outputChannel2")
public String transform(String input) {
return input.toUpperCase();
}
如果将 XML 配置与注释结合使用,则不需要注释。
如果要从元素的属性配置 POJO 引用,则只能提供方法级 Comments。
在这种情况下,即使元素上不存在方法级属性,注释也可以防止歧义。@MessageEndpoint ref <service-activator/> <service-activator/> |
注释的值也可以是 SpEL 表达式(例如, ),当您希望在注入 Headers 值之前对其进行操作时,这非常有用。
它还提供了一个可选属性,用于指定属性值是否必须在标头中可用。
该属性的默认值为 .someHeader.toUpperCase() required required true |
端点上的输出通道和回复通道消息头的组合支持管道方法,其中多个组件有一个输出通道,最终组件允许将回复消息转发到回复通道(如原始请求消息中指定)。 换句话说,最终组件取决于原始发送方提供的信息,并且可以动态支持任意数量的客户端。 这是返回地址模式的一个示例。 |
在解析上述注释后自动创建的通道(当没有配置特定的通道 bean 时)和相应的消费者端点,在上下文初始化结束时被声明为 bean。
这些 bean 可以在其他服务中自动装配,但是必须用 Comments 标记它们,因为在正常的自动装配处理期间,定义通常还不可用。
|
使用注释@Poller
在 Spring Integration 4.0 之前,消息传递注释要求 be 对 .
例如,需要一个元素来配置复合端点并使复合端点成为 .
版本 4.0 引入了注释,以允许直接在消息传递注释上配置属性,如下例所示:inputChannel
SubscribableChannel
PollableChannel
<int:bridge/>
<int:poller/>
PollingConsumer
@Poller
poller
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 ,则使用默认值(如果它存在于应用程序上下文中)。
要使用 annotation 声明默认 Poller,请使用类似于以下示例的代码:@Poller
PollerMetadata
@Poller
maxMessagesPerPoll
fixedDelay
fixedRate
cron
receiveTimeout
PollingConsumer
transaction
advice-chain
error-handler
PollerMetadata
@Poller
value
PollerMetadata
inputChannel
PollableChannel
@Poller
PollerMetadata
@Configuration
@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 开始,该 annotation 具有用于更轻松地配置底层 .
此属性与 XML 组件中的角色相同。
有关更多信息,请参阅 Endpoint Namespace Support 。@Poller
errorChannel
MessagePublishingErrorHandler
error-channel
<poller>
消息注释上的属性与该属性互斥。
有关更多信息,请参阅下一节。poller()
reactive()
使用注释@Reactive
这自 5.0 版以来一直存在,但仅当端点的 input 通道是(或任何实现)时才应用。
从版本 5.3 开始,当目标消息处理程序独立于 input 通道类型时,其实例也由框架创建。
从版本 5.5 开始,已为所有消息传递注释引入了 sub-annotation (类似于上面)。
它接受可选的 Bean 引用,并且独立于 input 通道类型和消息处理程序,将目标端点转换为实例。
该函数从运算符用于对 input 通道的反应式流源应用一些自定义(、、 等)。ReactiveStreamsConsumer
FluxMessageChannel
org.reactivestreams.Publisher
ReactiveMessageHandler
@Reactive
@Poller
Function<? super Flux<Message<?>>, ? extends Publisher<Message<?>>>
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) {
...
}
消息注释上的属性与该属性互斥。
有关更多信息,请参阅使用 @Poller
Annotation 和 Reactive Streams 支持。reactive()
poller()
使用注释@InboundChannelAdapter
版本 4.0 引入了方法级 Comments。
它基于 a 为带注释的方法生成集成组件。
此注释是 XML 组件的类似物,具有相同的限制:该方法不能有参数,并且返回类型不能为 .
它有两个属性:(必需的 bean 名称)和(可选的 Comments,如前所述)。
如果需要提供一些 ,请使用 return 类型并使用 a 构建 .
使用 a 可以配置 .
以下示例演示如何使用批注:@InboundChannelAdapter
SourcePollingChannelAdapter
MethodInvokingMessageSource
<int:inbound-channel-adapter>
void
value
MessageChannel
poller
@Poller
MessageHeaders
Message<?>
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 引入了 annotation 属性的别名,以提供更好的源代码可读性。
此外,目标 bean 在第一次调用时通过提供的名称(由选项设置)进行解析,而不是在初始化阶段。
它允许 “后期绑定” 逻辑:从消费者的角度来看,目标 bean 的创建和注册时间比解析阶段晚一点。channel
value
MessageChannel
SourcePollingChannelAdapter
outputChannelName
receive()
MessageChannel
@InboundChannelAdapter
第一个示例要求已在应用程序上下文中的其他位置声明默认 Poller。
使用注释@MessagingGateway
使用注释@IntegrationComponentScan
标准 Spring Framework 注释不扫描接口的构造型 Comments。
为了克服此限制并允许配置(请参阅@MessagingGateway
Annotation),我们引入了该机制。
此注释必须与注释一起放置,并对其进行自定义以定义其扫描选项。
例如 和 。
在这种情况下,所有发现的带注释的接口都将被解析并注册为实例。
所有其他基于 class 的组件都由标准 .@ComponentScan
@Component
@MessagingGateway
@IntegrationComponentScan
@Configuration
basePackages
basePackageClasses
@MessagingGateway
GatewayProxyFactoryBean
@ComponentScan