Java EE 7:带有Glassfish v4的JMS 2.0
Java EE 7最近已被執(zhí)行委員會接受 。 這意味著我們很快將在市場上提供Java EE 7應(yīng)用服務(wù)器。 構(gòu)成Java EE 7的規(guī)范之一是JMS 2.0 。 自1.1版以來,引入了一些有趣的改進(jìn)。
JMS有很多怪異的東西,例如: Connection#createSession(boolean Transacted,int acceptMode)方法。
第一個方法參數(shù)( transacted )定義是否應(yīng)處理會話。 Java EE應(yīng)用程序具有負(fù)責(zé)事務(wù)處理的JTA。 我們可以選擇是否支持交易(默認(rèn))。 那么,為什么我們需要這個論點呢?
第二個方法參數(shù)( acknowledgeMode )是一個從Session對象獲取的整數(shù)常量 。 認(rèn)真地說,整數(shù)常量使該API看起來太過傳統(tǒng)。 最后,Java EE環(huán)境中這些參數(shù)的含義是什么? JavaDoc的說, acknowledgeMode如果會話事務(wù)被忽略。
這是什么意思? 不外乎: 這些參數(shù)對于Java EE上下文中使用的JMS生產(chǎn)者沒有任何意義 。 這就是為什么他們鼓勵您使用(true, 0)參數(shù)值以避免不必要的混淆的原因。 這聞起來有遺味。
好的,讓我們回到主要主題。 我想看一下JMS世界中的新功能,以及它如何使我能夠更輕松,更可維護(hù)的方式進(jìn)行編碼。 我已經(jīng)準(zhǔn)備了一個使用JMS 2.0,JAX-RS和EJB(SLSB和MDB)的簡單Web應(yīng)用程序,并將其推送到這里的 github存儲庫中。
先決條件和基礎(chǔ)架構(gòu)
為了能夠運行此代碼,您應(yīng)該創(chuàng)建一個示例隊列。 我已經(jīng)在jms/queue/myqueue JNDI名稱下配置了它。
我正在使用Glassfish v4 build 87 。 要使用Java EE 7 API,我需要添加以下Maven依賴項:
<dependency><groupId>javax</groupId><artifactId>javaee-api</artifactId><version>7.0-b87</version><scope>provided</scope> </dependency>駐留在此存儲庫中:
<repository><id>Java EE 7</id><url>https://maven.java.net/content/groups/promoted/</url> </repository>這就是配置的全部內(nèi)容。
有效負(fù)載和REST配置
BusinessObject是一個簡單的對象,將充當(dāng)我們的JMS消息的有效負(fù)載。 它將由生產(chǎn)者發(fā)送并由消費者接收。 這里沒什么好想的,所以讓我們繼續(xù)前進(jìn)。 RESTConfiguration甚至更簡單–它只是為我們的應(yīng)用程序定義了JAX-RS端點前綴。 該前綴是:“ / rest”。 您可以通過訪問應(yīng)用程序URL / rest / producer / jms11或/ rest / producer / jms20(例如http://localhost:8080/jms2_0_spike/rest/producer/jms20 )來調(diào)用生產(chǎn)者EJB。
JMS生產(chǎn)者
現(xiàn)在,這里開始變得有趣。 在下面,您可以找到SLSB JMS消息產(chǎn)生器的JMS 1.1代碼:
@Stateless public class JMS11Producer {@Resource(lookup = "jms/__defaultConnectionFactory")private ConnectionFactory connectionFactory;@Resource(lookup = "jms/queue/myqueue")private Queue queue;@Path("/jms11")@GETpublic String produce() {String status = "OK";Connection connection = null;try {connection = connectionFactory.createConnection();Session session = connection.createSession(true, 0);MessageProducer producer = session.createProducer(queue);BusinessObject payload = new BusinessObject(UUID.randomUUID().toString());ObjectMessage message = session.createObjectMessage();message.setObject(payload);producer.send(message);} catch (JMSException e) {status = e.getMessage();} finally {if (connection != null) {try {connection.close();} catch (JMSException e) {status = e.getMessage();}}}return status;} }盡管JAX-RS結(jié)果狀態(tài)出現(xiàn)問題,但這是一個令人費解的樣板代碼,模糊了方法的主要職責(zé)。 它應(yīng)該只向隊列發(fā)送一條消息,但是它卻做了很多事情。 它會創(chuàng)建一個連接,會話(包括討厭的,忽略的參數(shù)在內(nèi)),對象類型的消息,將其初始化,然后最終將消息發(fā)送到隊列中……哦,是的–當(dāng)然,不要忘記檢查異常和嵌套的try / catch塊。 我們可以嘗試去優(yōu)化它-通過創(chuàng)建連接移動到一些如@PostConstruct方法和關(guān)閉,以@PreDestroy -但它仍然有很多unnecesary噪音。
現(xiàn)在,讓我們看一下功能上與JMS 2.0中表達(dá)的代碼相同的代碼:
@Stateless public class JMS20Producer {@Resource(lookup = "jms/queue/myqueue")private Queue queue;@Injectprivate JMSContext jmsContext;@Path("/jms20")@GETpublic String produce() {BusinessObject payload = new BusinessObject(UUID.randomUUID().toString());jmsContext.createProducer().send(queue, payload);return "OK";} }很整潔吧? 弄清楚此方法的作用要容易得多:它創(chuàng)建有效負(fù)載并將其發(fā)送到隊列。 就這樣–這就是方法的全部內(nèi)容。 異常處理,連接和會話創(chuàng)建,消息類型–一切都為我們完成。 如果可以將這些職責(zé)轉(zhuǎn)移到容器上以減輕開發(fā)人員的生活負(fù)擔(dān),那么為什么不這樣做呢?
讓我們看一下此示例中使用的一些JMS 2.0功能:
- 不需要ConnectionFactory ,
- 無需Connection或Session ,
- JMSContext是結(jié)合了Connection和Session功能的新對象。 它可以通過容器注入,
- 沒有檢查的異常–僅JMSRuntimeException ,
- 用于消息生成的鏈調(diào)用使其更易于閱讀。
JMS消費者
自JMS 1.1以來,Message Consumer并未發(fā)生太大變化。 它仍然是MDB,但是現(xiàn)在由于使用message.getBody(Clazz)進(jìn)行消息投射,更容易達(dá)到預(yù)期的有效負(fù)載:
@MessageDriven(mappedName = "jms/queue/myqueue") public class Consumer implements MessageListener {@Overridepublic void onMessage(Message message) {try {// In JMS 1.1:// ObjectMessage objectMessage = (ObjectMessage)message;// BusinessObject payload = (BusinessObject)objectMessage.getObject();BusinessObject payload = message.getBody(BusinessObject.class);System.out.println("Message received: " + payload);} catch (JMSException e) {System.err.println("Error while fetching message payload: " + e.getMessage());}} }結(jié)論
這只是對JMS 2.0的快速瀏覽。 但是,我發(fā)現(xiàn)有趣的是,與JMS 1.1相比,可以產(chǎn)生多少更清晰的代碼。 有關(guān)JMS 2.0的更多詳細(xì)信息,請查看其正式規(guī)范 。
翻譯自: https://www.javacodegeeks.com/2013/05/java-ee-7-jms-2-0-with-glassfish-v4.html
總結(jié)
以上是生活随笔為你收集整理的Java EE 7:带有Glassfish v4的JMS 2.0的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解谜安卓游戏(解谜安卓)
- 下一篇: 主管部门是什么意思 主管部门的含义