email - us1 - www mailchimp com login español
Spring multiple imapAdapter (1)
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<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);
}
}
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<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();
}
}
y
@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;
}
}
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.