email - Spring 多个 imapAdapter

标签 email spring-boot spring-integration

我是 Spring 的新手,我不喜欢代码重复。
我写了一个运行良好的 ImapAdapter:

@Component
public class GeneralImapAdapter {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private EmailReceiverService emailReceiverService;

    @Bean
    @InboundChannelAdapter(value = "emailChannel", poller = @Poller(fixedDelay = "10000", taskExecutor = "asyncTaskExecutor"))
    public MessageSource<javax.mail.Message> mailMessageSource(MailReceiver imapMailReceiver) {
        return new MailReceivingMessageSource(imapMailReceiver);
    }

    @Bean
    @Value("imaps://<login>:<pass>@<url>:993/inbox")
    public MailReceiver imapMailReceiver(String imapUrl) {
        ImapMailReceiver imapMailReceiver = new ImapMailReceiver(imapUrl);
        imapMailReceiver.setShouldMarkMessagesAsRead(true);
        imapMailReceiver.setShouldDeleteMessages(false);
        // other setters here
        return imapMailReceiver;
    }

    @ServiceActivator(inputChannel = "emailChannel",  poller = @Poller(fixedDelay = "10000", taskExecutor = "asyncTaskExecutor"))
    public void emailMessageSource(javax.mail.Message message) {
        emailReceiverService.receive(message);
    }
}

但我想要大约 20 个这样的适配器,唯一的区别是 imapUrl .

如何在不重复代码的情况下做到这一点?

最佳答案

使用多个应用程序上下文,配置有属性。

This sample是一个例子;它使用 XML 进行配置,但同样的技术也适用于 Java 配置。

如果您需要它们馈入公共(public) emailReceiverService ;使各个适配器上下文成为子上下文;有关如何执行此操作的指示,请参阅示例自述文件。

编辑:

这是一个示例,服务(和 channel )位于共享父上下文中......

@Configuration
@EnableIntegration
public class MultiImapAdapter {

    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(MultiImapAdapter.class);
        parent.setId("parent");
        String[] urls = { "imap://foo", "imap://bar" };
        List<ConfigurableApplicationContext> children = new ArrayList<ConfigurableApplicationContext>();
        int n = 0;
        for (String url : urls) {
            AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
            child.setId("child" + ++n);
            children.add(child);
            child.setParent(parent);
            child.register(GeneralImapAdapter.class);
            StandardEnvironment env = new StandardEnvironment();
            Properties props = new Properties();
            // populate properties for this adapter
            props.setProperty("imap.url", url);
            PropertiesPropertySource pps = new PropertiesPropertySource("imapprops", props);
            env.getPropertySources().addLast(pps);
            child.setEnvironment(env);
            child.refresh();
        }
        System.out.println("Hit enter to terminate");
        System.in.read();
        for (ConfigurableApplicationContext child : children) {
            child.close();
        }
        parent.close();
    }

    @Bean
    public MessageChannel emailChannel() {
        return new DirectChannel();
    }

    @Bean
    public EmailReceiverService emailReceiverService() {
        return new EmailReceiverService();
    }

}


@Configuration
@EnableIntegration
public class GeneralImapAdapter {

    @Bean
    public static PropertySourcesPlaceholderConfigurer pspc() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    @InboundChannelAdapter(value = "emailChannel", poller = @Poller(fixedDelay = "10000") )
    public MessageSource<javax.mail.Message> mailMessageSource(MailReceiver imapMailReceiver) {
        return new MailReceivingMessageSource(imapMailReceiver);
    }

    @Bean
    @Value("${imap.url}")
    public MailReceiver imapMailReceiver(String imapUrl) {
//      ImapMailReceiver imapMailReceiver = new ImapMailReceiver(imapUrl);
//      imapMailReceiver.setShouldMarkMessagesAsRead(true);
//      imapMailReceiver.setShouldDeleteMessages(false);
//      // other setters here
//      return imapMailReceiver;
        MailReceiver receiver = mock(MailReceiver.class);
        Message message = mock(Message.class);
        when(message.toString()).thenReturn("Message from " + imapUrl);
        Message[] messages = new Message[] {message};
        try {
            when(receiver.receive()).thenReturn(messages);
        }
        catch (MessagingException e) {
            e.printStackTrace();
        }
        return receiver;
    }

}


@MessageEndpoint
public class EmailReceiverService {

    @ServiceActivator(inputChannel="emailChannel")
    public void handleMessage(javax.mail.Message message) {
        System.out.println(message);
    }

}

希望有帮助。

请注意,您不需要服务激活器上的轮询器 - 使用 DirectChannel并且服务将在轮询执行器线程上调用 - 不需要另一个异步切换。

关于email - Spring 多个 imapAdapter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32826864/

相关文章:

python - GAE Python - 如何对邮件正文中的特殊字符进行编码?

linux - 使用 formail 获取电子邮件文件的最后一封电子邮件

java - 如何在 Spring 创建所有带有 Flyway 的模型?

java - 用于故障转移和恢复的最佳 Kafka 生产者选项

java - Spring cvc复合型.2.4.a : Invalid content was found starting with element 'channel'

Javascript 多电子邮件正则表达式验证

html - 保存到 Google 云端硬盘时,HTML 电子邮件中文本上的背景图像消失

java - Autowiring 异常

java - Spring-boot登录成功后如何限制POST Rest Api公开访问

spring - Spring Security中已弃用的AuthorizationServer的替代品是什么?