【问题标题】:Read large XSLT string in Parallel并行读取大型 XSLT 字符串
【发布时间】:2018-04-24 22:49:05
【问题描述】:

我有一个很大的 XSLT 字符串,用于将 XML 转换为 json。我在 dropwizard web 服务中执行此操作,其中非常需要并发性。当我将此 XSLT 字符串存储在一个文件中时,它会导致所有 Web 服务线程从文件系统按顺序访问该文件(从而延迟执行)。

如果我尝试将该 XSLT 存储为 java 字符串,则会收到 constant string too long 异常。我可以存储此 XSLT 以便我的线程可以并行访问它的最佳方式是什么?

【问题讨论】:

    标签: java file xslt parallel-processing


    【解决方案1】:

    如果 XSLT 源真的那么大,您可能应该将它存储在一个文件中,例如作为类路径资源,并且只加载和解析一次:

    private static Templates largeTemplate;
    

    使用初始化(仅一次):

    try (InputStream in = Test.class.getResourceAsStream("path/to/large.xslt")) {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        largeTemplate = transformerFactory.newTemplates(new StreamSource(in));
    }
    

    然后对于每个线程:

    Transformer transformer = largeTemplate.newTransformer();
    // Use transformer here
    

    【讨论】:

    • 我通常不会将 Templates 对象置于静态;这意味着你在 JVM 中只能有一个实例。
    • @MichaelKay 这就是重点。预解析 XSLT 文件的单个共享实例,因此系统不必在每次需要时重新解析它。既然这也是你所说的(“保存编译的样式表”),我不知道你的评论应该是什么意思。
    • 关于何时使用静态模式与单例模式比较合适,有很多讨论,例如这里:stackoverflow.com/questions/24214148/java-getinstance-vs-static,我不想在这里进行辩论,只是说我除非它是一个简单的单次应用程序,否则将始终使用单例模式。
    • @MichaelKay 我对您的第一条评论感到困惑。单例模式还将单例存储在一个静态字段中,就其本质而言,JVM 中只有一个单例实例。所以,说你不会使用static,这意味着你在JVM 中只能有一个实例,那么,是的,这就是重点。如果你的意思是说我应该使用单例模式,那么你应该这样说,但第一条评论毫无意义,尤其是后半部分。
    【解决方案2】:

    您不希望多次编译同一个大型 XSLT 文件,即使多个编译是并行完成的。在 Web 服务初始化期间或在第一次引用时对其进行编译,并保存已编译的样式表(如果您使用 JAXP,则为模板对象),以便可以将其重用于多个转换。 Templates 对象是线程安全的,因此使用此样式表的多个转换可以同时运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-12
      • 2020-03-16
      • 2010-11-08
      • 2014-08-16
      • 1970-01-01
      • 2021-12-26
      • 2015-06-24
      • 1970-01-01
      相关资源
      最近更新 更多