添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency>
配置文件
spring:
artemis:
host: localhost
port: 61617
user: admin
password: admin
提示:如果是在本地开发可以不用配置这些属性
8.1.2 使用JmsTemplate发送消息
- 3个send方法都需要MessageCreator来生成Message对象
- 3个convertAndSend方法会接受Object对象,并且在幕后自动进行Object转换为Message
3个convertAndSend方法会自动将Object转换为Message,同时还能接受一个MessagePostProcessor对象,在发送之前对Message进行自定义
public class JmsOrderMessagingService implements OrderMessagingService{
private JmsTemplate jmsTemplate;
@Autowired
public JmsOrderMessagingService(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
@Override
public void sendOrder(Order order) {
jmsTemplate.send(new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createObjectMessage(order);
}
});
}
}
使用lambda表达式改写sendOrder方法
@Override
public void sendOrder(Order order) {
jmsTemplate.send(session -> session.createObjectMessage(order));
}
配置默认的目的地
spring:
jms:
template:
default-destination: tacocloud.order.queue
通过bean的方式配置目的地
@Bean
public Destination orderQueue() {
return new ActiveMQQueue("tacocloud.order.queue");
}
将bean注入
private Destination orderQueue;
@Autowired
public JmsOrderMessagingService(JmsTemplate jmsTemplate, Destination orderQueue) {
this.jmsTemplate = jmsTemplate;
this.orderQueue = orderQueue;
}
还可以用send方法第一个参数,指明目的地
@Override
public void sendOrder(Order order) {
jmsTemplate.send("tacocloud.order.queue", session -> session.createObjectMessage(order));
}
发送消息之前进行转换
利用convertAndSend方法,可以在发送消息之前将java类转化为Message
@Override
public void sendOrder(Order order) {
jmsTemplate.convertAndSend("tacocloud.order.queue", order);
}
配置消息转换器
默认是SimpleMessageConverter转换器,但是可以用下面的方法来替代默认的转换器
注意:是import org.springframework.jms.support.converter.MappingJackson2MessageConverter;包下面的
@Bean
public MappingJackson2MessageConverter messageConverter() {
MappingJackson2MessageConverter messageConverter = new MappingJackson2MessageConverter();
messageConverter.setTypeIdPropertyName("_typeId");
return messageConverter;
}
默认情况下,它将会包含要转换的类型的全限定类名。但是,这样的话会不太灵活,要求接收端也包含相同的类型,并且具有相同的全限定类名。为了实现更⼤的灵活性,我们可以通过调⽤消息转换器的setTypeIdMappings()⽅法将⼀个合成类型名映射到实际类型上。
@Bean
public MappingJackson2MessageConverter messageConverter() {
MappingJackson2MessageConverter messageConverter = new MappingJackson2MessageConverter();
messageConverter.setTypeIdPropertyName("_typeId");
HashMap<String, Class<?>> typeIdMappings = new HashMap<>();
typeIdMappings.put("order", Order.class);
messageConverter.setTypeIdMappings(typeIdMappings);
return messageConverter;
}
对消息进行后期处理
可以调用Message对象设置些属性,例如可以设置一下订单来源属性
@Override
public void sendOrder(Order order) {
jmsTemplate.send("tacocloud.order.queue", session -> {
Message message = session.createObjectMessage(order);
message.setStringProperty("X_ORDER_SOURCE", "WEB");
return message;
});
}
convertAndSend方法是在底层创建Message的,但是可以用第三个参数MessagePostProcessor来实现上面的效果
@Override
public void sendOrder(Order order) {
jmsTemplate.convertAndSend("tacocloud.order.queue", order, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws JMSException {
message.setStringProperty("X_ORDER_SOURCE", "WEB");
return message;
}
});
}
用lambda表达式简化
@Override
public void sendOrder(Order order) {
jmsTemplate.convertAndSend("tacocloud.order.queue", order, message -> {
message.setStringProperty("X_ORDER_SOURCE", "WEB");
return message;
});
}
8.1.3 接收JMS消息
使⽤JmsTemplate来接收消息
@Component
public class JmsOrderReceiver implements OrderReceiver{
private JmsTemplate jmsTemplate;
private MessageConverter messageConverter;
@Autowired
public JmsOrderReceiver(JmsTemplate jmsTemplate, MessageConverter messageConverter) {
this.jmsTemplate = jmsTemplate;
this.messageConverter = messageConverter;
}
@Override
public Order receiveOrder() throws JMSException {
Message message = jmsTemplate.receive("tacocloud.order.queue");
return (Order) messageConverter.fromMessage(message);
}
}
或者可以用receiveAndConvert
@Override
public Order receiveOrder() throws JMSException {
return (Order) jmsTemplate.receiveAndConvert("tacocloud.order.queue");
}
声明消息监听器
@Component
public class OrderListener {
private KitchenUI ui;
@Autowired
public OrderListener(KitchenUI ui) {
this.ui = ui;
}
@JmsListener(destination = "tacocloud.order.queue")
public void receiveOrder(Order order) {
ui.displayOrder(order);
}
}