消息元注解
从 4.0 版本开始,所有消息处理注解都可以配置为元注解,并且所有用户定义的消息处理注解都可以定义相同的属性来覆盖其默认值。此外,元注解可以按层次结构配置,如下例所示
@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 依赖项隔离到用户注解中,避免在用户类中使用它们。如果框架发现一个带有用户注解的方法,并且该用户注解带有框架元注解,则该方法将被视为直接使用框架注解进行了注解。
@Bean
方法上的注解
从 4.0 版本开始,您可以在 @Configuration
类中的 @Bean
方法定义上配置消息处理注解,以便基于 bean(而不是方法)生成消息端点。当 @Bean
定义是“开箱即用”的 MessageHandler
实例(AggregatingMessageHandler
、DefaultMessageSplitter
等)、Transformer
实例(JsonToObjectTransformer
、ClaimCheckOutTransformer
等)和 MessageSource
实例(FileReadingMessageSource
、RedisStoreMessageSource
等)时,这非常有用。以下示例展示了如何将消息处理注解与 @Bean
注解一起使用
@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
注解并返回 java.util.function.Supplier
的 @Bean
的支持,后者可以生成 POJO 或 Message
。以下示例展示了如何使用这种组合
@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
定义)。
当您在消费者的 @Bean 定义上使用这些注解时,如果 bean 定义返回一个适当的 MessageHandler (取决于注解类型),您必须在 MessageHandler 的 @Bean 定义本身上设置属性(例如 outputChannel 、requiresReply 、order 等)。只有以下注解属性会被使用:adviceChain 、autoStartup 、inputChannel 、phase 和 poller 。所有其他属性都用于 handler。 |
Bean 名称按照以下算法生成 |
-
MessageHandler
(MessageSource
) 的@Bean
根据方法名称或@Bean
上的name
属性获取其标准名称。这就像@Bean
方法上没有消息处理注解一样工作。 -
AbstractEndpoint
bean 名称按照以下模式生成:[@Bean name].[decapitalizedAnnotationClassShortName]
。例如,前面所示的consoleSource()
定义的SourcePollingChannelAdapter
端点获得的 bean 名称是consoleSource.inboundChannelAdapter
。与 POJO 方法不同,端点 bean 名称中不包含 bean 方法名称。另请参见端点 Bean 名称。 -
如果
@Bean
不能直接在目标端点中使用(不是MessageSource
、AbstractReplyProducingMessageHandler
或AbstractMessageRouter
的实例),则会注册一个相应的AbstractStandardMessageHandlerFactoryBean
来委托给该@Bean
。此包装器的 bean 名称按照以下模式生成:[@Bean name].[decapitalizedAnnotationClassShortName].[handler (or source)]
。
在 @Bean 定义上使用这些注解时,inputChannel 必须引用一个已声明的 bean。如果通道尚不存在于应用程序上下文中,则会自动声明。 |
使用 Java 配置,您可以在
与现有的 Spring 容器逻辑一起,消息处理端点 bean(基于 |
使用注解创建桥接
从 4.0 版本开始,Java 配置提供了 @BridgeFrom
和 @BridgeTo
@Bean
方法注解来标记 @Configuration
类中的 MessageChannel
bean。这些注解是为了完整性而存在的,提供了一种便捷的机制来声明 BridgeHandler
及其消息端点配置
@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();
}
您也可以将这些注解用作元注解。
给注解端点提供 Advice
参阅 使用注解给端点提供 Advice。