Использование опроса для сервис-активатора в Spring-интеграции, как я могу передать контекст MCD (slf4j) в пул потоков - PullRequest
0 голосов
/ 12 марта 2020
 <service-activator ref="serviceName" input-channel="request-channel" method="methodName">
        <poller task-executor="taskExecutorCustom"/>
    </service-activator>
 <task:executor id="taskExecutorCustom" pool-size="5-20" queue-capacity="0"> 

Кто-нибудь может подсказать, как передать контекст MCD методу службы "serviceName"?

1 Ответ

1 голос
/ 12 марта 2020

Ответ на decorace a Runnable, который будет выполнен на этом TaskExecutor.

В Inte rnet есть много статей по этому вопросу:

Как использовать MD C с пулами потоков?

https://gist.github.com/pismy/117a0017bf8459772771

https://rmannibucau.metawerx.net/post/javaee-concurrency-utilities-mdc-propagation

Кроме того, Spring Security предлагает решение для распространения SecurityContext из одного потока в другой: https://docs.spring.io/spring-security/site/docs/5.3.0.RELEASE/reference/html5/#concurrency

Что бы я предложил вам принять некоторые идеи из этих ссылок и использовать существующий API в ThreadPoolTaskExecutor:

/**
 * Specify a custom {@link TaskDecorator} to be applied to any {@link Runnable}
 * about to be executed.
 * <p>Note that such a decorator is not necessarily being applied to the
 * user-supplied {@code Runnable}/{@code Callable} but rather to the actual
 * execution callback (which may be a wrapper around the user-supplied task).
 * <p>The primary use case is to set some execution context around the task's
 * invocation, or to provide some monitoring/statistics for task execution.
 * @since 4.3
 */
public void setTaskDecorator(TaskDecorator taskDecorator) {

Итак, ваш декоратор должен просто иметь такой код:

taskExecutor.setTaskDecorator(runnable -> {
        Map<String, String> mdc = MDC.getCopyOfContextMap();
        return () -> {
            MDC.setContextMap(mdc);
            runnable.run();
        };
    });
...