1

そのため、多くのチームが共通のサービスを使用し、共通のアーキテクチャに従っているプロジェクトに取り組んでいます。使用されているサービスの 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 トピックに送信します。メッセージ (WorkDTO) が JMS 経由で送信される場合、最初に 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