2017-04-04 217 views
2

春季工作我是rabbitmq的新手,我想知道我錯在哪裏。春季rabbitmq監聽器的異常處理

我已經寫了一個rabbitmq連接工廠和一個包含偵聽器的偵聽器容器。我也提供了一個錯誤處理程序的偵聽器容器,但它似乎並沒有工作。

我的春豆:

<rabbit:connection-factory id="RabbitMQConnectionFactory" virtual-host="${rabbitmq.vhost}" host="${rabbitmq.host}" port="${rabbitmq.port}" username="${rabbitmq.username}" password="${rabbitmq.password}"/> 
<rabbit:listener-container missing-queues-fatal="false" declaration-retries="0" error-handler="errorHandlinginRabbitMQ" recovery-interval="10000" auto-startup="${rabbitmq.apc.autostartup}" max-concurrency="1" prefetch="1" concurrency="1" connection-factory="RabbitMQConnectionFactory" acknowledge="manual"> 
    <rabbit:listener ref="apcRabbitMQListener" queue-names="${queue.tpg.rabbitmq.destination.apc}" exclusive="true" /> 
</rabbit:listener-container> 
<bean id="errorHandlinginRabbitMQ" class="RabbitMQErrorHandler"/> 

這是我RabbitMQErrorHandler類:

public class RabbitMQErrorHandler implements ErrorHandler 
{ 
    @Override 
    public void handleError(final Throwable exception) 
    { 
     System.out.println("error occurred in message listener and handled in error handler" + exception.toString()); 
    } 
} 

我認爲,如果我對連接工廠提供了無效的憑證,在RabbitMQErrorHandler類的HandleError方法應執行,並且服務器應該正常啓動,但是,當我嘗試運行服務器時,該方法不會執行(異常在控制檯中引發)並且服務器無法啓動。我在哪裏錯過了什麼,可能是什麼?

回答

3

錯誤處理程序用於處理消息傳遞期間的錯誤;因爲你還沒有連接,所以沒有消息來處理錯誤。

要獲得連接例外,您應該實施ApplicationListener<ListenerContainerConsumerFailedEvent>,如果您將它作爲一個bean添加到應用程序上下文中,您將作爲事件接收失敗。

如果您實施ApplicationListener<AmqpEvent>,您將獲得其他事件(消費者開始,消費者停止等)。

編輯

<rabbit:listener-container auto-startup="false"> 
    <rabbit:listener id="fooContainer" ref="foo" method="handleMessage" 
       queue-names="si.test.queue" /> 
</rabbit:listener-container> 

<bean id="foo" class="com.example.Foo" /> 

富:

public class Foo { 

    public final CountDownLatch latch = new CountDownLatch(1); 

    public void handleMessage(String foo) { 
     System.out.println(foo); 
     this.latch.countDown(); 
    } 

} 

應用:

@SpringBootApplication 
@ImportResource("context.xml") 
public class So43208940Application implements CommandLineRunner { 

    public static void main(String[] args) { 
     ConfigurableApplicationContext context = SpringApplication.run(So43208940Application.class, args); 
     context.close(); 
    } 

    @Autowired 
    private SimpleMessageListenerContainer fooContainer; 

    @Autowired 
    private CachingConnectionFactory connectionFactory; 

    @Autowired 
    private RabbitTemplate template; 

    @Autowired 
    private Foo foo; 

    @Override 
    public void run(String... args) throws Exception { 
     this.connectionFactory.setUsername("junk"); 
     try { 
      this.fooContainer.start(); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
     Thread.sleep(5000); 
     this.connectionFactory.setUsername("guest"); 
     this.fooContainer.start(); 
     System.out.println("Container started"); 
     this.template.convertAndSend("si.test.queue", "foo"); 
     foo.latch.await(10, TimeUnit.SECONDS); 
    } 

} 
+0

謝謝,它的工作。我想執行的方法,但是,它仍然沒有讓服務器正常啓動。我想要的是,即使由於監聽器中的某些異常,監聽器沒有被激活,我的服務器上的其他服務仍然繼續工作。請指導 –

+0

認證錯誤被認爲是致命的;你可以設置'auto-startup =「false」'並手動啓動容器,以便捕獲異常。 –

+0

以及我們如何手動啓動容器?這是我過去幾天以來一直在尋找的東西。此外,聽衆容器中沒有**自動啓動**標籤 –