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列出了您认为最有用的属性。
属性 | 描述 |
---|---|
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");
}
}