異步發送消息

Spring爲異步消息傳遞提供的三個選項:

Java消息服務(JMS),RabbitMQ和高級消息隊列協議(AMQP)以及Apache Kafka

使用JMS發送消息

爲構建添加啓動器依賴項

ActiveMQ Artemis,則啓動器依賴項應如下所示:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-artemis</artifactId>
</dependency>

默認情況下,Spring假定您的Artemis代理正在偵聽localhost端口61616.這適用於開發目的,但是一旦您準備好將應用程序投入生產,您將需要設置一些告訴Spring如何訪問的屬性經紀人。表8.1列出了您認爲最有用的屬性。

表8.1。 用於配置Artemis代理的位置和憑據的屬性

屬性

描述

spring.artemis.host 經紀人的主人
spring.artemis.port 經紀人的港口
spring.artemis.user 用於訪問代理的用戶(可選)
spring.artemis.password 用於訪問代理的密碼(可選)

例如,請考慮可能在非開發設置中使用的application.yml文件中的以下條目:

spring:
  artemis:
    host: artemis.tacocloud.com
    port: 61617
    user: tacoweb
    password: l3tm31n

安裝並啓動Artemis(或ActiveMQ)代理,而不是使用嵌入式代理

Artemis - https://activemq.apache.org/artemis/docs/latest/using-server.html

下載:https://activemq.apache.org/components/artemis/download/

Windows Server 

創建代理mybroker,並根據提示設置用戶名和密碼

$ artemis create mybroker

使用JmsTemplate發送消息

三種配置目標地址的方法:

1.在配置文件application.properties中設置默認地址Address

spring.jms.template.default-destination=tacocloud.order.queue

2. 聲明一個Destination 的bean

@Bean
public Destination orderQueue() {
  return new ActiveMQQueue("tacocloud.order.queue");
}

3.在發送消息時,同時傳入地址

package tacos.messaging;

import tacos.Order;

public interface OrderMessagingService {
    void sendOrder(Order order);
    void sendOrderFromDestination(Order order);
    void sendOrderFromString(Order order);
}
package tacos.messaging;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import tacos.Order;

import javax.jms.Destination;

@Service
public class JmsOrderMessagingService implements OrderMessagingService{
    private JmsTemplate jms;
    private Destination orderQueue;

    @Autowired
    public JmsOrderMessagingService(JmsTemplate jms,Destination orderQueue){
        this.jms=jms;
        this.orderQueue=orderQueue;
    }

    //發送到配置文件設置的地址,spring.jms.template.default-destination=tacocloud.order.queue
    @Override
    public void sendOrder(Order order) {
        jms.send(session -> session.createObjectMessage(order));
    }

    //發送到Bean設置的地址
    @Override
    public void sendOrderFromDestination(Order order) {
        jms.send(orderQueue,session -> session.createObjectMessage(order));
    }

    //發送到字符串設置的地址
    @Override
    public void sendOrderFromString(Order order) {
        jms.send("tacocloud.order.queue",session -> session.createObjectMessage(order));
    }


}

配置消息轉換器

爲了提供更大的靈活性,您可以通過調用setTypeIdMappings()消息轉換器將合成類型名稱映射到實際類型

@Bean
public MappingJackson2MessageConverter messageConverter() {
  MappingJackson2MessageConverter messageConverter =
                          new MappingJackson2MessageConverter();
  messageConverter.setTypeIdPropertyName("_typeId");

  Map<String, Class<?>> typeIdMappings = new HashMap<String, Class<?>>();
  typeIdMappings.put("order", Order.class);
  messageConverter.setTypeIdMappings(typeIdMappings);

  return messageConverter;
}

爲消息添加來源信息

@GetMapping("/convertAndSend/order")
public String convertAndSendOrder() {
  Order order = buildOrder();
  jms.convertAndSend("tacocloud.order.queue", order,
      this::addOrderSource);
  return "Convert and sent order";
}

private Message addOrderSource(Message message) throws JMSException {
  message.setStringProperty("X_ORDER_SOURCE", "WEB");
  return message;
}

接收JMS消息

package tacos.kitchen.messaging.jms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class JmsOrderReceiver implements OrderReceiver {
  private JmsTemplate jms;

  @Autowired
  public JmsOrderReceiver(JmsTemplate jms) {
    this.jms = jms;
  }

  public Order receiveOrder() {
    return (Order) jms.receiveAndConvert("tacocloud.order.queue");
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章