1. 程式人生 > >J2EE容器的理解 -- 讓Spring JMS使用WebSphere的執行緒池

J2EE容器的理解 -- 讓Spring JMS使用WebSphere的執行緒池

記得幾個月前在解決一個SSL Handshake問題後感悟到WAS是一個J2EE容器的含義,近期的一個事情又加深了我對“容器”一詞的感受。

專案的背景是用微服務架構重構一個十多年前開發的基於WAS的一個J2EE應用時。在重構過程中需要暫時性在該WAS應用上增加一個MQ進行偵聽器,無需多想兩種解決方案就浮現出來:傳統過時的MDB(Message Driven Bean)和Spring JMS Container。對於以年輕人為主的團隊來說,EJB無論如何都不會成為首選,畢竟那是十年前的技術流派了,大家只是聽說過。所以自然而然地選擇了後者–Spring JMS Container。

線上線下關於Spring的資料很豐富,所以實現一個需要的JMS Listener Container是很順利的,最後就只剩下一個事務問題待解決。WebSphere提供了JTA的實現, 而Spring的事務管理器介面很簡單,但是由於這是一個改造專案,業務邏輯很複雜,並且程式碼運行了很多年,所以任何一點程式碼改動都可能造成業務問題,結果就只能最大限度的保留現有程式碼。而該程式碼是原來是一個EJB(MDB)的一部分,通過EJB容器來獲取一個JTA事務的,在把該程式碼移植到基於Spring的JMS Container時,我們僅僅把獲取事務管理器的程式碼改成了通過JNDI來獲取一個WebSphere上的JTA例項。一切看起來都是水到渠成。

但是部署到WebSphere上執行的時候卻碰到了問題,錯誤提示該執行緒不是在WebSphere下的執行緒無法獲取JNDI物件。問題來了,我們的應用不是部署在WebSphere上的嗎?什麼叫執行緒不在WebSphere裡?這個問題一下子刺激了“WebSphere是容器”的理解,根本原因就是我們用的Spring的JMS Container是由Spring通過java執行緒池方式來建立的執行緒,這些執行緒是直接通過Java標準API建立的直接執行在JVM上的,對WebSphere而言是透明的,正是由於它不是執行在WebSphere的容器裡,WebSphere容器本身的資源和服務對它也是透明的。明白了這個之後,解決辦法就很簡單了,在Spring裡配置一下執行緒池,讓它用WebSphere的執行緒池,比如wm/default。簡單改動之後重新部署,問題解決。

補記:
關於J2EE容器的理解也讓另一個問題的解決有了新的思路。