通过引用传递消息有效内容:转发应用程序的使用方案和示例代码

JMS 转发者应用程序接收消息(通过连接工厂,或者如果该应用程序是消息驱动的 bean,那么通过激活规范),然后将消息对象发送至另一目标。 浏览不同的使用方案,然后对 JMS 转发应用程序进行编码,以便在将消息从一个队列转发到单个服务器中的另一个队列时,可以通过引用安全地传递消息有效内容。

发送大型对象消息或字节消息时,序列化、反序列化和复制消息有效内容的内存和处理器使用成本可能会很高。 如果在连接工厂或激活规范上启用 pass message payload by reference 属性,请告知缺省消息传递提供程序覆盖 JMS 1.1 规范,并可能减少或绕过此数据复制。

在下图中,消息通过使用者激活规范或连接工厂从消息传递引擎上的 queue1 传递至 JMS 转发应用程序。 然后消息会通过生产者连接工厂转发至同一消息传递引擎上的 queue2。

警告:
将定义这些属性所绕过的 JMS 规范的一部分,以确保消息数据完整性。 使用这些属性的任何 JMS 应用程序必须严格遵循所描述的规则,否则会有丧失数据完整性的风险。
图 1。 转发消息
该图显示了从一个队列到另一个队列的消息流。 通过使用者激活规范或连接工厂属性,消息从 queue1
传递至 JMS 转发应用程序。 从 JMS 转发应用程序中,然后通过生产者连接工厂属性将消息转发到 queue2 。
要了解本主题中给出的使用方案和关联示例代码,必须注意 JMS 转发应用程序的下列重要特征:
  • 转发应用程序不会替换消息对象。 如果应用程序在转发消息之前仅将其记入日志或进行其他记录(例如,打印出来),那么这很有用,并且意味着被转发消息保留了一些有用的消息属性,如 JMSCorrelationIDJMSReplyToJMSType 属性。
  • 转发应用程序可修改或替换消息有效内容。 如果它替换有效内容,那么它会在消息对象中设置新有效内容并将有效内容引用更改为指向新消息有效内容。
  • 对于转发应用程序,将 创建 转发的消息并由使用者连接工厂或激活规范进行配置。 生产者连接工厂仅用于路由被转发消息,对被转发消息的内容没有任何影响。

下表描述了影响您设置 pass message payload by reference 属性的方式的四个转发应用程序使用方案。 请注意,因为生产者连接工厂对被转发消息的内容没有任何影响,所以应对使用者连接工厂或激活规范设置使用者属性及生产者/转发者属性。

表 1. pass message payload by reference 属性设置对转发应用程序使用方案的影响 此表的第一列列示 4 个转发应用程序使用方案。 第二列指示这些方案的使用者属性设置。 第三列指示这些方案的连接工厂或激活规范属性设置。
转发应用程序使用方案 consumerDoesNotModify PayloadAfterGet 属性设置 producerDoesNotModify PayloadAfterSet(for连接工厂)或 forwarderDoesNotModify PayloadAfterSet (用于激活规范)属性设置
方案 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);