PublishSubscribeChannel使用TaskExecutor - 线程行为

时间:2017-04-26 02:12:16

标签: spring spring-integration

我有一个简单的弹簧dsl流程如下:

@Configuration
public class OrderFlow {

private static final Logger logger = LoggerFactory.getLogger(OrderFlow.class);

@Autowired
private OrderSubFlow orderSubFlow;

@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;

@Bean
public IntegrationFlow orders() {

    return IntegrationFlows.from(MessageChannels.direct("order_input").get()).handle(new GenericHandler<Order>() {
        @Override
        public Object handle(Order order, Map<String, Object> headers) {
            logger.info("Pre-Processing order with id: {}", order.getId());
            return MessageBuilder.withPayload(order).copyHeaders(headers).build();
        }
    }).publishSubscribeChannel(threadPoolTaskExecutor, new Consumer<PublishSubscribeSpec>() {
        @Override
        public void accept(PublishSubscribeSpec t) {
            t.subscribe(orderSubFlow);
        }
    }).handle(new GenericHandler<Order>() {
        @Override
        public Object handle(Order order, Map<String, Object> headers) {
            logger.info("Post-Processing order with id: {}", order.getId());
            return MessageBuilder.withPayload(order).copyHeaders(headers).build();
        }
    }).get();

}

@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    threadPoolTaskExecutor.setMaxPoolSize(2);
    threadPoolTaskExecutor.setCorePoolSize(2);
    threadPoolTaskExecutor.setQueueCapacity(10);
    return threadPoolTaskExecutor;
}

}

OrderSubFlow是

@Configuration
public class OrderSubFlow implements IntegrationFlow {

private static final Logger logger = LoggerFactory.getLogger(OrderSubFlow.class);

@Override
public void configure(IntegrationFlowDefinition<?> flow) {
    flow.handle(new GenericHandler<Order>() {
        @Override
        public Object handle(Order order, Map<String, Object> headers) {
            logger.info("Processing order with id: {}", order.getId());
            return null;
        }
    });

}

}

当我将消息放入“order_input”通道时,它正在执行主线程中的第一个OrderFlow处理程序和TaskExecutor线程中的OrderSubFlow处理程序,这是预期的。但OrderFlow第二个处理程序也在TaskExecutor线程中执行。这是预期的行为吗?不应该在主线程本身执行OrderFlow第二个处理程序吗?

请参阅下面的日志。

INFO 9648 --- [           main] com.example.flows.OrderFlow              : Pre-Processing order with id: 10
INFO 9648 --- [lTaskExecutor-1] com.example.flows.OrderSubFlow           : Processing order with id: 10
INFO 9648 --- [lTaskExecutor-2] com.example.flows.OrderFlow              : Post-Processing order with id: 10

这是我正在使用的网关

@MessagingGateway
public interface OrderService {

@Gateway(requestChannel="order_input")
Order processOrder(Order order);

}

1 个答案:

答案 0 :(得分:1)

请阅读https://jira.spring.io/browse/INT-4264中的讨论。这确实是预期的行为。仅仅因为该处理程序是该publishSubscribeChannel的另一个订阅者。

当其中一个收件人是带有Executor的pub-sub,另一个是DirectChannel继续在主线程中时,使用.routeToRecipients()可以实现所需。