因此,我正在开展一个项目,其中许多团队都使用通用服务并遵循通用架构。正在使用的服务之一是消息传递,目前是带有 ActiveMQ 的 JMS。几乎所有团队都需要遵循一套严格的规则来创建和发送消息,即一切都是 pub-subscribe 并且发送的消息有点像下面这样:
public class WorkDTO {
private String type;
private String subtype;
private String category;
private String jsonPayload; // converted custom Java object
}
'jsonPayload' 来自一个所有团队都从其扩展的基类,因此它具有共同的属性。
所以基本上在 JMS 中,每个人总是发送相同类型的消息,但是发送到不同的 ActiveMQ 主题。通过 JMS 发送消息 (WorkDTO) 时,首先将其转换为 JSON 对象,然后在 TextMessage 中发送。
每当团队希望为某个主题创建订阅者时,他们都会创建一个 DefaultMessageListenerContainer 并对其进行适当配置以接收消息(我们使用基于 Java 的 Spring 配置)。基本上,团队定义的每个 DefaultMessageListenerContainer 都几乎相同,除了接收消息的目的地和消息处理程序。
我想知道在这种情况下如何通过注释进一步抽象消息配置?这意味着,由于几乎每个人都必须遵循相同的要求,因此以下内容是否有用:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Listener {
String destination();
boolean durable() default false;
long receiveTimeout() default -1; // -1 use JMS default
String defaultListenerMethod() default "handleMessage";
// more config details here
}
@Listener(destination="PX.Foo", durable=true)
public class FooListener {
private ObjectMapper mapper = new ObjectMapper(); // converts JSON Strings to Java Classes
public void handleMessage(TextMessage message){
String text = message.getText();
WorkDTO dto = mapper.readValue(text, WorkDto.class);
String payload = dto.getPayload();
String type = dto.getType();
String subType = dto.getSubType();
String category = dto.getCategory();
}
}
当然,我省略了有关如何使用 @Listener 注释配置 DefaultMessageListenerContainer 的部分。我开始研究 BeanFactoryPostProcessor 来创建必要的类并将它们添加到应用程序上下文中,但我不知道如何做所有这些。
我问这个问题的原因是我们正在从 JMS/ActiveMQ 切换到 AMQP/RabbitMQ,并且希望通过使用注释来进一步抽象消息传递配置。我知道 AMQP 不像 JMS,所以配置细节会略有不同。我不相信我们会从 AMQP 切换到其他东西。
在这里,团队只需要知道目的地的名称以及他们是否想让他们的订阅持久。
这只是最近突然出现在我脑海中的事情。对此有什么想法吗?
我不想做一些过于复杂的事情,所以另一种选择是创建一个方便的方法,它返回一个预先配置的 DefaultMessageListenerContainer 给定一个目的地和一个消息处理程序:
@Configuration
public class MyConfig{
@Autowired
private MessageConfigFactory configFactory;
@Bean
public DefaultMessageListenerContainer fooListenerContainer(){
return configFactory.getListenerContainer("PX.Foo", new FooListener(), true);
}
}
class MessageConfigFactory {
public DefaultMessageListenerContainer getListener(String destination, Object listener, boolean durable) {
DefaultMessageListenerContainer l = new DefaultMessageListenerContainer();
// configuration details here
return l;
}
}