异步发送消息

Spring为异步消息传递提供的三个选项:

Java消息服务(JMS),RabbitMQ和高级消息队列协议(AMQP)以及Apache Kafka

使用JMS发送消息

为构建添加启动器依赖项

ActiveMQ Artemis,则启动器依赖项应如下所示:


  org.springframework.boot
  spring-boot-starter-artemis

默认情况下,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

异步发送消息_第1张图片

使用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> typeIdMappings = new HashMap>();
  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");
  }
}

 

你可能感兴趣的:(Spring)