本文檔是描述Smooks的應用狀況,以及使用Jaxb替換smooks的可行性分析及實施方案,有不足之處還望諒解和指出。 html
項目系統中使用Smooks出現幾回死鎖問題致使系統宕機,其後針對Smooks進行性能測試,同時,與jaxb進行了對比,發現Smooks存在嚴重的性能瓶頸的問題。 java
20個用戶併發操做的測試數據: 編程
50個用戶併發操做的測試數據: api
最終結果: 數組
一、smooks各項指標都低於jaxb 安全
二、jaxb的吞吐量變化不大,但平均處理時長多了4秒,比較穩定。 併發
注:測試過程當中包含了讀取報文的時間(即從文件中獲取報文數據,然後經過XMLBind技術進行轉換),雖然時間有所誤差,可是,不影響總體測試結果。 app
目前,有關smooks的技術框架的使用,集中在VOS系統的銷售服務層,也就是vos-app-sale-service。 框架
以下圖所示: 高併發
若是使用其餘技術好比Jaxb進行替換Smooks,能夠在此層能夠完成便可實現。其中,vos-app-sale-service層提供了每一個javabean與xml進行提供了可輸入的報文,使操做更加透明。
Smooks因爲它僅支持String的java引用類型對象,在咱們vos當中使用與xml進行綁定的Javabean的屬性都是爲java.lang.String,同時,每一個屬性的值(String類型)都不能爲null,必需要一個默認空字符"",這樣轉換過程當中纔不會報錯。這個侷限是由於Smooks自己問題而存在的,而VOS系統把這個做爲了開發規範,採用默認字符串進行屬性數據與XML綁定了。
示例代碼:
在這點來講,Jaxb相對比較靈活點。
一、Jaxb支持基本數據類型
二、支持對引用類型向基本數據類型正反的轉換好比java.util.Date,此功能須要配置jaxb的適配器完成的。
三、Jaxb對引用類型的對象(包括了String),若是屬性是引用類型,那麼若是爲null狀況,Jaxb是不會把該字段與XML進行綁定的,就是說在XML裏面看不到該字段。
對咱們來講,第三點是爭議比較多的,不一樣場景取決於不一樣的用法,怎麼使用須要根據實際狀況來判進行決策選擇。但事實上,咱們VOS中對javabean與xml轉換若是字段屬性出現null狀況,默認須要在xml打印改字段的,這個前提條件是字段類型是String。
如上圖示,劃紅線區域的是vos有關smook的config文件管理路徑。
Smooks對javabean與xml互轉的提供了最基本轉換的同時,也支持動態的轉換方式,主要體現config文件可使用模板引擎技術freemaket。
VOS中對smooks的動態支持是採用freemaket對其config進行處理完成的。
Jaxb對於動態支持是它薄弱的環節,從它自己來講,Jaxb主要是經過註解來實現JavaBean與XML的轉換。因此,對註解來講,是須要編譯然後沒法改變的。固然也可使用一些第三方包經過改變class字節碼來實現,但這個方案還沒有獲得普通應用,風險比較大。
Jaxb是靜態的支持,Jaxb須要替換Smooks須要考慮這部分移植的可能性,是否能夠經過其餘途徑來完成目的。答案是確定的,對於交換報文來講,報文本是就是靜態的,爲了更好抽象咱們業務模型,支持動態報文,是基於重用的目的,可是,從單一職責和業務模型來講,解耦是一個大問題,面向服務確定須要鬆耦合。
針對Smooks的應用狀況,從集中式管理結構和數據類型應用來講,Jaxb是實現替換Smooks是沒有問題的。但考慮到Smooks的動態支持,須要耗費一些時間開來進行動態支持轉換。從技術角度出發,是可行的。
必要考慮到風險分析:
一、其1、涉及到銷售核心模塊,任何差錯均可能引發一些大的問題。
二、其2、涉及面廣,雖然是集中,改動面積確實很大,config文件就有122個。
三、其3、技術要求更多,要求技術人員既要熟悉smooks,也要熟悉jaxb
四、其4、銷售業務開發熟悉,不容易出錯。
五、其5、須要測試人員進行迴歸測試。
Jaxb替換smooks具體實施過程,主要目標是下降風險,平滑化進行技術切換,可根據目前緊急程度,進行具體實施過程決策選擇。
具體實施過程保障:
1、須要開發人員進行smooks與jaxb的技術培訓。
2、提供jaxb相關的技術基礎設施,好比轉換工具類,數據類型適配器等。
3、兼容兩種技術,一旦出現重大狀況,須要進行回退。
具體實施建議參考:
1、以點到點就行操做,確保每一步修改都沒有問題。
2、對存在比較嚴重問題區域優先處理。
若是人數充足支持下時間的狀況下,能夠進行大範圍推土機方式進行處理,短期就能夠出結果,風險高。
若是人數很少支持下時間足夠的狀況下,能夠進行循環漸進方式進行處理,優先對主要的問題區域進行實施,這樣操做的目的,將風險降到最低,可進可退,效率高。
JAXB(Java API for XML Binding),是一個業界的標準,提供了一個快速便捷的方式將Java對象與XML進行轉換。
在JAX-WS(Java的WebService規範之一)中,JDK1.6 自帶的版本JAX-WS2.1,其底層支持就是JAXB。
JAXB 2.0 基於 JSR 175 編程註釋工具定義的程序註釋。
JAXB 2.0是JDK 1.6的組成部分。JAXB 2.2.3是JDK 1.7的組成部分。
若是使用JDK 1.5單獨下載JAXB的RI便可,JAXB不支持JDK 1.4。
Jaxb官方地址:
JaveBean必須實現java.io.Serializable序列化接口,在頭部地方必須註解@XmlRootElement。
實現對JaveBean轉換成XML的實現過程。
public static String java2xml(Object obj) { try { JAXBContext content = JAXBContext.newInstance(obj.getClass()); Marshaller m = content.createMarshaller(); StringWriter sw = new StringWriter(); m.marshal(obj, sw); return sw.toString(); } catch (Exception e) { e.printStackTrace(); } return null; }
實現對XML轉換成JaveBean的實現過程。
public static Object xml2java(String xml, Class clazz) { try { JAXBContext content = JAXBContext.newInstance(clazz); Unmarshaller m = content.createUnmarshaller(); StringReader sr = new StringReader(xml); Object t = m.unmarshal(sr); return t; } catch (Exception e) { e.printStackTrace(); } return null; }
Jaxb相關的重要的Class和Interfce。
參考文檔:
是應用的入口,用於管理XML/Java綁定信息。
將Java對象序列化爲XML數據。
將XML數據反序列化爲Java對象。
Jaxb對List或者數組是須要手動處理,否則打印出來XML格式不是咱們須要的。
新增包含List的類:
在類對象中引用包含list的類屬性:
Jaxb默認對Map進行處理,可能也不是咱們須要格式。
這個是帶Map屬性的JavaBean,可是最終結果展示不是咱們須要的。
若是學會了對象屬性進行適配器處理就能夠解決此類問題。
jaxb對java.uitl.Date進行處理,轉換時間不是中文格式,由於java.util.Date的toString()默認是西方格式。這種風格不適合中國風,也很差認識。
下面是Date打印:
2011-09-01T00:00:00-03:00
而咱們須要的是
2011-09-01 00::00:03
這時候處理以下:
JavaBean的一些屬性有時候是不須要對外進行xml綁定,這時候,咱們該怎麼處理呢?在該字段前面進行註解@XmlTransient,表示不行對字段進行xml轉換。
每每高併發系統對吞吐量要求比較要的,因此,不少XmlBind技術都必須針對不一樣狀況進行相應處理。而Jaxb當中, JAXBContext是屬於線程安全的,可是Marshaller, Unmarshaller以及Validato都是非線程安全的。
針對JAXBContext屬於線程安全的狀況下,實現單例雖然有益於性能提升,可是高併發狀況下,更容易出現問題。這種狀況下,能夠採起對象池來解決。