日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

java 配置jmstemplate_Spring JMSTemplate 与 JMS 原生API比较

發布時間:2025/3/15 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 配置jmstemplate_Spring JMSTemplate 与 JMS 原生API比较 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JMSUtil與Spring JmsTemplate的對比

Author:信仰

Date:2012-4-20

未完待續,截止日期2012-4-20

從以下幾方面比較JMSUtil和Spring JmsTemplate

l??對JNDI的支持

l??對ConnectionFactory、Connection、Destination、Session、MessageProducer、MessageConsumer對象的處理

l??對事務的處理

l??不同類型的消息處理

l??異常處理

Spring

JMSUtil

對JNDI的支持

支持,可配置,可編碼

支持,只能編碼

對ConnectionFactory、

Connection、

Destination、

Session、

MessageProducer、

MessageConsumer對象的處理

配置

編碼

對事務的處理

配置

編碼

對不同類型消息處理

自動轉換

編碼轉換

異常處理

運行時異常,無需寫try…catch

檢查異常,必須寫try…catch

1.???對JNDI的支持

兩者都支持JNDI和非JNDI方式。兩者的JNDI名稱都是在XML中配置完成的,這一點上兩者不存在誰更有優勢。

1.1.?Spring對JNDI的支持

1.1.1.????Spring JMS?實現

JNDI查詢的JNDI模板配置

com.ibm.websphere.naming.WsnInitialContextFactory

iiop://127.0.0.1:2813/

通過JNDI配置JMS連接工廠

class="org.springframework.jndi.JndiObjectFactoryBean">

MQ_JMS_MANAGER

JMS模板配置

false

20000

把JmsTemplate綁定到應用程序中

用JmsTemplate發送JMS消息的JMSSender

public class JMSSender

{

private JmsTemplate102 jmsTemplate102;

public JmsTemplate102 getJmsTemplate102()

{

return jmsTemplate102;

}

public void setJmsTemplate102(JmsTemplate102 jmsTemplate102)

{

this.jmsTemplate102 = jmsTemplate102;

}

public void sendMesage()

{

jmsTemplate102.send("JMS_RequestResponseQueue", new MessageCreator()

{

public Message createMessage(Session session) throws JMSException

{

return session.createTextMessage("This is a sample message");

}

});

}

}

用JmsTemplate檢索JMS消息的JMSReceiver(同步接收)

public class JMSReceiver

{

private JmsTemplate102 jmsTemplate102;

public JmsTemplate102 getJmsTemplate102()

{

return jmsTemplate102;

}

public void setJmsTemplate102(JmsTemplate102 jmsTemplate102)

{

this.jmsTemplate102 = jmsTemplate102;

}

public void processMessage()

{

Message msg = jmsTemplate102.receive("JMS_RequestResponseQueue");

try

{

TextMessage textMessage = (TextMessage) msg;

if ( msg != null )

{

System.out.println(" Message Received -->" + textMessage.getText());

}

}

catch ( Exception e )

{

e.printStackTrace();

}

}

}

1.2.?JMSUtil對JNDI的支持

1.2.1.????JMSUtil的實現

XML配置:

${jms.logQueueConFactory}

${jms.errLogQueueName}

0

1

JMSUtil中發送消息報文和對象報文的方法:

public?static?void?putTextMessage(MsgData?msgData,?boolean?transacted)?throwsMessageException

{

……

ConnectionFactory connectionFactory =?null;

Connection connection =?null;

Session session =?null;

Destination destination =?null;

MessageProducer messageProducer =?null;

try

{

connectionFactory = (ConnectionFactory)

LocalContext.lookup(msgData.getQcfName(),?true);

destination = (Destination) LocalContext.lookup(msgData.getOutputQ,?false);

connection = connectionFactory.createConnection();

session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);

messageProducer = session.createProducer(destination);

//?修改為 二進制 ,字符集為可配置項,缺省為?GBK

BytesMessage message = session.createBytesMessage();

if?(msgData.getExpirationTime() !=?null)

{

messageProducer

.setTimeToLive(msgData.getExpirationTime().longValue());

}

……

message

.writeBytes(msgData.getMsg()

.getBytes(MtoFactory.getInstance().getCharsetName()));

}

catch?( JMSException e1 )

{

String errorMsg = "發送消息失敗:錯誤碼" + e1.getErrorCode() + ",錯誤原因:" + e1.getMessage();

……

}

catch?(NamingException e1)

{

String errorMsg =?"發送消息失敗,查找對應的資源未找到,錯誤原因:"?+ e1.getMessage();

……

}

catch?( UnsupportedEncodingException ue )

{

String errorMsg =?"發送消息失敗,不支持的字符集: "?+ MtoFactory.getInstance().getCharsetName();

log.error(errorMsg, ue);

throw?new?MessageException(errorMsg, ue);

}

catch?(RuntimeException e)

{

String errorMsg =?"發送消息失敗:"?+ e.getMessage();

……

}

finally

{

if?( connection !=?null)

{

if( messageProducer !=?null)

{

try

{

messageProducer.close();

}

catch?( JMSException e2 )

{

log.error("關閉messageProducer異常", e2);

}

}

if( session !=?null)

{

try

{

session.close();

}

catch?( JMSException e2 )

{

log.error("關閉session異常", e2);

}

}

try

{

connection.close();

}

catch?( JMSException e2 )

{

log.error("關閉connection異常", e2);

}

}

}

}

/**

*?發送一條對象報文,將一個對象放入隊列中

*

*?@param?qcfName

*????????????連接工廠名

*?@param?outputQ

*????????????隊列名

*?@param?obj

*????????????要發送的對象

*?@param?transacted?是否參與事務

*?@throws?MessageException

*/

public?static?void?putObjectMessage(String qcfName, String outputQ, Serializable obj,boolean?transacted)?throws?MessageException

{

ConnectionFactory connectionFactory =?null;

Connection connection =?null;

Session session =?null;

Destination destination =?null;

MessageProducer messageProducer =?null;

try

{

connectionFactory = (ConnectionFactory) LocalContext.lookup(qcfName,?true);

destination = (Destination) LocalContext.lookup(outputQ,?false);

connection = connectionFactory.createConnection();

session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);

messageProducer = session.createProducer(destination);

ObjectMessage objmsg = session.createObjectMessage(obj);

objmsg.setJMSType("transfer");

messageProducer.send(objmsg);

}

catch?( JMSException e1 )

{

String errorMsg = "發送消息失敗:錯誤碼" + e1.getErrorCode() + ",錯誤原因:" + e1.getMessage();

……

}

catch?(NamingException e1)

{

String errorMsg =?"發送消息失敗,查找對應的資源未找到,錯誤原因:"?+ e1.getMessage();

……

}

catch?( UnsupportedEncodingException ue )

{

String errorMsg =?"發送消息失敗,不支持的字符集: "?+ MtoFactory.getInstance().getCharsetName();

log.error(errorMsg, ue);

throw?new?MessageException(errorMsg, ue);

}

catch?(RuntimeException e)

{

String errorMsg =?"發送消息失敗:"?+ e.getMessage();

……

}

finally

{

if?( connection !=?null)

{

if( messageProducer !=?null)

{

try

{

messageProducer.close();

}

catch?( JMSException e2 )

{

log.error("關閉messageProducer異常", e2);

}

}

if( session !=?null)

{

try

{

session.close();

}

catch?( JMSException e2 )

{

log.error("關閉session異常", e2);

}

}

try

{

connection.close();

}

catch?( JMSException e2 )

{

log.error("關閉connection異常", e2);

}

}

}

}

2.??對ConnectionFactory、Connection、Destination、Session、MessageProducer、MessageConsumer的處理

Spring對打開和關閉連接的處理由容器控制,而JMS打開和關閉連接的處理由應用來控制。

2.1.?JMSUtil對上述對象的處理

關閉上述對象:

finally

{

if?( connection !=?null)

{

if( messageProducer !=?null)

{

try

{

messageProducer.close();

}

catch?( JMSException e2 )

{

log.error("關閉messageProducer異常", e2);

}

}

if( session !=?null)

{

try

{

session.close();

}

catch?( JMSException e2 )

{

log.error("關閉session異常", e2);

}

}

try

{

connection.close();

}

catch?( JMSException e2 )

{

log.error("關閉connection異常", e2);

}

}

}

3.???對事務的處理

3.1.?Spring JMSTemplate對事物的處理方式

3.1.1.????本地事務

Spring為JMS提供了本地事務管理的能力,JMS事務管理器和數據庫事務管理器都是PlatformTransactionManager接口的實現類,Spring的org.springframework.jms.connection包提供了用于管理JMS本地事務JmsTransactionManager事務管理器,JMS1.0.2則對應JmsTransactionManager102。

class=”org.springframework.jms.connection.JmsTransactionManager”>

在進行標準的Spring事務配置后,就能夠管理那些基于JmsTemplate編寫的JMS處理類。對于那些未基于JmsTemplate編寫的JMS處理類,可以讓消息監聽器容器對它們進行事務管理。DefaultMessageListenerContainer和ServerSessionMessageListenerContainer都支持通過消息監聽器使用JMS事務,不過必須為他們提供一個事務管理器,如下配置:

class=”org.springframework.jms.connection.JmsTransactionManager”>

class=”org.springframeword.jms.listener.DefaultMessageListenerContainer”>

3.1.2.????JTA事務

啟用JTA事務后,用戶可以讓數據庫操作、JMS操作以及其它符合JTA標準的操作工作在同一個全局事務中。

對于JMS來說,用戶必須從Java EE的JNDI中獲取XA支持的JMS ConnectionFactory。

對于Spring配置來說,JTA全局事務和本地事務的差別并不大,用戶只需要聲明一個JtaTransactionManager事務管理器,將事務委托給Java EE應用服務器就可以了。當然,ConnectionFactory必須使用XA支持的JMSConnectionFactory。

下面是讓一個數據源和一個JMSConnectionFactory工作于同一個JTA事務的具體配置:

class=”org.springframework.transaction.jta.JtaTransactionManager”/>

3.2.?JMSUtil對事物的處理方式

3.2.1.????本地事務

在Session可以控制交易,首選Session要定義成transacted,然后通過調用commit或rollback來提交或者回滾事務。

QueueSession queueSession

= connection.createQueueSession(boolean transacted, int acknowledgeMode);

TopicSession topicSession

= connection.createTopicSession(Boolean transacted, int acknowledgeMode);

Session.commit();

Session.rollback()

注意:如果transacted = true,則acknowledgeMode的值便無關緊要。

3.2.2.????JTA事務

還不太了解……

4.???不同類型的消息的處理

JMS有多鐘類型的消息:

l??javax.jms.TextMessage

l??javax.jms.MapMessage

l??javax.jms.ObjectMessage

l??javax.jms.BytesMessage

4.1.?Spring使用消息轉換器發送/接收消息

Spring將POJO和JMS消息的雙向轉換工作抽象到MessageConverter中,在JmsTemplate中提供了幾個convertAndSend()和receiveAndConvert()方法,這些方法自動使用MessageConverter完成消息的轉換工作。

4.1.1.????消息轉換器

在org.springframework.jms.support.converter包中,Spring提供了消息轉換器的支持,首先看一下MessageConverter接口的兩個方法:

l??Object fromMessage(Message message)

l??Message toMessage(Object object, Session session)

MessageConverter接口的目的是為了向調用者屏蔽JMS細節,在JMS之上搭建的一個隔離層,這樣調用者可以直接發送和接收POJO,而不是發送和接收JMS相關消息,調用者的程序將得到進一步簡化。

JMS消息類型

POJO類型

javax.jms.TextMessage

String

javax.jms.MapMessage

java.util.Map

javax.jms.ObjectMessage

java.io.Serializable

javax.jms.BytesMessage

byte[] bytes

當轉換發生錯誤時,Spring將拋出MessageConversionException異常,該異常是org.springframework.jms.JmsException的子類。

JmsTemplate和JmsTemplate102分別使用SimpleMessageConverter和SimpleMessageConverter102作為默認的消息轉換器。用戶也可以通過實現MessageConverter定義自己的消息轉換器,并在配置JmsTemplate時通過messageConverter屬性指定自己的消息轉換器。

4.1.2.????發送POJO消息

4.1.2.1.???????將POJO簡單地映射為Message對象發送

假設User是一個POJO,其結構如下:

package com.baobaotao.domain;

……

public class User?implement Serializable

{

private String username;

private String userId;

private String email;

private int level;

//?省略get/setter

}

這個POJO必須實現Serializable接口,以便可以將對象序列化后作為消息發送,除此以外沒有任何其他的要求。

將User作為JMS消息發送的操作僅需要一行簡單的代碼就可以完成:

package com.baobaotao.jms;

……

import com.baobaotao.domain.User;

public class MessageSender extends JmsGatewaySupport

{

……

public void sendUserMsg(User user)

{

//發送User對象

super.getJmsTemplate.convertAndSend(“userMsgQ”, user);

}

}

JmsTemplate提供了幾個重載版本的convertAndSend()方法:

l??convertAndSend

public void convertAndSend(Object?message)

Send the given object to the default destination, converting the object to a JMS message with a configured MessageConverter.

This will only work with a default destination specified!

Specified by:

Parameters:

message?- the object to convert to a message

Throws:

JmsException?- converted checked JMSException to unchecked

l??convertAndSend

public void convertAndSend(Destination?destination,

Object?message)

Send the given object to the specified destination, converting the object to a JMS message with a configured MessageConverter.

Specified by:

Parameters:

destination?- the destination to send this message to

message?- the object to convert to a message

Throws:

JmsException?- converted checked JMSException to unchecked

l??convertAndSend

public void convertAndSend(String?destinationName,

Object?message)

Send the given object to the specified destination, converting the object to a JMS message with a configured MessageConverter.

Specified by:

Parameters:

destinationName?- the name of the destination to send this message to (to be resolved to an actual destination by a DestinationResolver)

message?- the object to convert to a message

Throws:

JmsException?- checked JMSException converted to unchecked

l??convertAndSend

public void convertAndSend(Object?message,

Send the given object to the default destination, converting the object to a JMS message with a configured MessageConverter. The MessagePostProcessor callback allows for modification of the message after conversion.

This will only work with a default destination specified!

Specified by:

Parameters:

message?- the object to convert to a message

postProcessor?- the callback to modify the message

Throws:

JmsException?- checked JMSException converted to unchecked

l??convertAndSend

public void convertAndSend(Destination?destination,

Object?message,

Send the given object to the specified destination, converting the object to a JMS message with a configured MessageConverter. The MessagePostProcessor callback allows for modification of the message after conversion.

Specified by:

Parameters:

destination?- the destination to send this message to

message?- the object to convert to a message

postProcessor?- the callback to modify the message

Throws:

JmsException?- checked JMSException converted to unchecked

l??convertAndSend

public void convertAndSend(String?destinationName,

Object?message,

Send the given object to the specified destination, converting the object to a JMS message with a configured MessageConverter. The MessagePostProcessor callback allows for modification of the message after conversion.

Specified by:

Parameters:

destinationName?- the name of the destination to send this message to (to be resolved to an actual destination by a DestinationResolver)

message?- the object to convert to a message.

postProcessor?- the callback to modify the message

Throws:

JmsException?- checked JMSException converted to unchecked

4.1.2.2.???????將POJO映射為Message后進行后置處理

通過以上方法發送POJO,JmsTemplate僅會按照簡單的映射方式發送JMS消息,如果我們需要在此基礎上進一步設置Message的Header和Properties部分的值,一種方法是編寫自己的消息轉換器達到目的,還有一種更好的方法是使用Spring的org.springframework.jms.core.MessagePostProcessor回調接口。JmsTemplate在使用MessageConverter將POJO轉換為JMS消息后以及發送消息前,將調用MessagePostProcessor對JMS消息進行后置加工處理。因此,我們有機會通過一個自定義的MessagePostProcessor回調接口對JMS消息對象進行“修正性”工作。

下面,我們在User轉換為ObjectMessage后,為消息對象指定過期時間并設置一個屬性:

package com.baobaotao.jms;

……

import org.springframework。jms.core.MessagePostProcessor;

public class MessageSender extends JmsGatewaySupport

{

public void sendUserMsg2(final User user)

{

getJmsTemplate().convertAndSend(“userMsgQ”,

user,

new MessagePostProcessor()

{

public Message postProcessMessage(Message message) throws JMSException

{

message.setJMSExpiration(System.currentTimeMillis() + 60 * 60 * 1000); //設置過期時間:一小時后過期

message.setIntProperty(“level”, user.getLevel()); //?設置一個屬性

}

});

}

}

4.1.3.????接收POJO消息

4.2.?JMSUtil必須直接實例化不同類型的消息對象

4.2.1.????發送消息

例如,如果要發送的消息是javax.jms.TextMessage類型,代碼如下所示:

TextMessage txtMsg = queueSession.createTextMessage(obj);

messageProducer.send(txtMsg);

4.2.2.????接收消息

例如,如果要接收的消息是javax.jms.TextMessage類型,代碼如下所示:

Message m = messageConsumer.receive(1000 * 1);

if ( m instanceof TextMessage )

{

TextMessage textMessage = (TextMessage) m;

System.out.println(textMessage.getText());

}

5.???異常處理

5.1.?Spring JmsTemplate?運行時異常

JMS的異常都是檢查型異常,使用原生JMS API,用戶需要提供繁瑣的異常捕獲代碼。而Spring將檢查型異常轉化為運行期異常。

Spring在org.springframework.jms包為javax.jms包中所有的異常類提供了類型轉換的鏡像實現。如:org.springframework.jms.IllegalStateException對應javax.jms.IllegalStateExceptipn;org.springframework.jms.InvalidClientIDException對應javax.jms.InvalidClientIDException等。Spring中所有JMS相關的異常都繼承于JmsException類。

此外,Spring還提供了一些特定的JMS異常類:

l??DestinationResolutionException:Spring允許通過簡單的字符串指定消息地址,DestinationResolver在解析消息地址發生錯誤時拋出異常;

l??SynchedLocalTransactionFailedException:如果在同步本地事務發生異常時拋出該異常,由于事務已經結束后,再次嘗試同步事務時會發生這個異常;

l??UncategorizedJmsException:任何未被歸類的其他類型一場。

5.2.?JMSUtil檢查異常

總結

以上是生活随笔為你收集整理的java 配置jmstemplate_Spring JMSTemplate 与 JMS 原生API比较的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。