发送
概述
JmsTemplate提供了3组*3,共计9个发送用的方法。
发送的方法有3组:
- 基本的发送
- 转换并发送
- 转换、后处理再发送
必需的资源
必需的资源有:
- javax.jms.ConnectionFactory
ConnectionFactory是客户端编程的开始,由它依次获取Connection、Session、Message、MessageProducer或MessageConsumer,从而做好了发送或接收的准备。 - javax.jms.Destination
Destination是发送的目的地,或者接收的源
实际上,我们提供了上述的资源之后,我们就是做了这样的指令:让JmsTemplate连接到Destination,从我们提供的ConnectionFactory中获取连接资源。
1.ConnectionFactory资源
我们如何提供ConnectionFactory给JmsTemplate?凭借
JmsTemplete提供的构造器或setter方法:
- public JmsTemplate(ConnectionFactory connectionFactory)
- public void setConnectionFactory(ConnectionFactory connectionFactory)
# 继承自org.springframework.jms.support.JmsAccessor
2.Destination资源
我们如何提供
Destination给JmsTemplate?
我们有两个机会做这件事,第一次是在初始化的时候提供一个默认的Destination,第二次是在发送的时候提供一个明确的Destination。相关的方法:
- public void setDefaultDestination(Destination destination)
设置默认的Destination - public void send(Destination destination, MessageCreator messageCreator)
将消息发送到指定的Destination
MessageCreator接口用来提供创建消息的回调方法,后面再讲。
JmsTemplate还提供了另一种获取Destination的方式:基于Destination解析器、Destination类型、Destination名字的获取。你可以使用下面的代码来指定解析器、Destination类型:
// jt is instance of JmsTemplate
jt.setDestinationResolver(new DynamicDestinationResolver()); // set Destination解析器
jt.setPubSubDomain(false); // set Destinantion类型
Destination解析器要实现org.springframework.jms.support.destination.DestinationResolver接口。解析器有默认的值,就是DynamicDestinationResolver,除非你要使用其他的解析器,否则不必调用setDestinationResolver。所以,第2行代码是多余的。
Destination类型有2个:false-Queue类型,true-Topic类型;默认为false。所以,第3行代码是多余的。
设置了解析器、类型,或者直接使用默认的值,之后,就可以设置destination的name。JmsTemplate提供了两个方法:
- public void setDefaultDestinationName(String destinationName)
设置defaultDestination。这个方法和setDefaultDestination(Destination destination)做同样的事情,只是这个方法依赖于解析器和类型。 - public void send(String destinationName, MessageCreator messageCreator)
将消息发送到指定的Destination。这个方法和send(Destination destination, MessageCreator messageCreator)做同样的事情,只是这个方法依赖于解析器和类型。
P.S.如何根据destinationName创建Destination实例?
javax.jms.Session提供了两个方法,分别创建两种类型的Destination:
- Queue createQueue(java.lang.String queueName)
根据name创建Queue类型的Destination - Topic createTopic(java.lang.String topicName)
根据name创建Topic类型的Destination
我们看下DynamicDestinationResolver的源码:
public class DynamicDestinationResolver implements DestinationResolver {
@Override
public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)
throws JMSException {
Assert.notNull(session, "Session must not be null");
Assert.notNull(destinationName, "Destination name must not be null");
if (pubSubDomain) {
return resolveTopic(session, destinationName);
}
else {
return resolveQueue(session, destinationName);
}
}
protected Topic resolveTopic(Session session, String topicName) throws JMSException {
return session.createTopic(topicName);
}
protected Queue resolveQueue(Session session, String queueName) throws JMSException {
return session.createQueue(queueName);
}
}
根据这份源码,可以帮助理解pubSubDomain的机制,以及将JMS的api和Spring的Destination解析器这两个知识点连接起来。
1.基本的发送方法
在前文我们已经接触了两个,它们都是在发送的同时指定Destination。现把它们和第3种一起介绍:
- public void send(Destination destination, MessageCreator messageCreator)
将消息发送到指定的Destination - public void send(String destinationName, MessageCreator messageCreator)
将消息发送到指定的Destination。这个方法和send(Destination destination, MessageCreator messageCreator)做同样的事情,只是这个方法依赖于解析器和类型。
- public void send(MessageCreator messageCreator)
将消息发送到defaultDestination。
这个方法要求提前设置defaultDestination,你可以调用setDefaultDestination(Destination destination)或者setDefaultDestinationName(String destinationName)来满足这个前提。
在3个基本的发送方法中,都使用MessageCreator来创建消息。