1

因此,我正在开展一个项目,其中许多团队都使用通用服务并遵循通用架构。正在使用的服务之一是消息传递,目前是带有 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;

    }
}
4

0 回答 0