通过引用传递消息有效内容:转发应用程序的使用方案和示例代码
JMS 转发器应用程序接收消息(通过连接工厂,或者如果该应用程序是消息驱动的 Bean,那么通过激活规范),然后将消息对象发送至另一目标。研究不同使用方案,然后编写 JMS 转发应用程序,以便将消息从单个服务器中的一个队列转发至另一个队列时可通过引用安全地传递消息有效内容。
发送大型对象消息或字节消息时,序列化、反序列化和复制消息有效内容的内存和处理器使用成本可能会很高。 如果对连接工厂或激活规范启用通过引用传递消息有效内容属性,请通知缺省消息传递提供程序覆盖 JMS 1.1 规范并可能要减少或绕过此数据复制。
在下图中,消息通过使用者激活规范或连接工厂从消息传递引擎上的 queue1 传递至 JMS 转发应用程序。然后消息会通过生产者连接工厂转发至同一消息传递引擎上的 queue2。

- 转发应用程序不会替换消息对象。如果应用程序在转发消息之前仅将其记入日志或进行其他记录(例如,打印出来),那么这很有用,并且意味着被转发消息保留了一些有用的消息属性,如 JMSCorrelationID、JMSReplyTo 和 JMSType 属性。
- 转发应用程序可修改或替换消息有效内容。如果它替换有效内容,那么它会在消息对象中设置新有效内容并将有效内容引用更改为指向新消息有效内容。
- 对于转发应用程序,使用者连接工厂或激活规范会“创建”并配置被转发消息。生产者连接工厂仅用于路由被转发消息,对被转发消息的内容没有任何影响。
下表描述影响您设置“通过引用传递消息有效内容”属性的方式的 4 个转发应用程序使用方案。请注意,因为生产者连接工厂对被转发消息的内容没有任何影响,所以应对使用者连接工厂或激活规范设置使用者属性及生产者/转发者属性。
转发应用程序使用方案 | consumerDoesNotModify |
producerDoesNotModify forwarderDoesNotModify |
---|---|---|
方案 1:应用程序接收消息,查看有效内容但不进行修改,然后转发该消息而不修改或替换有效内容。 | 已启用 | 并非必需,但可启用 |
方案 2:应用程序接收消息,查看有效内容但不进行修改,将消息中的有效内容替换为新有效内容,并在调用后转发该消息而不修改有效内容以将其设置到消息中。 | 已启用 | 已启用 |
方案 3:应用程序接收消息,查看并修改有效内容,然后将已修改有效内容或某些其他数据设置回消息中,并在调用后转发该消息而不进一步修改有效内容以将其设置到消息中。 | 未启用 | 已启用 |
方案 4:应用程序接收消息,查看并修改有效内容,然后将已修改有效内容或某些其他数据设置回消息中,并在调用后进一步修改有效内容以将其设置到消息中。 | 未启用 | 未启用 |
对于方案 1、方案 2 和方案 3,可启用一个或多个“通过引用传递消息有效内容”属性,只要转发应用程序可保证按方案中所述执行操作。为帮助您实现此目标,下面提供了一些示例代码,可改写这些代码以在您的应用程序中使用。
转发应用程序:方案 1
应用程序接收消息,查看有效内容但不进行修改,然后转发该消息而不修改或替换有效内容。
public void onMessage (Message message)
{
ObjectMessage oMessage = (ObjectMessage) message;
DataObject data = oMessage.getObject();
System.out.print(data.getXXX());
System.out.print(data.getYYY());
// get a session to forward on the received message
producer.send(message);
session.close();
}
转发应用程序:方案 2
应用程序接收消息,查看有效内容但不进行修改,将消息中的有效内容替换为新有效内容,并在调用后转发该消息而不修改有效内容以将其设置到消息中。
public void onMessage (Message message)
{
ObjectMessage oMessage = (ObjectMessage) message;
DataObject data = oMessage.getObject();
System.out.print(data.getXXX());
System.out.print(data.getYYY());
// get a session to forward on the received message
message.setObject(newData);
producer.send(message);
session.close();
}
对于字节消息,应用程序还必须保证仅将单个完整字节数组写至消息。byte [] data = myByteData;
BytesMessage message = session.createBytesMessage();
message.writeBytes(data);
data = null;
producer.send(message);
转发应用程序:方案 3
应用程序接收消息,查看并修改有效内容,然后将已修改有效内容或某些其他数据设置回消息中,并在调用后转发该消息而不进一步修改有效内容以将其设置到消息中。
public void onMessage (Message message)
{
ObjectMessage oMessage = (ObjectMessage) message;
DataObject data = oMessage.getObject();
System.out.print(data.getXXX());
System.out.print(data.getYYY());
// get a session to forward on the received message
data.setXXX(xxx);
data.setYYY(yyy);
message.setObject(data);
producer.send(message);
session.close();
}
对于字节消息,应用程序还必须保证仅将单个完整字节数组写至消息。byte [] data = myByteData;
BytesMessage message = session.createBytesMessage();
message.writeBytes(data);
data = null;
producer.send(message);