【问题标题】:Spring integration mail inbound channelSpring集成邮件入站通道
【发布时间】:2014-11-07 09:40:59
【问题描述】:

我是 Spring 和 Spring 集成的新手,我有一个简单的任务要完成。通过正则表达式按主题过滤一些电子邮件并在数据库中注册一些信息。

我已经设置了 JavaMailProperties,测试为我提供了已读电子邮件的输出,但我使用 service-activator 设置的方法从未被调用过,这实际上让我非常头疼。

以下是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:mail="http://www.springframework.org/schema/integration/mail"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
              http://www.springframework.org/schema/integration/mail  
              http://www.springframework.org/schema/integration/mail/spring-integration-mail-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">  
<util:properties id="javaMailProperties">
        <prop key="mail.store.protocol">pop3</prop>
        <prop key="mail.debug">true</prop>
    </util:properties>
    <mail:inbound-channel-adapter id="pop3Adapter" 
                                      store-uri="pop3://username:password@mail..example.com:110/INBOX"                                     
                                      channel="recieveEmailChannel"                                          
                                      should-delete-messages="false"                                   
                                      auto-startup="true"
                                      java-mail-properties="javaMailProperties"
                                      mail-filter-expression="subject matches '(^Presente+\\s([1-9]{1})+(\\s[-]\\s)+([A-Z]{4,})+(\\s[A-Z]{6,})$)'">
        <int:poller max-messages-per-poll="10" fixed-delay="10000"/>
    </mail:inbound-channel-adapter>
    <int:channel id="recieveEmailChannel">        
        <int:interceptors>
            <int:wire-tap channel="logger"/>
        </int:interceptors>
    </int:channel>
    <int:logging-channel-adapter id="logger" level="DEBUG"/>
    <int:service-activator input-channel="recieveEmailChannel" ref="leggiMail" method="processa_mail"/>
    <bean id="leggiMail" class="it.jenia.ac.mail.rapportini.LeggiMail">
    </bean>
</beans>

带有processa_mail方法的LeggiMail类非常简单:

import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.stereotype.Service;

@Service
public class LeggiMail {
    private static Logger logger = Logger.getLogger(LeggiMail.class);
    public static int count_get = 0;
    @ServiceActivator
    public void processa_mail(MimeMessage mimeMessage) {
        count_get++;
        logger.debug("porcessa_mail working");
    }

我正在使用这个应用程序的测试类:

@ContextConfiguration(locations = { "classpath*:/test-spring-configuration.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
public class LeggiMailTest {
    private static Logger logger = Logger.getLogger(LeggiMailTest.class);
    @Autowired
    LeggiMail lm;
    @Test
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
    public void test_processa_mail(){
        logger.debug("Test started");
    }
}

日志Test started 正确显示在控制台中,但日志porcessa_mail working 从未出现..

我在这个主题上找到的第一个教程只是谈到了一个默认情况下会被上下文调用的方法。 http://blog.solidcraft.eu/2011/04/read-emails-from-imap-with-spring.html(它说在加载上下文时默认调用方法“processa_mail”,因为它是service-activator

阅读本关于服务激活器的教程并没有足够的帮助:http://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html

【问题讨论】:

  • 为什么要调用它。如果我是正确的,应用程序会在此之后启动和停止。另外我想知道你为什么要加载 2 个上下文并让你混合来自不同上下文的 2 个 bean 变得更糟......乍一看我会说你的测试有缺陷。
  • 根据这个(blog.solidcraft.eu/2011/04/…) 教程,默认情况下应该调用该方法。我真的不明白为什么,但是,我可以问你一个解决方案来“在”阅读电子邮件之后调用该方法吗?
  • 我根本无法理解“中间”的过程..
  • 正如我所说,您的测试存在缺陷。您正在加载 2 个上下文,混合来自不同上下文的 bean....首先修复您的测试,据我所知,您正在尝试做太多事情并围绕框架工作而不是使用框架。此外,上下文加载并且什么也不做,您进行了测试,但不会检查任何邮件,因为上下文直接关闭/被清理。或者可能更糟(我怀疑)由于双重上下文,您还拥有多个频道。
  • 无论如何都要显示您当前的测试课程。对我来说,您应该在测试结束时等待一段时间,因为&lt;poller&gt; 使用单独的线程来接收电子邮件。但是你的主线程可能不会等待一段时间让LeggiMail 做这些事情。

标签: java spring spring-integration


【解决方案1】:

当您尝试测试一些 async 时,您需要添加一些 barrier 以防止 main 线程提前停止,而不是整个测试用例所必需的。

最简单的方法是在测试方法结束前添加Thread.sleep()

但更好的解决方案是基于一些synchonizer,比如CountDonwLatch

另一方面,Spring 集成中有QueueChannel。您可以将它用作output-channel&lt;service-activator&gt;。将其注入测试类并等待output.receive(10000)。和assert... 结果消息使您的测试真正成为单元测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-21
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2014-12-07
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多