2015-01-05 70 views
1

目前我們有一個要求來處理彈簧集成流程中的異常。常見的彈簧集成異常處理程序

當前的解決方案是通過Aspects來處理從任何POJO(變換器,聚合器,服務等)拋出的異常。而在這方面,推特會發送出現異常。然而,這些方面並不包括例如Spring Integration Flow引發的異常。也就是說,如果<object-to-json-transformer>發生異常,或者<int-http:outbound-gateway>返回500狀態。

我們需要一種方法來處理這個問題。目前我們看到,我們可以讓流程(網關)的啓動附加錯誤通道,並在此錯誤通道中發送推文。然而,問題在於我們在由錯誤通道調用的服務中也有業務邏輯。所以我們需要混合推文(通知)和商業問題。這也意味着每個錯誤頻道服務都需要手動編程發送推文。因此,如果新開發人員創建新的錯誤渠道服務,他/她可能會忘記放入推特代碼。

有沒有什麼辦法可以把一個通用的全局錯誤句柄除了流程特定的錯誤服務之外也被調用?然後在通用的全局錯誤處理程序代碼中運行所有的通知推特邏輯和其他橫切問題。那麼當時最好的策略是什麼?

更新1

我想出了下面的代碼,但它似乎給StackOverFlowException,但是當我改變有效載荷路由通道nullChannel錯誤消失

<int:publish-subscribe-channel id="global-wire-tap-channel" /> 

<int:service-activator input-channel="log-channel" ref="loggerEndpointService" method="logMessageHistory" /> 

<int:payload-type-router input-channel="global-wire-tap-channel" default-output-channel="nullChannel"> 
    <int:mapping type="java.lang.Exception" channel="global-notifier-error-channel" /> 
</int:payload-type-router> 

堆棧跟蹤如已給出

java.lang.StackOverflowError 
at java.lang.Class.privateGetDeclaredMethods(Class.java:2414) 
at java.lang.Class.getMethod0(Class.java:2670) 
at java.lang.Class.getMethod(Class.java:1603) 
at org.apache.commons.logging.LogFactory.directGetContextClassLoader(LogFactory.java:825) 
at org.apache.commons.logging.LogFactory$1.run(LogFactory.java:791) 
at java.security.AccessController.doPrivileged(Native Method) 
at org.apache.commons.logging.LogFactory.getContextClassLoader(LogFactory.java:788) 
at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:383) 
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:645) 
at org.springframework.messaging.support.MessageHeaderAccessor.<init>(MessageHeaderAccessor.java:51) 
at org.springframework.integration.IntegrationMessageHeaderAccessor.<init>(IntegrationMessageHeaderAccessor.java:49) 
at org.springframework.integration.support.MessageBuilder.<init>(MessageBuilder.java:59) 
at org.springframework.integration.support.MessageBuilder.fromMessage(MessageBuilder.java:75) 
at org.springframework.integration.support.DefaultMessageBuilderFactory.fromMessage(DefaultMessageBuilderFactory.java:29) 
at org.springframework.integration.support.DefaultMessageBuilderFactory.fromMessage(DefaultMessageBuilderFactory.java:25) 
at org.springframework.integration.history.MessageHistory.write(MessageHistory.java:76) 
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:76) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:160) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:142) 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255) 
at org.springframework.integration.channel.interceptor.WireTap.preSend(WireTap.java:128) 
at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:338) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:251) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:223) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:114) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:44) 
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:93) 
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:175) 
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:160) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:142) 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255) 
at org.springframework.integration.channel.interceptor.WireTap.preSend(WireTap.java:128) 
at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:338) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:251) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:223) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:114) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:44) 
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:93) 
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:175) 
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:160) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:142) 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255) 
at org.springframework.integration.channel.interceptor.WireTap.preSend(WireTap.java:128) 
at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:338) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:251) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:223) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:114) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:44) 
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:93) 
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:175) 
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:160) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:142) 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255) 
at org.springframework.integration.channel.interceptor.WireTap.preSend(WireTap.java:128) 
at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:338) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:251) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:223) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:114) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:44) 
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:93) 
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:175) 
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:160) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:142) 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255) 
at org.springframework.integration.channel.interceptor.WireTap.preSend(WireTap.java:128) 
at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:338) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:251) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:223) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:114) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:44) 
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:93) 
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:175) 
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:160) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:142) 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255) 
at org.springframework.integration.channel.interceptor.WireTap.preSend(WireTap.java:128) 
at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:338) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:251) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:223) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:114) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:44) 
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:93) 
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:175) 
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:160) 
at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:142) 

顯然,當我這樣做,也沒有給出

<int:wire-tap pattern="*" channel="global-notifier-error-channel" /> 

則通知將工作

工作

<int:wire-tap pattern="*" channel="global-wire-tap-channel" /> 

<int:channel id="global-wire-tap-channel" /> 

<int:payload-type-router input-channel="global-wire-tap-channel" default-output-channel="nullChannel"> 
    <int:mapping type="java.lang.Exception" channel="global-notifier-error-channel" /> 
</int:payload-type-router> 

但是如果我直接調用全局通知錯誤通道

Regards, Milinda

回答

1

我想說,你去正確的方式劃分邏輯實現loosely-coupled原理。這是正確的,不同的模塊(或集成流程)可以擁有自己的錯誤處理邏輯,這很好,您可以使用error-channel來捕獲這些下游異常。

我看到一個很好的解決方案,爲您的全球tweeting錯誤處理。我們不能在這裏使用內置的error-channel,因爲任何自定義優先。但是我們可以爲它們添加一個方面,對於所有這些目標錯誤通道,它是全球<wire-tap>pattern。在這種情況下,您的所有開發人員都應遵循命名約定來處理所有錯誤通道,以允許該全局通道攔截器爲他們處理消息。

但是請注意,請注意,WireTap處理消息preSend。因此全局錯誤處理將在任何定製邏輯之前進行。在這種情況下,您可能需要編寫簡單的WireTap擴展來做postSend

+0

您好Artem,請您在postSend中的WireTap上進一步闡述一下,或許還有一些示例代碼。此外,我假設postSend的意思就像在方面處理結果從變壓器(或聚合器或服務)返回。 – MilindaD

+0

請詳細瞭解ChannelInterceptor:http://docs.spring.io/spring-integration/docs/latest-ga/reference/html/messaging-channels-section.html#channel-interceptors –