I am novice in Spring and I don't like code duplication. I wrote one ImapAdapter that works fine:
@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);
}
}
But I want about 20 adapters like that, the only difference is imapUrl
.
How to do that without code duplication?
Use multiple application contexts, configured with properties.
This sample is an example; it uses XML for its configuration, but the same techniques apply with Java configuration.
If you need them to feed into a common
emailReceiverService
; make the individual adapter contexts child contexts; see the sample readme for pointers about how to do that.EDIT:
Here's an example, with the service (and channel) in a shared parent context...
and
and
Hope that helps.
Notice that you don't need a poller on the service activator - use a
DirectChannel
and the service will be invoked on the poller executor thread - no need for another async handoff.