我想为ImapIdleChannelAdapter收到的电子邮件设置事务行为。在事务提交后我想从电子邮件中删除邮件。我已经以这种方式设置了我的邮件接收器配置:
@Configuration
@EnableAsync
@EnableTransactionManagement
@ConfigurationProperties(prefix = "email")
@Profile("email")
public class MailReceiverConfiguration {
@Setter
private String imapUsername;
@Setter
private String imapPassword;
@Setter
private String imapServer;
@Setter
private String imapServerPort;
@Setter
private String folder;
@Setter
private String storeProtocol;
@Bean(name = "emailTransactionManager")
public PlatformTransactionManager emailTransactionManager() {
PseudoTransactionManager pseudoTransactionManager = new PseudoTransactionManager();
pseudoTransactionManager.getTransactionSynchronization();
return pseudoTransactionManager;
}
@Bean
public QueueChannel receiveChannel() {
return new QueueChannel();
}
@Bean
public ImapIdleChannelAdapter imapIdleChannelAdapter(ImapMailReceiver imapMailReceiver) {
ImapIdleChannelAdapter imapIdleChannelAdapter = new ImapIdleChannelAdapter(imapMailReceiver);
imapIdleChannelAdapter.setAutoStartup(true);
imapIdleChannelAdapter.setOutputChannel(receiveChannel());
imapIdleChannelAdapter.setTransactionSynchronizationFactory(transactionSynchronizationFactory());
return imapIdleChannelAdapter;
}
@Bean
public ImapMailReceiver imapMailReceiver() throws UnsupportedEncodingException {
ImapMailReceiver receiver = new ImapMailReceiver(
storeProtocol + "://" + URLEncoder.encode(imapUsername, "UTF-8") + ":" + imapPassword + "@" + imapServer + ":" + imapServerPort + "/" + folder
);
receiver.setShouldDeleteMessages(false);
receiver.setShouldMarkMessagesAsRead(true);
return receiver;
}
@Bean
public DefaultTransactionSynchronizationFactory transactionSynchronizationFactory() {
ExpressionParser parser = new SpelExpressionParser();
ExpressionEvaluatingTransactionSynchronizationProcessor syncProcessor =
new ExpressionEvaluatingTransactionSynchronizationProcessor();
syncProcessor.setAfterCommitExpression(parser.parseExpression("@messagesDeleter.process(payload)"));
return new DefaultTransactionSynchronizationFactory(syncProcessor);
}
@Bean
public MessagesDeleter messagesDeleter() {
return new MessagesDeleter();
}
}
Bean MessageDeleter有void方法将标志删除为消息:
public class MessagesDeleter{
public void process(MimeMessage message) throws Exception{
Folder folder = message.getFolder();
String messageId = message.getMessageID();
Message[] messages = folder.getMessages();
for (int i = 0; i < messages.length; i++) {
if (((MimeMessage) messages[i]).getMessageID().equals(messageId)) {
messages[i].setFlag(Flags.Flag.DELETED, true);
break;
}
}
folder.close(true);
}
我尝试在spring documentation中做所有事情。我收到消息,但交易不存在。我在方法createMessageSendingTask(final Object mailMessage)
中的ImapIdleChannelAdapter中发现,当检查TransactionSynchronizationManager.isActualTransactionActive()
时,它返回false
。我如何添加喜欢的TransactionManager或包含它。或者我犯了什么错误?
答案 0 :(得分:1)
imapIdleChannelAdapter.setTransactionSynchronizationFactory(transactionSynchronizationFactory());
你是对的。
您遗失的是在TransactionInterceptor
中添加imapIdleChannelAdapter.setAdviceChain()
的事实:
imapIdleChannelAdapter.setAdviceChain(
Collections.singletonList(
new TransactionInterceptorBuilder()
.transactionManager(emailTransactionManager())
.build()))
<强>更新强>
在Spring Integration 5.0
之前,您需要手动配置TransactionInterceptor
:
TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
MatchAlwaysTransactionAttributeSource txAttributeSource = new MatchAlwaysTransactionAttributeSource();
txAttributeSource.setTransactionAttribute(new DefaultTransactionAttribute());
transactionInterceptor.setTransactionAttributeSource(txAttributeSource);
transactionInterceptor.setTransactionManager(emailTransactionManager());