Spring несколько imapAdapter
Я новичок в весне, и я не люблю дублирование кода. Я написал один 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
,
Как это сделать без дублирования кода?
1 ответ
Используйте несколько контекстов приложения, настроенных с помощью свойств.
Этот образец является примером; он использует XML для своей конфигурации, но те же методы применяются и для конфигурации Java.
Если вам нужно их кормить в общий emailReceiverService
; сделать отдельные адаптеры контекстами дочерними контекстами; см. образец readme для указателей о том, как это сделать.
РЕДАКТИРОВАТЬ:
Вот пример со службой (и каналом) в общем родительском контексте...
@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
и служба будет вызываться в потоке исполнителя поллера - нет необходимости в другой асинхронной передаче обслуживания.