我使用spring-boot和spring集成来接收电子邮件并将附件保存到文件中。
我使用了PseudoTransactionManager,因为我想在电子邮件没有附件的情况下引发异常和角色(在角色中我将电子邮件移动到失败文件夹并在提交时将其移动到成功文件夹)。
@Bean(name="emailTransactionManager")
public PseudoTransactionManager emailTransactionManager() {
return new PseudoTransactionManager();
}
@Bean(name="transactionManager")
@Primary
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
每件事情都很好,除非我回来时我得到了以下错误。
2015-12-09 21:01:03.388 INFO 874 --- [ask-scheduler-1] o.s.integration.mail.ImapMailReceiver : attempting to receive mail from folder [INBOX]
2015-12-09 21:01:04.767 INFO 874 --- [pool-3-thread-1] c.t.r.m.support.EmailTransformer : Email contains 1 fragments.
2015-12-09 21:01:04.772 ERROR 874 --- [pool-3-thread-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: emailTransactionManager,transactionManager
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:96)
at org.springframework.integration.splitter.AbstractMessageProcessingSplitter.splitMessage(AbstractMessageProcessingSplitter.java:61)
at org.springframework.integration.splitter.AbstractMessageSplitter.handleRequestMessage(AbstractMessageSplitter.java:55)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:123)
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.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231)
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.handler.MessageHandlerChain.handleMessageInternal(MessageHandlerChain.java:104)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
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.mail.ImapIdleChannelAdapter.access$2300(ImapIdleChannelAdapter.java:62)
at org.springframework.integration.mail.ImapIdleChannelAdapter$1.run(ImapIdleChannelAdapter.java:269)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy83.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: emailTransactionManager,transactionManager
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:366)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:367)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:271)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:654)
at com.teltacworldwide.rateserver.mailattachments.support.EmailSplitter$$EnhancerBySpringCGLIB$$d5a16c5e.splitIntoMessages(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:113)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129)
at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330)
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:166)
at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:317)
at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:155)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:93)
... 43 more
2015-12-09 21:01:04.774 INFO 874 --- [pool-3-thread-1] c.t.r.mailattachments.support.ImapMove : Moving message <27492C59-5000-44E9-9151-E29BE98A7A24@teltacworldwide.com> to success folder
我不知道它是一个spring-boot还是集成但是日志记录适配器订阅了errorChannel并且它不能自动装入transactionManager我试图用@Primary注释transactionManager但是它没有工作< / p>
集成XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-file="http://www.springframework.org/schema/integration/file"
xmlns:int-mail="http://www.springframework.org/schema/integration/mail"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xsi:schemaLocation="http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/integration/mail http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<int:transaction-synchronization-factory
id="syncFactory">
<int:after-commit expression="@imapMove.success(payload)" />
<int:after-rollback expression="@imapMove.fail(payload)" />
</int:transaction-synchronization-factory>
<int-mail:imap-idle-channel-adapter
id="poll-for-email" channel="emailChannel" java-mail-properties="javaMailProperties"
store-uri="imaps://xxxxxxx\test:passw0rd@exchange.xxxxxxx.co/INBOX"
should-delete-messages="false" error-channel="failed-email-fetch" auto-startup="true">
<int-mail:transactional transaction-manager="emailTransactionManager" synchronization-factory="syncFactory"/>
</int-mail:imap-idle-channel-adapter>
<util:properties id="javaMailProperties">
<prop key="mail.store.protocol">imaps</prop>
<prop key="mail.pop3.starttls.enable">true</prop>
<prop key="mail.pop3.ssl.trust">exchange.xxxxxxx.co</prop>
<prop key="mail.imaps.starttls.enable">true</prop>
<prop key="mail.imaps.ssl.trust">exchange.xxxxxxx.co</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.ssl.trust">exchange.xxxxxxx.co</prop>
<prop key="mail.debug">false</prop>
</util:properties>
<int:channel id="emailChannel" />
<int:chain id="transform-split-save" input-channel="emailChannel"
output-channel="jobChannel">
<int:transformer ref="emailTransformer" />
<int:splitter ref="emailSplitter" />
<int:header-enricher ref="carrierEnricher" method="addCarrier" />
<int-file:outbound-gateway id="save-as-file"
auto-create-directory="true"
directory-expression="'target/out/' + headers.directory" />
</int:chain>
<!-- <int-file:outbound-channel-adapter id="save-as-file" auto-create-directory="true"
channel="outputChannel" directory-expression="'target/out/' + headers.directory"/> -->
<int:channel id="jobChannel" />
<int-stream:stdout-channel-adapter channel="jobChannel">
</int-stream:stdout-channel-adapter>
<int:exception-type-router input-channel="failed-email-fetch" default-output-channel="errorChannel">
<int:mapping exception-type="com.xxxxxxx.rateserver.exception.RateException"
channel="customError" />
</int:exception-type-router>
<int:channel id="failed-email-fetch" />
<int:channel id="customError" />
<int:service-activator input-channel="customError" ref="emailError" method="onEmailFetchFailed" />
</beans>
答案 0 :(得分:1)
我发现问题,在拆分器上,该方法使用@Transactional
注释,因此它使用默认的transactionManager
。
要确认我使用@Transactional(transactionManager="emailTranasactionmanager")
进行了尝试,它确实有效。在我的情况下,我刚删除了@Transaction
,因为我只需要一次交易。