2016-05-15 121 views
1

目標從路徑字符串中解析Java對象樹中的字段的最有效方法是什麼?

甲模板引擎,採用一個含有多個置換位點上下文樹的文檔。替換站點的格式爲$ {someObject.someProperty},並使用類似於JavaScript的屬性訪問器的點分隔路徑表示法標識目標字段。上下文樹的POJO這樣一個簡單的層次結構:

public class ContextRoot { 
    public SomeObject someObject; 
    public OtherObject otherObject; 
} 

public class SomeObject { 
    public String someProperty; 
} 

public class OtherObject { 
    public Integer count; 
} 

像上下文根的類的實例與模板文件送入模板引擎一起和產品是一個文檔,其中所有的替換字符串中有已被他們解決的財產的價值取代。

我已經試過

目前,我們的解決方案使用JSON傑克遜向ObjectMapper我們的上下文根對象轉換成地圖。從這一點,我們使用jayway/JsonPath庫來解析由路徑引用的屬性的值。這是合作得非常好,但我已經開始擔心,這種方法的性能可能不是最優的,因爲傑克遜可能會或可能不會在上下文對象反序列化回成地圖前轉換爲中間JSON表示。

問題

我也接觸過一些解決方案建議使用本地Java反射來實現類似的目標。我對這種方法的擔憂是,我被告知從性能的角度來看反射可能是昂貴的。此外,使用這種方法滾動內部解決方案意味着我們會犧牲傑克遜的巧妙類型推導和序列化邏輯;我們不喜歡重新實現的東西。有沒有其他的方法可以建議完成這樣的事情?

更多信息

澄清一點,而我從來沒有一個雞蛋裏挑骨頭的作品,並且效果很好,這個模板引擎,同時服務於客戶端web請求所以我們運行的解決方案的性能試圖對我們的響應時間的位置敏感一點。

+0

是否有一個原因,你沒有使用開源模板引擎,這會爲你做這個? – meriton

+0

除了通常的企業政治壓力以及這臺發動機的基礎對我們來說運轉良好的事實之外,沒有任何好的*理由。這是一項我們所負責的新增功能,我們正在從中獲得完美的可接受性能,但我認爲它可能會好得多。 – DaveStance

+0

您如何看待*「傑克遜的巧妙類型演繹和序列化邏輯」*的作品?使用反射。所以你已經開始認識到思考反射性能的重要性,但是Jackson做得更多,甚至比直接使用反射還要慢。慢速部分實際上不是反射,而是解析'$ {someObject.someProperty}'表達式,以及將數據轉換爲JSON所需的數據轉換。 – Andreas

回答

3

這已經解決了很多次,在陽光下所有的Java模板引擎。因此,只需使用現有的成熟模板引擎(如FreeMarker,Velocity,JMustache,StringTemplate等)即可獲得經過良好測試的解決方案。如果由於「政治壓力」而無法實現這一目標,您可能仍然可以從實施中學習。

簡而言之:是的,反思是要走的路,這就是傑克遜做什麼,太。但是,對於高性能使用反射,它緩存MethodField對象,並禁止使用setAccessible(true)冗餘訪問檢查是很重要的。單形態呼叫站點甚至可以啓用反射訪問的內聯,但這通常很難完成,因此通常不值得。

最後,我想知道,大多數的模板引擎花費更多的時間字符串複製到該訪問模型對象的輸出是很重要的,所以它很可能你在優化您的自定義模板引擎的錯誤部分。

+0

關於訪問檢查的優秀信息和寶貴技巧。我們使用反射和行走對象層次來定位字段,但是即使緩存字段(事實證明,在單個渲染過程中很少重新訪問),我們實現了一個天真的解決方案,我們發現性能有點欠缺。 正如您正確指出的那樣,實際字段定位完全被正確地將路徑段映射到字段,正確格式化字符串化值並寫入字符串輸出的過程所淹沒。 再次感謝! – DaveStance

相關問題