一尘不染

Spring多个imapAdapter

spring-boot

我是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

没有代码重复怎么办?


阅读 506

收藏
2020-05-30

共1个答案

一尘不染

使用配置了属性的多个应用程序上下文。

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

如果您需要他们共同养活emailReceiverService; 使各个适配器上下文成为子上下文;请参阅样本自述文件以获取有关如何进行操作的指针。

编辑:

这是一个示例,其中服务(和渠道)在共享的父上下文中…

@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);
    }

}

希望能有所帮助。

请注意,您不需要服务激活器上的轮询器-使用a DirectChannel,该服务将在轮询器执行器线程上被调用-无需其他异步切换。

2020-05-30