Spring multiple imapAdapter

Soy principiante en Spring y no me gusta la duplicación de código. Escribí un ImapAdapter que funciona bien:

@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 mailMessageSource(MailReceiver imapMailReceiver) { return new MailReceivingMessageSource(imapMailReceiver); } @Bean @Value("imaps://:@: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); } } 

Pero quiero aproximadamente 20 adaptadores como ese, la única diferencia es imapUrl .

¿Cómo hacer eso sin duplicación de código?

Use contextos de aplicaciones múltiples, configurados con propiedades.

Esta muestra es un ejemplo; usa XML para su configuración, pero las mismas técnicas se aplican a la configuración de Java.

Si los necesita para alimentar a un emailReceiverService común; hacer que los contextos del adaptador individual sean contextos secundarios; vea el archivo léame de muestra para ver cómo hacerlo.

EDITAR:

Aquí hay un ejemplo, con el servicio (y el canal) en un contexto principal compartido …

 @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 children = new ArrayList(); 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(); } } 

y

 @Configuration @EnableIntegration public class GeneralImapAdapter { @Bean public static PropertySourcesPlaceholderConfigurer pspc() { return new PropertySourcesPlaceholderConfigurer(); } @Bean @InboundChannelAdapter(value = "emailChannel", poller = @Poller(fixedDelay = "10000") ) public MessageSource 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; } } 

y

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

Espero que ayude.

Tenga en cuenta que no necesita un sondeo en el activador del servicio: use un DirectChannel y el servicio se invocará en el hilo del ejecutor del sondeador, sin necesidad de otro traspaso asincrónico.