2. SpringBoot使用jms整合IBM MQ


此次主要介紹jmsTemplate相關分享

目標:可以透過jmsTemplate與MQ互動(接收/互動)

前情提要:
銜接上1篇文章分析1下
spring boot 真的是很方便的東西
依賴注入、控制反轉
spring 起服務時會把所有@Bean放在Pool,我稱之@Bean Pool。
預設為單例模式(singleton),相同名稱的Bean都只有1個(同樣功能不同名稱的也算另1個)
有需要就注入很常使用@Autowired進行操作(@注釋這方式是從Java 5 開始的,非spring boot所擁有的特性)
boot系列優點是可以用較簡單的設定,或很少量的資訊進行初始化設定。
對於想要了解或想要快速開方專注於商業模式也是很適合的

扯遠了,回歸正題。
上篇的ibm mq 寫法是屬於該系列的撰寫方式,但其實還有不同的mq。例如:activeMq
對於想要開發mq就要了解不同的mq時間成本上會耗費較大成本,因此有了jmsTemplate更高接的API來共同化操作模式。
方便於更多人快速開發、有很多很常用到的方法因為他人提供的模組因此不用自己在從新開發。
那現在開始介紹jmsTemplate

必須知識:

  1. java 8
  2. spring系列
  3. MVC 分層抽離
  4. mq的基本知識
  5. 可能需要會通靈,解釋性資訊不多XD

spring boot核心應用為以下

  1. spring starter
  2. . mq spring starter // 先前因依賴為spring web啟服務 現在改為mq starter
    <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.7.11</version>
     <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
     <groupId>com.ibm.mq</groupId>
     <artifactId>mq-jms-spring-boot-starter</artifactId>
     <version>2.0.0</version>
    </dependency>
    

次要應用依據需求自行調整

  1. ibm mq

使用為ibm mq

<dependency>
    <groupId>com.ibm.mq</groupId>
    <artifactId>com.ibm.mq.allclient</artifactId>
    <version>9.3.2.1</version>
</dependency>

分享片段程式

application.yml 這等同上1篇的IbmConnectionConfiguration.class

ibm:
  mq:
    queueManager: qm管理者
    channel: 自定義頻道
    connName: host(port)
    user:

互動介面
JmsMessageProcesser介面省略
僅JmsMessageProcesserImpl.class 完整class 請參考上1篇

@Override
public List<String> getAllMessages(String queueName) throws JMSException {
    try {
        return jmsTemplate.execute(session -> {
            try (final MessageConsumer consumer = session.createConsumer(session.createQueue(queueName))) {
                List<String> messages = new ArrayList<>();
                Message  message;
                while ((message = consumer.receiveNoWait()) != null) {
                    messages.add(this.getMsg(message));
                }
                return messages;
            }
        }, true);
    }catch (Exception e){
        e.printStackTrace();
        throw new JMSException("get Mssage Error",e.getMessage());
    }

/*
 * List<Message> messages = new ArrayList<Message>();
 * Message message;
 * while ((message = queueJmsTemplate.receive(destination)) != null) {
 * messages.add(message);
 * }
 * return messages;
 */

/*
 * The receive method of the JmsTemplate creates a new MessageConsumer every time.
 * The second time, your transaction is not yet committed, and Spring will have prefetched a number of messages during the first receive.
 * At that moment are no messages left to fetch, resulting in null from your receive call.
 * JmsTemplate in Spring has an "execute" method that takes a SessionCallback as parameter. This allows you to run your own code against the underlying session of the JmsTemplate. Creating only one MessageConsumer should fix your problem.
 */
    }

@Override
public String getMsg(String queueName) throws JMSException {
    try {
    Object res = jmsTemplate.receiveAndConvert(queueName);
    if (Objects.nonNull(res)){
        return res.toString();
    }
    // res equals null show that queue is empty
    return StringUtils.EMPTY;
    }catch (Exception e){
        e.printStackTrace();
        throw new JMSException("get Mssage Error",e.getMessage());
    }
}

透過RestfulApi介面接收/發送 完整的class請參考上1篇文章
JMSController.class

/*
 * test send msg to IBM MQ.
 * ref:
 * MQ JMS application development with Spring Boot
 * https://developer.ibm.com/tutorials/mq-jms-application-development-with-spring-boot/
 * SpringBoot IBM MQ without user authentication
 * https://stackoverflow.com/questions/55253877/springboot-ibm-mq-without-user-authentication
 * spring-boot
 *
 * @return all queue msg
 */
@GetMapping("/jmsTemplate-send")
public WebRestResponse<String> sendByJmsTemplate() {
    jmsTemplate.convertAndSend("自定義佇列", "Hello World!");
    return WebRestResponse.success();
}

@GetMapping("/jmsTemplate-get")
public WebRestResponse<String> getByJmsTemplate() throws JMSException {
        return WebRestResponse.success(jmsMessageService.getMsg("自定義佇列"));
    }

更重要@注釋讓服務啟動 @EnableJms
Application.class

@EnableJms
@SpringBootApplication(scanBasePackages = {Constant.BASE_PACKAGE})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

補充:

需要有mq服務 建議可以使用containter方便又快速
WebRestResponse自定義的JSON

主要是給自己的一個紀錄,也分享給有需要的夥伴
註解部分有提及一些參考的連結,有興趣可以點進去看看喔

這是一個心血來潮,產生的文章
若有喜歡或交流的部分都歡迎在下方留言,多多關照。

#mq #jmstemplate #ibm







你可能感興趣的文章

JS30 Day 5 筆記

JS30 Day 5 筆記

Express

Express

React-[入門篇]- JSX聲明式語法

React-[入門篇]- JSX聲明式語法






留言討論