【问题标题】:Converting wire-tap from XML syntax to Spring Integration Java annotation or DSL将 XML 语法的窃听转换为 Spring Integration Java 注释或 DSL
【发布时间】:2018-08-20 22:14:05
【问题描述】:

我发现了很多不同的方法将我的窃听记录器转换为 Java 配置,但它们似乎都不起作用。

这是我的 XML 版本:

<int:channel id="tasksRequestChannel">
    <int:queue capacity="${channel.queue.capacity}"/>
    <int:interceptors>
        <int:wire-tap channel="logRequestingTasks" />
    </int:interceptors>
</int:channel>

<int:logging-channel-adapter id="logRequestingTasks" level="INFO"
    expression="'Requesting tasks : ' + headers.#{T(com.application.infrastructure.CommonConstants).KEY_TASK_NAME} + ' of ID : ' + headers.#{T(com.application.infrastructure.CommonConstants).KEY_TASK_ID} " />

通道确实是可池化的,但我不明白为什么不需要为 XML 语法定义池化器?

这是我将其转换为 Java 的尝试(我的 SpEL 也不起作用):

@Bean
public IntegrationFlow logRequestingTasks(@Qualifier("defaultPoller") PollerMetadata defaultPoller) {
    LoggingHandler loggingHandler = new LoggingHandler(LoggingHandler.Level.INFO.name());
    loggingHandler.setLogExpressionString("'Requesting tasks : ' + headers.#{T(com.application.infrastructure.CommonConstants).KEY_TASK_NAME} + ' of ID : ' + headers.#{T(com.application.infrastructure.CommonConstants).KEY_TASK_ID} ");
    loggingHandler.setLoggerName("logRequestingTasks");

    return IntegrationFlows.from("tasksRequestChannel")
             .handle(loggingHandler, e -> e.poller(defaultPoller))
             .get();
}

===========

更新:

@Gary,我已经尝试了您的解决方案,但我得到了一些奇怪的效果。这是我在控制台中得到的:

2018-08-21 13:22:50.347  INFO 7060 --- [ask-scheduler-3] T.RestTemplate                           : step=INIT;...
2018-08-21 13:22:50.564  INFO 7060 --- [ask-scheduler-3] T.RestTemplate                           : step=SUCCESS;...
2018-08-21 13:22:50.824  INFO 7060 --- [ask-scheduler-3] c.a.t.d.a.TasksSplitter            : No active task retrieved.
2018-08-21 13:23:20.343  INFO 7060 --- [ask-scheduler-9] logStartDmwProcess                       : Start of Application process.
2018-08-21 13:23:20.346  INFO 7060 --- [ask-scheduler-9] T.RestTemplate                           : step=INIT;...
2018-08-21 13:23:20.540  INFO 7060 --- [ask-scheduler-9] T.RestTemplate                           : step=SUCCESS;...
2018-08-21 13:23:20.555  INFO 7060 --- [ask-scheduler-9] c.a.t.d.a.TasksSplitter            : No active task retrieved.

在我的 InboundChannelAdapter 上似乎每隔 x2 的 fixedRate 记录一次。

这是我的记录器和 InboundChannelAdapter:

@Bean
public IntegrationFlow logStartProcess() {       
    Expression logExpression = new SpelExpressionParser().parseExpression("'Start of Application process.'");
    return IntegrationFlows.from("initTimestampChannel")
                .log(Level.INFO, "logStartProcess", logExpression)
                .get();
}

@RefreshScope
@Bean
@InboundChannelAdapter(value = "initTimestampChannel", poller = @Poller(fixedRate = "30000"))
public MessageSource<?> buildTasksRequest() {
    MethodInvokingMessageSource source = new MethodInvokingMessageSource();
    source.setObject(tasksService);
    source.setMethodName("requestAllTasks");
    return source;
}

【问题讨论】:

    标签: spring spring-boot spring-integration spring-el spring-integration-dsl


    【解决方案1】:

    您可以使用.wiretap() 方法,或简单地使用.log() 方法(在内部创建窃听)。

    @SpringBootApplication
    public class So51939181Application {
    
        private static final Expression logExpression = new SpelExpressionParser().parseExpression(
                "'Requesting tasks : ' + headers." + CommonConstants.KEY_TASK_NAME
                + " + ' of ID : ' + headers." + CommonConstants.KEY_TASK_ID);
    
        @Bean
        public MessageChannel foo() {
            return new DirectChannel();
        }
    
        @Bean
        public IntegrationFlow flow() {
            return IntegrationFlows.from("foo")
                    .log(logExpression)
                    // .more stuff
                    .handle(System.out::println)
                    .get();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(So51939181Application.class, args);
        }
    
        @Bean
        public ApplicationRunner runner(MessageChannel foo) {
            return args -> foo.send(MessageBuilder.withPayload("foo")
                    .setHeader(CommonConstants.KEY_TASK_NAME, "name")
                    .setHeader(CommonConstants.KEY_TASK_ID, "id")
                    .build());
        }
    
    }
    

    结果:

    2018-08-20 20:19:44.777  INFO 4096 --- [           main] o.s.integration.handler.LoggingHandler   : Requesting tasks : aName of ID : anId
    GenericMessage [payload=foo, headers={taskName=name, id=b21dde6e-bfa3-f727-52f0-056cb2775ee7, taskId=id, timestamp=1534810784776}]
    

    您不能在此处对 SpEL 使用 #{...} 构造。

    【讨论】:

    • 谢谢加里。我已经用我得到的奇怪结果更新了我的帖子。我还有 2 个问题:如何避免使用 .handle(System.out::println) 它会污染控制台,但是当我在可轮询频道上删除它时,我会得到 No Subscriber error ... 并且必须使用 @ 为我的可轮询频道记录器定义轮询器987654328@?
    • 你必须从频道中消费一些东西; System.out 只是一个示例处理程序 - 您需要在 XML 版本中显示来自 tasksRequestChannel 的内容,然后我可以更新我的示例以匹配。此外,您不能将 Spring Integration 组件放在 @RefreshScope 中 - 这仅适用于被动组件,不适用于集成流程中的主动组件。
    猜你喜欢
    • 1970-01-01
    • 2017-10-30
    • 2020-12-19
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多