目前我們有一個要求來處理彈簧集成流程中的異常。常見的彈簧集成異常處理程序
當前的解決方案是通過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
您好Artem,請您在postSend中的WireTap上進一步闡述一下,或許還有一些示例代碼。此外,我假設postSend的意思就像在方面處理結果從變壓器(或聚合器或服務)返回。 – MilindaD
請詳細瞭解ChannelInterceptor:http://docs.spring.io/spring-integration/docs/latest-ga/reference/html/messaging-channels-section.html#channel-interceptors –