gpt4 book ai didi

java - 使用 XPath 时有没有办法避免 Jaxp13XPathExpression 的瓶颈?

转载 作者:太空宇宙 更新时间:2023-11-04 06:07:15 24 4
gpt4 key购买 nike

我正在转换 Spring 托管编排服务以使用 Spring Integration 作为概念证明。

我已经运行了基本应用程序,但遇到了主要瓶颈。

应用程序使用入站网关从标准 MultivaluedMap 获取 XML 负载:

<int-http:inbound-gateway id="DSOWebServicePOC" request-channel="httpRequestsChannel" 
reply-channel="httpResponsesChannel" path="/orchestrate/do" supported-methods="POST"
payload-expression="#requestParams.getFirst(&quot;XML&quot;)">
</int-http:inbound-gateway>

然后通过直接 channel 将其发送到 xpath-splitter,该 xpath-splitter 旨在将请求(包含许多类似的子请求)分解为每个可以处理的实际请求。

应用程序的性能比原始服务慢约 6 倍,这是由于方法 org.springframework.xml.xpath.Jaxp13XPathExpressionFactory$Jaxp13XPathExpression.evaluate(Node, QName)

这是因为编译的 XPath 表达式不是线程安全的,并且 Jaxp13XPathExpression 中的方法有一个同步块(synchronized block) - 与使用单例的 Spring 结合...在原始服务中,我使用了包含编译的 XPathExressions 的本地线程。

我尝试过自定义范围但无济于事,这解释了原因

Custom Spring Scope not working for Message Channel

我遵循动态 ftp 的示例,但使用线程名称作为映射键。我已将其与包含传入 channel 、拆分器和 xpath 表达式的子应用程序上下文组合在一起,但在代码中, channel 解析器从新上下文中按名称获取 bean:

https://github.com/spring-projects/spring-integration-samples/blob/master/advanced/dynamic-ftp/src/main/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolver.java

我无法对 XPathExpression 执行此操作,因为 Jaxp13XPathExpression 是具有默认访问修饰符的抽象类中的私有(private)静态类。

如何获得具有不同作用域的已编译 XPathExpression - 无论是请求/ session /线程,而不只是创建具有本地线程的服务激活器,并且不使用框架的 XML 处理中的构建?

更多信息:

路由器:

<int:router input-channel="httpRequestsChannel" ref="channelResolver" method="resolve" />

解决方法:

public MessageChannel resolve() {
String thread = Thread.currentThread().getName();
ChannelResolverIntegrationBeans beans = this.integrationBeans
.get(thread);
if (beans == null) {
beans = createNewThreadIntegrationBeans(thread);
}
return beans.getChannel();
}

ChannelResolverIntegrationBeans 方法 - XPathExpression 是我最后一次尝试让它工作,但它返回

名为“dsoBatchRequestXPathNs”的 Bean 必须是 [javax.xml.xpath.XPathExpression] 类型,但实际上是 [org.springframework.xml.xpath.Jaxp13XPathExpressionFactory$Jaxp13XPathExpression] 类型

private synchronized ChannelResolverIntegrationBeans createNewThreadIntegrationBeans(
String thread) {
ChannelResolverIntegrationBeans beans = this.integrationBeans
.get(thread);
if (beans == null) {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] { "/xmlChildHandlerContext.xml" }, this.appContext);
MessageChannel channel = ctx.getBean("fromDynamicRouter",
MessageChannel.class);
EventDrivenConsumer splitter = ctx.getBean("requestSplitter",
EventDrivenConsumer.class);
XPathExpression expression = ctx.getBean("dsoBatchRequestXPathNs",
XPathExpression.class);
beans = new ChannelResolverIntegrationBeans(channel, splitter);
this.integrationBeans.put(thread, beans);
// Will works as the same reference is presented always
this.contexts.put(beans, ctx);
}
return beans;
}

子上下文 bean:

<int:channel id="fromDynamicRouter" />

<int-xml:xpath-splitter id="requestSplitter"
input-channel="fromDynamicRouter" output-channel="xPathSplitterResultsChannel"
xpath-expression-ref="dsoBatchRequestXPathNs">
</int-xml:xpath-splitter>

<int-xml:xpath-expression id="dsoBatchRequestXPathNs"
expression="/dso:DsoRequests/dso:DsoRequest/*" namespace-map="namespaceMap" />

UDPATE

通过检查它们的哈希码,我发现子上下文中的所有 bean 实际上每个 channel 都不同。所需要做的就是创建子上下文并动态路由到传入 channel 。

但这并没有真正解决性能问题 - 它仍然比原始服务慢大约两倍。 Spring Integration 在这方面似乎表现不佳,除非我遗漏了一些东西?

最佳答案

JAXP XPathExpression 不仅是非线程安全的,而且我猜您可能正在使用它来访问 DOM,而 DOM 也不是线程安全的。考虑切换到 Saxon,其中编译的 XPath 表达式和 native 树模型都是线程安全的,并且作为奖励,您可以访问 XPath 2.0。

关于java - 使用 XPath 时有没有办法避免 Jaxp13XPathExpression 的瓶颈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29163601/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com