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