Messaging Meta-Annotations
从 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 依赖项隔离到用户标注,避免在用户类中使用它们。如果框架使用具有框架元标注的用户标注找到了一个方法,则该方法的处理与使用框架标注直接对该方法执行标注一样。
Annotations on @Bean
Methods
从 4.0 版本开始,可以针对 @Configuration
类中的 @Bean
方法定义配置消息传递标注,以基于 Bean(而不是方法)生成消息端点。在 @Bean
定义是 “out-of-the-box” 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
标注的 @Bean
的支持,后者返回 java.util.function.Supplier
,可生成 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
方法进行处理(可以在 @Bean
定义中应用 @MyServiceActivator
注释 described earlier)。
当您对使用者 |
bean 名称使用以下算法生成: |
-
MessageHandler
(MessageSource
)@Bean
从@Bean
上的方法名称或name
特性中获取自己的标准名称。这如同@Bean
方法上没有消息传递注解。 -
AbstractEndpoint
bean 名称按照以下模式生成:[@Bean name].[decapitalizedAnnotationClassShortName]
。例如,consoleSource()
定义 shown earlier 的SourcePollingChannelAdapter
端点得到一个 bean 名称consoleSource.inboundChannelAdapter
。与 POJO 方法不同,bean 方法名称不包括在端点 bean 名称中。另请参见 Endpoint Bean Names。 -
如果
@Bean
不能直接在目标端点中使用(不是MessageSource
、AbstractReplyProducingMessageHandler
或AbstractMessageRouter
的实例),则会注册一个相应的AbstractStandardMessageHandlerFactoryBean
委托给这个@Bean
。此包装器的 bean 名称按照以下模式生成:[@Bean name].[decapitalizedAnnotationClassShortName].[handler (or source)]
。
当在 @Bean
定义上使用这些注释时,inputChannel
必须引用声明的 bean。如果通道在应用程序上下文中不存在,则它们将自动声明。
使用 Java 配置,可以在
与现有的 Spring 容器逻辑结合使用时,还会取消注册消息传递端点 Bean(基于 |
Creating a Bridge with Annotations
从 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();
}
也可以将这些标注用作元标注。