消息中间件规范JMS 2.0在编码方面做了很多改进,可以帮助开发者减少编写的代码量。下面,由我一一说明。
在JMS 1.1中是这样的:
Connection connection = ConnectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
在JMS 2.0中是这样的:
JMSContext context = connectionFactory.createContext(JMSContext.SESSIONA_TRANSACTED);
在JMS 1.1中是这样的:
try{
Connection connection = connectionFactory.createConnection();
try{
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
} finally{
connection.close();
}
} catch(JMSException ex){
ex.printStackTrace();
}
在JMS 2.0中是这样的:
try (Connection connection = connectionFactory.createConnection();) {
......
} catch(JMSException ex){
ex.printStackTrace();
}
注意,上面的代码也可改用JMSContext。
在JMS 1.1中是这样的:
Session session = connection.createSession(true,Session.SESSION_TRANSACTED);
在JMS 2.0中是这样的:
Session session = connection.createSession(Session.SESSION_TRANSACTED);
在JMS 1.1中是这样的:
// 传递的两个参数都会被忽略事务的行为由容器决定
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
在JMS 2.0中是这样的:
// JMS 2中提供了无参方法
Session session = connection.createSession();
在JMS 1.1中是这样的:
MessageProducer messageProducer = session.createProducer(domoQueue);
messageProducer.setPriority(1);
TextMessage textMessage = session.createTextMessage(body);
textMessage.setStringProperty("foo", "bar");
messageProducer.send(textMessage);
在JMS 2.0中是这样的:
TextMessage textMessage = context.createTextMessage(body);
context.createProducer().setPriority(1).setProperty("foo", "bar").send(demoQueue, textMessage);
在JMS 1.1中是这样的:
// MessageProducer开销很大,因此需要重用它
MessageProducer messageProducer = session.createProducer(demoQueue);
messageProducer.send(message1);
messageProducer.send(message2);
在JMS 2.0中是这样的:
// JMSProducer是轻量级的,无需用变量保存它
context.createProducer().send(demoQueue, message1);
context.createProducer().send(demoQueue, message2);
在JMS 1.1中是这样的:
try{
Connection connection = connectionFactory.createConnection();
try{
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(demoQueue);
TextMessage textMessage = session.createTextMessage(body);
messageProducer.send(textMessage);
} finally{
connection.close();
}
} catch(JMSException ex){
ex.printStackTrace();
}
在JMS 2.0中是这样的:
try{
context.createProducer().send(inboundQueue, body);
} catch(JMSRuntimeException ex){
ex.printStackTrace();
}
在JMS 1.1中是这样的:
// 需要创建适合类型的消息对象,再设置其Body
MessageProducer messageProducer = session.createProducer(demoQueue);
TextMessage textMessage = session.createTextMessage("Hello World");
messageProducer.send(textMessage);
在JMS 2.0中是这样的:
// 简单的传递消息Body到send方法
context.createProducer().send(demoQueue, "Hello World");
在JMS 1.1中是这样的:
// 当同步接收时,需给定消息对象,再转换为合适的子类型,再提取Body
MessageConsumer messageConsumer = session.createConsumer(demoQueue);
TextMessage textMessage = (TextMessage)messageConsumer.receive(1000);
if(textMessage==null)
return "Received null"
else
return "Received " + textMessage.getText();
在JMS 2.0中是这样的:
// JMS 2允许直接接收消息Body
JMSConsumer consumer = context.createConsumer(demoQueue);
return "Received " + consumer.receiveBody(String.class, 1000);
在JMS 1.1中是这样的:
public void onMessage(Message m){
MyObject myObj = (MyObject)((ObjectMessage)m).getObject();
...
在JMS 2.0中是这样的:
public void onMessage(Message m){
MyObject myObj = m.getBody(MyObject.class);
一、用JMSContext取代了Connection和Session对象
消息中间件规范JMS 2.0引入了一个新对象——JMSContext,它提供了原先Connection和Session对象同样的功能。在JMS 1.1中是这样的:
Connection connection = ConnectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
在JMS 2.0中是这样的:
JMSContext context = connectionFactory.createContext(JMSContext.SESSIONA_TRANSACTED);
二、利用try-with-resources块意味着无需调用close语句
在JMS 1.1中如果不调用close语句,那么或许会导致内存资源耗尽。在JMS 1.1中是这样的:
try{
Connection connection = connectionFactory.createConnection();
try{
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
} finally{
connection.close();
}
} catch(JMSException ex){
ex.printStackTrace();
}
在JMS 2.0中是这样的:
try (Connection connection = connectionFactory.createConnection();) {
......
} catch(JMSException ex){
ex.printStackTrace();
}
注意,上面的代码也可改用JMSContext。
三、在JavaSE中创建会话时无需传递两个参数
在JMS 1.1中是这样的:
Session session = connection.createSession(true,Session.SESSION_TRANSACTED);
在JMS 2.0中是这样的:
Session session = connection.createSession(Session.SESSION_TRANSACTED);
四、在JavaEE事务处理中创建会话无需传递任何参数
在JavaEE事务处理中创建会话,createSession传递的参数会被忽略掉,详见EJB 3.1规范。在JMS 1.1中是这样的:
// 传递的两个参数都会被忽略事务的行为由容器决定
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
在JMS 2.0中是这样的:
// JMS 2中提供了无参方法
Session session = connection.createSession();
五、新的JMSProducer对象支持方法链
消息中间件规范JMS 2.0引入了一个新对象——JMSProducer,他允许消息头、消息属性、交付的选项等都在单行代码中通过方法链进行指定。在JMS 1.1中是这样的:
MessageProducer messageProducer = session.createProducer(domoQueue);
messageProducer.setPriority(1);
TextMessage textMessage = session.createTextMessage(body);
textMessage.setStringProperty("foo", "bar");
messageProducer.send(textMessage);
在JMS 2.0中是这样的:
TextMessage textMessage = context.createTextMessage(body);
context.createProducer().setPriority(1).setProperty("foo", "bar").send(demoQueue, textMessage);
六、无需保存JMSProducer的变量
新的JMSPruducer对象是轻量级对象,因此无需在变量中保存它,当需要时直接实例化即可。在JMS 1.1中是这样的:
// MessageProducer开销很大,因此需要重用它
MessageProducer messageProducer = session.createProducer(demoQueue);
messageProducer.send(message1);
messageProducer.send(message2);
在JMS 2.0中是这样的:
// JMSProducer是轻量级的,无需用变量保存它
context.createProducer().send(demoQueue, message1);
context.createProducer().send(demoQueue, message2);
七、在JavaEE中,注入JMSContext意味着无需创建或关闭它
在JMS 1.1中是这样的:
try{
Connection connection = connectionFactory.createConnection();
try{
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(demoQueue);
TextMessage textMessage = session.createTextMessage(body);
messageProducer.send(textMessage);
} finally{
connection.close();
}
} catch(JMSException ex){
ex.printStackTrace();
}
在JMS 2.0中是这样的:
try{
context.createProducer().send(inboundQueue, body);
} catch(JMSRuntimeException ex){
ex.printStackTrace();
}
八、当发送消息时,无需实例化消息对象
在JMS 1.1中是这样的:
// 需要创建适合类型的消息对象,再设置其Body
MessageProducer messageProducer = session.createProducer(demoQueue);
TextMessage textMessage = session.createTextMessage("Hello World");
messageProducer.send(textMessage);
在JMS 2.0中是这样的:
// 简单的传递消息Body到send方法
context.createProducer().send(demoQueue, "Hello World");
九、同步接收,可以直接接收消息有效载荷
在JMS 1.1中是这样的:
// 当同步接收时,需给定消息对象,再转换为合适的子类型,再提取Body
MessageConsumer messageConsumer = session.createConsumer(demoQueue);
TextMessage textMessage = (TextMessage)messageConsumer.receive(1000);
if(textMessage==null)
return "Received null"
else
return "Received " + textMessage.getText();
在JMS 2.0中是这样的:
// JMS 2允许直接接收消息Body
JMSConsumer consumer = context.createConsumer(demoQueue);
return "Received " + consumer.receiveBody(String.class, 1000);
十、异步接收在提取消息Body时无需转换
在JMS 1.1中是这样的:
public void onMessage(Message m){
MyObject myObj = (MyObject)((ObjectMessage)m).getObject();
...
在JMS 2.0中是这样的:
public void onMessage(Message m){
MyObject myObj = m.getBody(MyObject.class);