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");
}
}