在多个服务之间重用 CXF jaxb 上下文 [英] Reuse CXF jaxb context between multiple services

查看:29
本文介绍了在多个服务之间重用 CXF jaxb 上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多个服务可以从数千个类中返回结果.
由于每个 CXF 服务都包含一个私有的几乎相同的 JAXB 上下文,因此会造成巨大的内存浪费.
有没有办法自己创建 JAXB 上下文并在服务之间共享它?

I have multiple services which can return results out of thousands of classes.
Since each CXF service contains a private almost identical JAXB context, it causes a huge memory waste.
Is there a way to create the JAXB context myself and share it between the services?

推荐答案

一种可能的解决方法是在 spring 配置中添加以下内容:

One possible way to solve it is by adding the following to the spring configuration:

<bean class="org.apache.cxf.jaxb.JAXBDataBinding" >
    <constructor-arg index="0" value="#{GlobalContextBean.context}"/>
</bean>

其中的值只是对持有全局(单个)JAXBContext 并具有以下方法的 bean 的引用:

Where the value is just a reference to a bean which holds the global (single) JAXBContext and has the following method:

public javax.xml.bind.JAXBContext getContext() {...}

您可以在以下线程中查看更多详细信息(包括 CXF 大师 Daniel Kulp 的输入):
Reuse-JAXB-context-in-jaxws

You can see more details (including the CXF guru Daniel Kulp inputs) in the following thread:
Reuse-JAXB-context-in-jaxws

经过测试后,我发现将当前的 JAXBDataBinding 设置为多个服务的全局实例是行不通的,因为其 initialize 方法中有一个if"语句,一旦第一个服务设置了上下文,就会返回该语句.
这就是为什么我最终扩展了类并收集了所有必需的服务类和模型类.在所有服务初始化结束后,我创建一个包含所有必需类的全局上下文并将其返回给所有服务.
您可以使用以下类.
初始化所有 Web 服务后,调用 compileGlobalJAXBContext 方法来创建全局上下文.您可以在那里添加应用程序需要的其他类,而 init 错过了.
不要忘记配置服务以使用此 bean.

After testing it I've discovered that setting the current JAXBDataBinding as a global instance for multiple services won't work since there is an "if" statement in its initialize method which returns once the context was set by the first service.
That's why I've ended up by extending the class and collecting all the required services classes and model ones. After all services initialization ends, I create a global context with all required classes and return it to all services.
You can use the following class.
After all your web services are initialized call the compileGlobalJAXBContext method for creating the global context. You can add there other classes which the application needs and the init missed.
Don't Forget to configure the services to work with this bean.

public class GlobalJAXBDataBinding extends JAXBDataBinding
{
private Set<Class<?>> globalContextClasses;
private boolean contextBuilt = false;

public GlobalJAXBDataBinding(Set<Class<?>> classes) {
    globalContextClasses = new HashSet<>(classes);
    globalContextClasses.add(CPUUID.class);
}

public GlobalJAXBDataBinding() {
}

}

public synchronized void initialize(Service service) {
    if (contextBuilt)
        return;
    super.initialize(service);
    globalContextClasses.addAll(getContextClasses());
    super.setContext(null);
}

public void compileGlobalJAXBContext() {
    if (contextBuilt) return;
    setContext(JAXBContext.newInstance(globalContextClasses));
    contextBuilt *equals* true; 
}

由于一些奇怪的原因,编辑器没有让我在 compileGlobalJAXBContext 的最后一行添加等号,所以只需将等号替换为相关符号即可.

For some strange reason the editor didn't let me add the equal sign in the last line of compileGlobalJAXBContext so just replace the equals word with the relevant sign.

这篇关于在多个服务之间重用 CXF jaxb 上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆