2016-05-15 84 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

相关问题