升级到Spring Framework 4.2.4后,Spring Integration Java Configuration突然失败

时间:2016-02-17 22:30:37

标签: spring-integration

我将Spring Framework从4.1.4升级到 4.2.4 。我们的Spring Integration版本是4.2.0,但问题也出现在SI 4.2.4上。

升级到SF 4.2.2后,我们收到了这个运行时错误:

org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'org.springframework.context.annotation.AnnotationConfigApplicationContext@41799345.inboundRouting.inputChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers

当我检查日志时,我看到变换器:inboundRoutingConfig.assignPriority.transformer被添加为inboundRouting.inputChannel的订户。这解释了“Dispatcher没有订阅者”。但是,如果我恢复到SF 4.1.4 ,我 DO 会看到变频器作为频道的订户添加,并且运行良好。

Spring Framework升级导致此问题的任何想法?

以下是特定配置,失败的部分是assignPriority @Transformer注释方法。

请注意@EnableConfiguration位于项目中另一个@Configuration带注释的类中,但我也尝试将其添加到此类中。

@Configuration
public class InboundRoutingConfig {
private static final Logger logger = LoggerFactory.getLogger(InboundRoutingConfig.class);

private final static String RESOURCE_AWARE_OUTBOUND_CHANNEL = "inboundRouting.resourceAwareOutputChannel";
private final static String STANDARD_OUTBOUND_CHANNEL = "inboundRouting.standardOutputChannel";
private final static String INBOUND_ROUTING_INPUT_CHANNEL = "inboundRouting.inputChannel";
private final static String ROUTING_CHANNEL = "inboundRouting.outboundRoutingChannel";
private SpringIntegrationHelper SpringIntegrationConfigHelper;
private InboundRoutingMessagePrioritizer inboundRoutingMessagePrioritizer;
private AmqpTemplate resourceAwarePriorityTemplate;
private RouterMapper routerMapper;
private AmqpTemplate standardPriorityTemplate;


@Transformer(inputChannel = INBOUND_ROUTING_INPUT_CHANNEL, outputChannel = ROUTING_CHANNEL, autoStartup="true")
public PriorityMessage assignPriority( PriorityMessage msg, MessageHeaders messageHeaders) {
    logger.debug("RECV: InboundRouting content id [{}], request id [{}]", msg.getContentId(), msg.getRequestId());
    return inboundRoutingMessagePrioritizer.setPriorityAndResourceAware(msg, messageHeaders);
}

@Router(inputChannel = ROUTING_CHANNEL, autoStartup="true",
        channelMappings={"true=" + RESOURCE_AWARE_OUTBOUND_CHANNEL, "false=" + STANDARD_OUTBOUND_CHANNEL})
public String resourceAwareRouter(PriorityMessage pm) {
    return Boolean.toString(routerMapper.inboundRoutingIsResourceAware(pm)).toLowerCase();
}

@ServiceActivator(inputChannel=RESOURCE_AWARE_OUTBOUND_CHANNEL)
public void inboundRoutingToResourceAwareOutputEndpoint(PriorityMessage pm, MessageHeaders messageHeaders) {
    resourceAwarePriorityTemplate.convertAndSend(pm, new CoreAnalysisMessagingService.CopyHeadersPostProcessor(messageHeaders));
}

@ServiceActivator(inputChannel=STANDARD_OUTBOUND_CHANNEL)
public void inboundRoutingToStandardOutputEndpoint(PriorityMessage pm,  MessageHeaders messageHeaders) {
    standardPriorityTemplate.convertAndSend(pm,  new CoreAnalysisMessagingService.CopyHeadersPostProcessor(messageHeaders));
}



/************************************************************************
 *                                                                      *
 *                        Infrastructure                                *
 *                                                                      *
 ************************************************************************/

@Bean(name = "exec.inboundRouting")
TaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor e = new ThreadPoolTaskExecutor();
    e.setCorePoolSize(1);
    e.setQueueCapacity(1);
    return e;
}

@Bean(name = "inboundRouting.inboundChannelAdapter")
public AmqpInboundChannelAdapter inboundRoutingInboundChannelAdapter(
        @Qualifier("exec.inboundRouting") TaskExecutor taskExecutor,
        @Qualifier(INBOUND_ROUTING_INPUT_CHANNEL) MessageChannel inputChannel,
        @Qualifier("inboundRoutingQueue") Queue inboundQueue) {

    org.aopalliance.aop.Advice[] adviceChain = new org.aopalliance.aop.Advice[] { };
    int concurrentConsumers = 1;
    AmqpInboundChannelAdapter a = springIntegrationConfigHelper.createInboundChannelAdapter(taskExecutor,
            inputChannel, new Queue[] { inboundQueue }, concurrentConsumers, adviceChain);
    return a;
}

@Bean(name = INBOUND_ROUTING_INPUT_CHANNEL)
public MessageChannel resourceAwareInputChannel() {
    DirectChannel c = new DirectChannel();
    c.setComponentName(INBOUND_ROUTING_INPUT_CHANNEL);
    c.setBeanName(INBOUND_ROUTING_INPUT_CHANNEL);
    return c;
}

@Bean(name = "inboundRouting.outboundRoutingChannel")
public MessageChannel resourceAwareOutboundRoutingChannel() {
    DirectChannel c = new DirectChannel();
    c.setComponentName(ROUTING_CHANNEL);
    c.setBeanName(ROUTING_CHANNEL);
    return c;
}

@Bean(name = RESOURCE_AWARE_OUTBOUND_CHANNEL)
public MessageChannel inboundRoutingToResourceAwareOutboundChannel() {
    DirectChannel c = new DirectChannel();
    c.setComponentName(RESOURCE_AWARE_OUTBOUND_CHANNEL);
    c.setBeanName(RESOURCE_AWARE_OUTBOUND_CHANNEL);
    return c;
}

@Bean(name = STANDARD_OUTBOUND_CHANNEL)
public MessageChannel inboundRoutingToStandardOutboundChannel() {
    DirectChannel c = new DirectChannel();
    c.setComponentName(STANDARD_OUTBOUND_CHANNEL);
    c.setBeanName(STANDARD_OUTBOUND_CHANNEL);
    return c;
}

/************************************************************************
 *                                                                      *
 *               Inbound routing config setters                         *
 *                                                                      *
 ************************************************************************/

@Autowired
public void setInboundRoutingMessagePrioritizer (InboundRoutingMessagePrioritizer inboundRoutingMessagePrioritizer) {
    this.inboundRoutingMessagePrioritizer = inboundRoutingMessagePrioritizer;
}

@Autowired
public void setSpringIntegrationConfigHelper (SpringIntegrationHelper springIntegrationConfigHelper) {
    this.springIntegrationConfigHelper = springIntegrationConfigHelper;   
}

@Autowired
@Qualifier("resourceAwarePriorityTemplate")
public void setResourceAwarePriorityTemplate(AmqpTemplate resourceAwarePriorityTemplate) {
    this.resourceAwarePriorityTemplate = resourceAwarePriorityTemplate;
}

@Autowired
public void setRouterMapper(RouterMapper routerMapper) {
    this.routerMapper = routerMapper;
}

@Autowired
@Qualifier("standardPriorityTemplate")
public void setStandardPriorityTemplate(AmqpTemplate standardPriorityTemplate) {
    this.standardPriorityTemplate = standardPriorityTemplate;
}
}

以下是错误的堆栈跟踪

org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:865)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:760)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:680)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:93)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:183)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1345)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:661)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1096)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1080)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$800(SimpleMessageListenerContainer.java:93)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'org.springframework.context.annotation.AnnotationConfigApplicationContext@41799345.inboundRouting.inputChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:81)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:105)
    at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$400(AmqpInboundChannelAdapter.java:45)
    at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$1.onMessage(AmqpInboundChannelAdapter.java:93)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:757)
    ... 12 more
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:153)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    ... 21 more

这是一个复制问题的压缩配置:

@EnableIntegration
@Configuration
public class CompressedConfig {
private final static String INPUT_CHANNEL = "testSpring.inputChannel";
private final static String SERVICE_ACTIVATOR_CHANNEL = "testSpring.service";

private String exchangeName = "amq.direct";
private String queueName = "testSpring";

private ConnectionFactory connectionFactory;
private MessageConverter messageConverter;

@Bean
public Queue testSprintQueue(RabbitAdmin rabbitAdmin) {
    boolean durable = true;
    boolean exclusive = false;
    boolean autoDelete = false;

    Exchange exchange = new DirectExchange(exchangeName, durable, autoDelete);
    rabbitAdmin.declareExchange(exchange);

    Map<String,Object> arguments = new HashMap<String, Object>();
    Queue queue = new Queue(queueName,
            durable,
            exclusive,
            autoDelete,
            arguments);

    rabbitAdmin.declareQueue(queue);

    Binding binding = new Binding(queueName,
            DestinationType.QUEUE,
            exchangeName,
            queueName,
            null);
    rabbitAdmin.declareBinding(binding);

    return queue;
}

@Bean
public AmqpTemplate testSpringTemplate() {
    RabbitTemplate template = new RabbitTemplate(connectionFactory);
    template.setChannelTransacted(false);
    template.setExchange(exchangeName);
    template.setQueue(queueName);
    template.setRoutingKey(queueName);
    template.setMessageConverter(messageConverter);
    return template;
}

@Transformer(inputChannel = INPUT_CHANNEL, outputChannel = SERVICE_ACTIVATOR_CHANNEL)
public String transform( TestMessage msg, MessageHeaders messageHeaders) {
    return msg.getContents();
}

@ServiceActivator(inputChannel=SERVICE_ACTIVATOR_CHANNEL)
public void serviceActivator(String msg, MessageHeaders messageHeaders) {
    System.out.println("serviceActivator: " + msg);
}

@Bean(name = "exec.testSpring")
TaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor e = new ThreadPoolTaskExecutor();
    e.setCorePoolSize(1);
    e.setQueueCapacity(1);
    return e;
}

@Bean(name = "testSpring.inboundChannelAdapter")
public AmqpInboundChannelAdapter inboundRoutingInboundChannelAdapter(
        @Qualifier("exec.testSpring") TaskExecutor taskExecutor,
        @Qualifier(INPUT_CHANNEL) MessageChannel inputChannel,
        @Qualifier("testSprintQueue") Queue queue) {

     int concurrentConsumers = 1;

    SimpleMessageListenerContainer listenerContainer =
            new SimpleMessageListenerContainer(connectionFactory);
    //AUTO is default, but setting it anyhow.
    listenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
    listenerContainer.setAutoStartup(true);
    listenerContainer.setConcurrentConsumers(concurrentConsumers);
    listenerContainer.setMessageConverter(messageConverter);
    listenerContainer.setQueues(queue);
    listenerContainer.setPrefetchCount(1);
    listenerContainer.setTaskExecutor(taskExecutor);
    listenerContainer.setDefaultRequeueRejected(false);

    AmqpInboundChannelAdapter a = new AmqpInboundChannelAdapter(listenerContainer);
    a.setMessageConverter(messageConverter);
    a.setAutoStartup(true);
    a.setOutputChannel(inputChannel);
    return a;


}

@Bean(name = INPUT_CHANNEL)
public MessageChannel inputChannel() {
    DirectChannel c = new DirectChannel();
    c.setComponentName(INPUT_CHANNEL);
    c.setBeanName(INPUT_CHANNEL);
    return c;
}

@Bean(name = SERVICE_ACTIVATOR_CHANNEL)
public MessageChannel serviceChannel() {
    DirectChannel c = new DirectChannel();
    c.setComponentName(SERVICE_ACTIVATOR_CHANNEL);
    c.setBeanName(SERVICE_ACTIVATOR_CHANNEL);
    return c;
}

@Autowired
public void setConnectionFactory (ConnectionFactory connectionFactory) {
    this.connectionFactory = connectionFactory;
}

@Autowired
public void setMessageConverter(@Qualifier("jsonMessageConverter") MessageConverter messageConverter) {
    this.messageConverter = messageConverter;
}

}

public class TestMessage {

    private String contents;

    public String getContents() {
        return contents;
    }

    public void setContents(String contents) {
        this.contents = contents;
    }
}

这是助手的createInboundChannelAdapter()代码中发生的事情:

public AmqpInboundChannelAdapter createInboundChannelAdapter(TaskExecutor taskExecutor
        , MessageChannel outputChannel, Queue[] queues, int concurrentConsumers
        , org.aopalliance.aop.Advice[] adviceChain) {

    SimpleMessageListenerContainer listenerContainer =
            new SimpleMessageListenerContainer(connectionFactory);
    listenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
    listenerContainer.setAutoStartup(true);
    listenerContainer.setConcurrentConsumers(concurrentConsumers);
    listenerContainer.setMessageConverter(messageConverter);
    listenerContainer.setQueues(queues);
    listenerContainer.setErrorHandler(new MyCustomListenerErrorHandler());
    listenerContainer.setPrefetchCount(1);
    listenerContainer.setTaskExecutor(taskExecutor);
    listenerContainer.setDefaultRequeueRejected(true);
    if (adviceChain != null && adviceChain.length > 0) {
        listenerContainer.setAdviceChain(adviceChain);
    }

    AmqpInboundChannelAdapter a = new AmqpInboundChannelAdapter(listenerContainer);
    a.setMessageConverter(messageConverter);
    a.setAutoStartup(true);
    a.setHeaderMapper(new MyCustomHeaderMapper());
    a.setOutputChannel(outputChannel);
    return a;
}

这是DEBUG级别之前的输出,包括使用压缩配置运行测试时产生的异常:

2016-02-18 16:04:50,337 - DEBUG - org.springframework.amqp.rabbit.listener.BlockingQueueConsumer [exec.testSpring-1] - Retrieving delivery for Consumer: tags=[{amq.ctag-lqiTx-rBl_HWPwn8a5G2XQ=testSpring}], channel=Cached Rabbit Channel: AMQChannel(amqp://company@192.168.1.46:5672/,22), acknowledgeMode=AUTO local queue size=0
2016-02-18 16:04:51,038 - DEBUG - org.springframework.amqp.rabbit.listener.BlockingQueueConsumer [pool-1-thread-8] - Storing delivery for Consumer: tags=[{amq.ctag-lqiTx-rBl_HWPwn8a5G2XQ=testSpring}], channel=Cached Rabbit Channel: AMQChannel(amqp://company@192.168.1.46:5672/,22), acknowledgeMode=AUTO local queue size=0
2016-02-18 16:04:51,041 - DEBUG - org.springframework.amqp.rabbit.listener.BlockingQueueConsumer [exec.testSpring-1] - Received message: (Body:'{"contents":"Here is my message"}'MessageProperties [headers={__TypeId__=test.TestMessage}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=application/json, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=amq.direct, receivedRoutingKey=testSpring, deliveryTag=1, messageCount=0])
2016-02-18 16:04:51,127 - DEBUG - org.springframework.integration.mapping.AbstractHeaderMapper$HeaderMatcher [exec.testSpring-1] - headerName=[json__TypeId__] WILL be mapped, found in [amqp_appId, amqp_clusterId, amqp_contentEncoding, amqp_contentLength, contentType, amqp_correlationId, amqp_deliveryMode, amqp_deliveryTag, amqp_expiration, amqp_messageCount, amqp_messageId, amqp_receivedExchange, amqp_receivedRoutingKey, amqp_redelivered, amqp_replyTo, amqp_timestamp, amqp_type, amqp_userId, json__TypeId__, json__ContentTypeId__, json__KeyTypeId__, amqp_springReplyCorrelation, amqp_springReplyToStack]
2016-02-18 16:04:51,127 - DEBUG - org.springframework.integration.mapping.AbstractHeaderMapper$HeaderMatcher [exec.testSpring-1] - headerName=[amqp_receivedRoutingKey] WILL be mapped, found in [amqp_appId, amqp_clusterId, amqp_contentEncoding, amqp_contentLength, contentType, amqp_correlationId, amqp_deliveryMode, amqp_deliveryTag, amqp_expiration, amqp_messageCount, amqp_messageId, amqp_receivedExchange, amqp_receivedRoutingKey, amqp_redelivered, amqp_replyTo, amqp_timestamp, amqp_type, amqp_userId, json__TypeId__, json__ContentTypeId__, json__KeyTypeId__, amqp_springReplyCorrelation, amqp_springReplyToStack]
2016-02-18 16:04:51,127 - DEBUG - org.springframework.integration.mapping.AbstractHeaderMapper$HeaderMatcher [exec.testSpring-1] - headerName=[amqp_deliveryMode] WILL be mapped, found in [amqp_appId, amqp_clusterId, amqp_contentEncoding, amqp_contentLength, contentType, amqp_correlationId, amqp_deliveryMode, amqp_deliveryTag, amqp_expiration, amqp_messageCount, amqp_messageId, amqp_receivedExchange, amqp_receivedRoutingKey, amqp_redelivered, amqp_replyTo, amqp_timestamp, amqp_type, amqp_userId, json__TypeId__, json__ContentTypeId__, json__KeyTypeId__, amqp_springReplyCorrelation, amqp_springReplyToStack]
2016-02-18 16:04:51,128 - DEBUG - org.springframework.integration.mapping.AbstractHeaderMapper$HeaderMatcher [exec.testSpring-1] - headerName=[amqp_receivedExchange] WILL be mapped, found in [amqp_appId, amqp_clusterId, amqp_contentEncoding, amqp_contentLength, contentType, amqp_correlationId, amqp_deliveryMode, amqp_deliveryTag, amqp_expiration, amqp_messageCount, amqp_messageId, amqp_receivedExchange, amqp_receivedRoutingKey, amqp_redelivered, amqp_replyTo, amqp_timestamp, amqp_type, amqp_userId, json__TypeId__, json__ContentTypeId__, json__KeyTypeId__, amqp_springReplyCorrelation, amqp_springReplyToStack]
2016-02-18 16:04:51,128 - DEBUG - org.springframework.integration.mapping.AbstractHeaderMapper$HeaderMatcher [exec.testSpring-1] - headerName=[amqp_contentEncoding] WILL be mapped, found in [amqp_appId, amqp_clusterId, amqp_contentEncoding, amqp_contentLength, contentType, amqp_correlationId, amqp_deliveryMode, amqp_deliveryTag, amqp_expiration, amqp_messageCount, amqp_messageId, amqp_receivedExchange, amqp_receivedRoutingKey, amqp_redelivered, amqp_replyTo, amqp_timestamp, amqp_type, amqp_userId, json__TypeId__, json__ContentTypeId__, json__KeyTypeId__, amqp_springReplyCorrelation, amqp_springReplyToStack]
2016-02-18 16:04:51,128 - DEBUG - org.springframework.integration.mapping.AbstractHeaderMapper$HeaderMatcher [exec.testSpring-1] - headerName=[contentType] WILL be mapped, found in [amqp_appId, amqp_clusterId, amqp_contentEncoding, amqp_contentLength, contentType, amqp_correlationId, amqp_deliveryMode, amqp_deliveryTag, amqp_expiration, amqp_messageCount, amqp_messageId, amqp_receivedExchange, amqp_receivedRoutingKey, amqp_redelivered, amqp_replyTo, amqp_timestamp, amqp_type, amqp_userId, json__TypeId__, json__ContentTypeId__, json__KeyTypeId__, amqp_springReplyCorrelation, amqp_springReplyToStack]
2016-02-18 16:04:51,128 - DEBUG - org.springframework.integration.mapping.AbstractHeaderMapper$HeaderMatcher [exec.testSpring-1] - headerName=[amqp_redelivered] WILL be mapped, found in [amqp_appId, amqp_clusterId, amqp_contentEncoding, amqp_contentLength, contentType, amqp_correlationId, amqp_deliveryMode, amqp_deliveryTag, amqp_expiration, amqp_messageCount, amqp_messageId, amqp_receivedExchange, amqp_receivedRoutingKey, amqp_redelivered, amqp_replyTo, amqp_timestamp, amqp_type, amqp_userId, json__TypeId__, json__ContentTypeId__, json__KeyTypeId__, amqp_springReplyCorrelation, amqp_springReplyToStack]
2016-02-18 16:04:51,128 - DEBUG - org.springframework.integration.mapping.AbstractHeaderMapper$HeaderMatcher [exec.testSpring-1] - headerName=[amqp_deliveryTag] WILL be mapped, found in [amqp_appId, amqp_clusterId, amqp_contentEncoding, amqp_contentLength, contentType, amqp_correlationId, amqp_deliveryMode, amqp_deliveryTag, amqp_expiration, amqp_messageCount, amqp_messageId, amqp_receivedExchange, amqp_receivedRoutingKey, amqp_redelivered, amqp_replyTo, amqp_timestamp, amqp_type, amqp_userId, json__TypeId__, json__ContentTypeId__, json__KeyTypeId__, amqp_springReplyCorrelation, amqp_springReplyToStack]
2016-02-18 16:04:51,146 - DEBUG - org.springframework.integration.channel.DirectChannel [exec.testSpring-1] - preSend on channel 'testSpring.inputChannel', message: GenericMessage [payload=test.TestMessage@43784f9a, headers={timestamp=1455840291145, id=217e6fc4-4b99-d5e4-0c0d-3c35771b9e90, json__TypeId__=test.TestMessage, amqp_receivedRoutingKey=testSpring, amqp_deliveryMode=PERSISTENT, amqp_consumerQueue=testSpring, amqp_consumerTag=amq.ctag-lqiTx-rBl_HWPwn8a5G2XQ, amqp_receivedExchange=amq.direct, amqp_contentEncoding=UTF-8, contentType=application/json, amqp_redelivered=false, amqp_deliveryTag=1}]
2016-02-18 16:04:51,147 - WARN - org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler [exec.testSpring-1] - Execution of Rabbit message listener failed.
org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:865)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:760)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:680)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:93)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:183)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1345)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:661)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1096)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1080)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$800(SimpleMessageListenerContainer.java:93)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'org.springframework.context.annotation.AnnotationConfigApplicationContext@7a5291d9.testSpring.inputChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:81)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)

1 个答案:

答案 0 :(得分:0)

抱歉,您的配置从我这边开始玩起来并不简单。我发现问题来自AMQP入站通道适配器,看起来你在应用程序之前在队列中有消息。在开始申请之前,我在foo队列中有类似的配置和消息。

@Configuration
@EnableIntegration
public static class MyConfig {

    @Transformer(inputChannel = "input", outputChannel = "nullChannel")
    public String transform(String payload) throws Exception {
        System.out.println(payload);
        return payload;
    }

    @Bean
    public MessageChannel input() {
        return new DirectChannel();
    }

    @Bean
    public CachingConnectionFactory connectionFactory() {
        return new CachingConnectionFactory("localhost", AMQP.PROTOCOL.PORT);
    }

    @Bean
    public SimpleMessageListenerContainer container() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
        container.setQueueNames("foo");
        return container;
    }

    @Bean
    public AmqpInboundChannelAdapter amqpInboundChannelAdapter() {
        AmqpInboundChannelAdapter channelAdapter = new AmqpInboundChannelAdapter(container());
        channelAdapter.setOutputChannel(input());
        return channelAdapter;
    }

}

一切都运作良好。 AMQP入站通道适配器已在@Transformer端点之后启动,因此最后一个能够选择第一个队列侦听后产生的消息。

您是否介意在该异常导致之前共享org.springframework类别的DEBUG?