web-dev-qa-db-ja.com

Spring BootでJMSキューを実装する方法

イニシャライザを使用してSpring Bootプロジェクトを作成し、最初のメッセージを作成しようとしていますが、どこから始めればよいかわかりません。私はJEEを使用した同じプロセスに精通しているので、ファクトリー、センダー、およびコンシューマーを作成する必要があると思います。

誰かが私を助けてくれますか?

9
Maria Georgiou

開始するのに最適な場所は プロジェクトスタートガイド です。

あなたのアプローチは一般的には正しいですが、彼はスケルトンのように見えます。

最初のスプリングブートは完璧な構成ファイル構造を提供し、NetbeansのようなスマートIDEを使用している場合は、スプリングブートプラグインを追加することで、プロパティファイルでもオートコンプリートが提供されます。 Springはブローカーごとに少し異なる動作をするため、私の例ではActiveMQを使用します

ビルドパスにActiveMQを置くだけで、Spring Bootは自動的にActiveMQブローカーをセットアップします。接続プールなしでメモリブローカーにするために、いくつかのプロパティを設定する必要があります。これを行うには、Spring Bootに2つのプロパティを設定します。

spring.activemq.in-memory=true
spring.activemq.pooled=false
jms.bookmgrqueue.name=book-mgr-queue #queue name

他のブローカーについても同様の構成を行うことができます。

最初に、Springアプリケーションのセットアップから始めます。 @EnableJmsアノテーションを配置してJmsサポートを有効にし、新しいキューをセットアップする必要があります。

@EnableJms
@Configuration
public class JmsConfiguration {

    @Autowired
    private BeanFactory springContextBeanFactory;

    @Bean
    public DefaultJmsListenerContainerFactory containerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory =
                new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setDestinationResolver(new BeanFactoryDestinationResolver(springContextBeanFactory));
        factory.setConcurrency("3-10");
        return factory;
    }

    @Bean
    public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) throws JMSException {
        return new JmsTemplate(connectionFactory);
    }

}

メッセージのキューへのリッスン

リスナーコンポーネント(BookMgrQueueListener.Java)は、Springの@JmsListenerアノテーションをセレクターとともに使用して、指定されたOperationヘッダーのメッセージを読み取ります。

@Component
public class BookMgrQueueListener implements Loggable{

    private final BookService bookService;

    @Autowired
    public BookMgrQueueListener(BookService bookService) {
        this.bookService = bookService;
    }

    @JmsListener(containerFactory = "containerFactory",
                 destination = "bookMgrQueueDestination",
                 selector = "Operation = 'Create'")
    public void processCreateBookMessage(BookDTO book) throws JMSException{
        bookService.createNew(book);
    }

    @JmsListener(containerFactory = "containerFactory",
                 destination = "bookMgrQueueDestination",
                 selector = "Operation = 'Update'")
    public void processUpdateBookMessage(BookDTO book) throws JMSException{
        bookService.update(book.getIsbn(), book);
    }

    @JmsListener(containerFactory = "containerFactory",
                 destination = "bookMgrQueueDestination",
                 selector = "Operation = 'Delete'")
    public void processDeleteBookMessage(BookDTO book) throws JMSException{
        bookService.delete(book.getIsbn());
    }

}

テスト用のアクティブMQ

構成をテストするために、新しい構成ファイルActiveMqConfiguration.JavaにactiveMqブローカーを設定しています。

@Configuration
public class ActiveMqConfiguration {

    public static final String ADDRESS = "vm://localhost";

    private BrokerService broker;

    @Bean(name="bookMgrQueueDestination")
    public Destination bookMgrQueueDestination(@Value("${jms.bookmgrqueue.name}") String bookMgrQueueName)
            throws JMSException {
        return new ActiveMQQueue(bookMgrQueueName);
    }

    @PostConstruct
    public void startActiveMQ() throws Exception {
        broker = new BrokerService();
        // configure the broker
        broker.setBrokerName("activemq-broker");
        broker.setDataDirectory("target");
        broker.addConnector(ADDRESS);
        broker.setUseJmx(false);
        broker.setUseShutdownHook(false);
        broker.start();
    }

    @PreDestroy
    public void stopActiveMQ() throws Exception {
        broker.stop();
    }

    @Bean
    public ConnectionFactory connectionFactory() {
        return new ActiveMQConnectionFactory(ADDRESS + "?broker.persistent=false");
    }
}

テストケースで完全なアプリケーションコンテキストを設定していますが、リスナーのBookService参照をMockedBookServiceに置き換えています。これを使用して、正しい呼び出しが実行されたかどうかを確認します。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class, loader = SpringApplicationContextLoader.class)
@WebAppConfiguration
public class BookMgrQueueListenerIntegrationTest {

    @Autowired(required = false)
    private JmsTemplate jmsTemplate;

    @Autowired
    private BookMgrQueueListener bookMgrQueueListener;


    @Autowired(required = false)
    @Qualifier("bookMgrQueueDestination")
    private Destination bookMgrQueueDestination;

    @Mock
    private BookService mockBookService;

    @Captor
    private ArgumentCaptor<BookDTO> bookArgumentCaptor;

    @Before
    public void setUp(){
        MockitoAnnotations.initMocks(this);
        ReflectionTestUtils.setField(bookMgrQueueListener, "bookService", mockBookService);
    }

    /* ... tests */
}

最後に、すべての操作のテストを追加し、サービスレイヤーが正しい操作とパラメーターで呼び出されたかどうかを確認します。

/* ... */
public class BookMgrQueueListenerIntegrationTest {
    /* ... */
    @Test
    public void testSendCreateBookMessage(){
        BookDTO book =  new BookDTO("isbn", "title", "author");
        jmsTemplate.convertAndSend(bookMgrQueueDestination, book, Message -> {
            return OperationHeader.CREATE.applyToMessage(Message);
        });
        // verify
        verify(mockBookService).createNew(bookArgumentCaptor.capture());
        assertEquals(book.getIsbn(), bookArgumentCaptor.getValue().getIsbn());
        assertEquals(book.getTitle(), bookArgumentCaptor.getValue().getTitle());
        assertEquals(book.getAuthor(), bookArgumentCaptor.getValue().getAuthor());
    }

    @Test
    public void testSendUpdateBookMessage(){
        BookDTO book =  new BookDTO("isbn", "title", "author");
        jmsTemplate.convertAndSend(bookMgrQueueDestination, book, Message -> {
            return OperationHeader.UPDATE.applyToMessage(Message);
        });
        // verify
        verify(mockBookService).update(eq(book.getIsbn()), bookArgumentCaptor.capture());
        assertEquals(book.getIsbn(), bookArgumentCaptor.getValue().getIsbn());
        assertEquals(book.getTitle(),bookArgumentCaptor.getValue().getTitle());
        assertEquals(book.getAuthor(),bookArgumentCaptor.getValue().getAuthor());
    }

    @Test
    public void testSendDeleteBookMessage(){
        BookDTO book =  new BookDTO("isbn", "title", "author");
        jmsTemplate.convertAndSend(bookMgrQueueDestination, book, Message -> {
            return OperationHeader.DELETE.applyToMessage(Message);
        });
        // verify
        verify(mockBookService).delete(book.getIsbn());
    }

そして、私たちは行ってもいいです!

参照 JMSキューをSpringアプリケーションに統合

14