消息通道是一个还是多个?
Message channels one or many?
我需要处理来自大约 30 个地址的电子邮件。我以一种方式实现这一点,所有电子邮件都发送到一个 DirectChannel
,然后再发送到 Receiver
。在 Receiver
中,我可以理解消息来自哪个地址,为此我创建 CustomMessageSource
将 javax.mail.Message
包装到我自己的类型,其中包含 javax.mail.Message
和一些 Enum
.看起来这不是一个好的决定,因为我可以使用 @Transformer
,但如果我只有 1 个频道,我该如何使用它?
这是第一个问题。
第二题:
我应该为所有地址使用 ONE 通道和 ONE 接收器吗?或者更好地为每个邮件地址设置频道和接收者?我不明白 Spring 如此深刻,无法感受到差异。
p.s。这个问题是
的延续
在每个 child 上下文中,您可以添加一个 header enricher 以将自定义 header 设置为来自适配器的 URL;输出通道是共享服务的共享通道。
在服务中,使用void foo(Message emailMessage, @Header("myHeader") String url)
我通常建议使用单一服务,除非该服务需要根据源做完全不同的事情。
编辑:
我修改了对您之前问题的回答,以在 header 中使用 url 增强原始消息;每个实例都有自己的 header enricher,它们都将经过丰富的消息路由到公共 emailChannel
.
@Configuration
@EnableIntegration
public class GeneralImapAdapter {
@Value("${imap.url}")
String imapUrl;
@Bean
public static PropertySourcesPlaceholderConfigurer pspc() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
@InboundChannelAdapter(value = "enrichHeadersChannel", poller = @Poller(fixedDelay = "10000") )
public MessageSource<javax.mail.Message> mailMessageSource(MailReceiver imapMailReceiver) {
return new MailReceivingMessageSource(imapMailReceiver);
}
@Bean
public MessageChannel enrichHeadersChannel() {
return new DirectChannel();
}
@Bean
@Transformer(inputChannel="enrichHeadersChannel", outputChannel="emailChannel")
public HeaderEnricher enrichHeaders() {
Map<String, ? extends HeaderValueMessageProcessor<?>> headersToAdd =
Collections.singletonMap("emailUrl", new StaticHeaderValueMessageProcessor<>(this.imapUrl));
HeaderEnricher enricher = new HeaderEnricher(headersToAdd);
return enricher;
}
@Bean
public MailReceiver imapMailReceiver() {
MailReceiver receiver = mock(MailReceiver.class);
Message message = mock(Message.class);
when(message.toString()).thenReturn("Message from " + this.imapUrl);
Message[] messages = new Message[] {message};
try {
when(receiver.receive()).thenReturn(messages);
}
catch (MessagingException e) {
e.printStackTrace();
}
return receiver;
}
}
...我修改了接收服务,以便它可以访问 header...
@MessageEndpoint
public class EmailReceiverService {
@ServiceActivator(inputChannel="emailChannel")
public void handleMessage(Message message, @Header("emailUrl") String url) {
System.out.println(message + " header:" + url);
}
}
...希望对您有所帮助。
编辑 2:
这个有点复杂;它从有效载荷中提取 from 并将其放入 header;您的用例不需要,因为您有完整的消息,但它说明了技术...
@Bean
@Transformer(inputChannel="enrichHeadersChannel", outputChannel="emailChannel")
public HeaderEnricher enrichHeaders() {
Map<String, HeaderValueMessageProcessor<?>> headersToAdd = new HashMap<>();
headersToAdd.put("emailUrl", new StaticHeaderValueMessageProcessor<String>(this.imapUrl));
Expression expression = new SpelExpressionParser().parseExpression("payload.from[0].toString()");
headersToAdd.put("from", new ExpressionEvaluatingHeaderValueMessageProcessor<>(expression, String.class));
HeaderEnricher enricher = new HeaderEnricher(headersToAdd);
return enricher;
}
和
@ServiceActivator(inputChannel="emailChannel")
public void handleMessage(Message message, @Header("emailUrl") String url,
@Header("from") String from) {
System.out.println(message + " header:" + url + " from:" + from);
}
我需要处理来自大约 30 个地址的电子邮件。我以一种方式实现这一点,所有电子邮件都发送到一个 DirectChannel
,然后再发送到 Receiver
。在 Receiver
中,我可以理解消息来自哪个地址,为此我创建 CustomMessageSource
将 javax.mail.Message
包装到我自己的类型,其中包含 javax.mail.Message
和一些 Enum
.看起来这不是一个好的决定,因为我可以使用 @Transformer
,但如果我只有 1 个频道,我该如何使用它?
这是第一个问题。
第二题:
我应该为所有地址使用 ONE 通道和 ONE 接收器吗?或者更好地为每个邮件地址设置频道和接收者?我不明白 Spring 如此深刻,无法感受到差异。
p.s。这个问题是
在每个 child 上下文中,您可以添加一个 header enricher 以将自定义 header 设置为来自适配器的 URL;输出通道是共享服务的共享通道。
在服务中,使用void foo(Message emailMessage, @Header("myHeader") String url)
我通常建议使用单一服务,除非该服务需要根据源做完全不同的事情。
编辑:
我修改了对您之前问题的回答,以在 header 中使用 url 增强原始消息;每个实例都有自己的 header enricher,它们都将经过丰富的消息路由到公共 emailChannel
.
@Configuration
@EnableIntegration
public class GeneralImapAdapter {
@Value("${imap.url}")
String imapUrl;
@Bean
public static PropertySourcesPlaceholderConfigurer pspc() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
@InboundChannelAdapter(value = "enrichHeadersChannel", poller = @Poller(fixedDelay = "10000") )
public MessageSource<javax.mail.Message> mailMessageSource(MailReceiver imapMailReceiver) {
return new MailReceivingMessageSource(imapMailReceiver);
}
@Bean
public MessageChannel enrichHeadersChannel() {
return new DirectChannel();
}
@Bean
@Transformer(inputChannel="enrichHeadersChannel", outputChannel="emailChannel")
public HeaderEnricher enrichHeaders() {
Map<String, ? extends HeaderValueMessageProcessor<?>> headersToAdd =
Collections.singletonMap("emailUrl", new StaticHeaderValueMessageProcessor<>(this.imapUrl));
HeaderEnricher enricher = new HeaderEnricher(headersToAdd);
return enricher;
}
@Bean
public MailReceiver imapMailReceiver() {
MailReceiver receiver = mock(MailReceiver.class);
Message message = mock(Message.class);
when(message.toString()).thenReturn("Message from " + this.imapUrl);
Message[] messages = new Message[] {message};
try {
when(receiver.receive()).thenReturn(messages);
}
catch (MessagingException e) {
e.printStackTrace();
}
return receiver;
}
}
...我修改了接收服务,以便它可以访问 header...
@MessageEndpoint
public class EmailReceiverService {
@ServiceActivator(inputChannel="emailChannel")
public void handleMessage(Message message, @Header("emailUrl") String url) {
System.out.println(message + " header:" + url);
}
}
...希望对您有所帮助。
编辑 2:
这个有点复杂;它从有效载荷中提取 from 并将其放入 header;您的用例不需要,因为您有完整的消息,但它说明了技术...
@Bean
@Transformer(inputChannel="enrichHeadersChannel", outputChannel="emailChannel")
public HeaderEnricher enrichHeaders() {
Map<String, HeaderValueMessageProcessor<?>> headersToAdd = new HashMap<>();
headersToAdd.put("emailUrl", new StaticHeaderValueMessageProcessor<String>(this.imapUrl));
Expression expression = new SpelExpressionParser().parseExpression("payload.from[0].toString()");
headersToAdd.put("from", new ExpressionEvaluatingHeaderValueMessageProcessor<>(expression, String.class));
HeaderEnricher enricher = new HeaderEnricher(headersToAdd);
return enricher;
}
和
@ServiceActivator(inputChannel="emailChannel")
public void handleMessage(Message message, @Header("emailUrl") String url,
@Header("from") String from) {
System.out.println(message + " header:" + url + " from:" + from);
}