首页 > 解决方案 > 重用 org.apache.cxf 生成的客户端,而不是总是重新生成

问题描述

我正在尝试将自动生成的客户端存储在 bean 中,因为我总是在控制台中看到以下输出,这意味着它将始终向 SOAP 服务器发送请求以生成客户端,这需要大约 1 - 1 1/2 秒甚至更长的时间.

Creating Service {http://example.com/soap/example}ExampleService from WSDL: https://test.example.com/soap/example?wsdl

生成的样子如下

@WebService(targetNamespace = "http://example.com/soap/example", name = "Example")
@XmlSeeAlso({com.example.soap.packe.ObjectFactory.class, ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface Example { ... }



@WebServiceClient(name = "ExampleService",
                  wsdlLocation = "http://example.com/soap/example?wsdl",
                  targetNamespace = "http://example.com/soap/example")
public class ExampleService extends Service {

@WebEndpoint(name = "ExampleServiceProd")
public Example getExampleForProd() {
    return super.getPort(ExampleServiceProd, Example.class);
}

@WebEndpoint(name = "ExampleServiceTest")
public Example getExampleForTest() {
    return super.getPort(ExampleServiceTest, Example.class);
}

我试过的:

private final ExampleService exampleService;    
@Bean
    @RequestScope
    public Example getExample() {
        final EnvConfig envConfig = someService.getEnvConfig();
        if (envConfig.isProd())
            return someService.getExampleForTest();
        return someService.getExampleForProd();
    }

它带有注释,@RequestScope因为配置可能在运行时发生变化。调用getExampleForXXX似乎总是重新生成客户端(关于上面发布的日志),这大约需要 1 - 1 1/2 秒。

然后我尝试了以下方法

private final Map<EnvConfig, Example> examples = new HashMap<>();
private final ExampleService exampleService;
@Bean
@RequestScope
public Example getExample() {
    final EnvConfig envConfig = someService.getEnvConfig();
    if (!examples.containsKey(accessDataEntity)) {
        if (envConfig.isProd())
            examples.put(envConfig, exampleService.getExampleForProd());
        else
            examples.put(envConfig, exampleService.getExampleForTest());
    }    
    return wallets.get(envConfig);
}
    

起初这似乎有效,但在第二个请求中,从 获取时ExampleMap我总是面临以下异常

Caused by: java.lang.IllegalStateException: The client has been closed.
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:99)
    at com.sun.proxy.$Proxy246.hashCode(Unknown Source)
    at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
    at java.base/java.util.concurrent.ConcurrentHashMap.containsKey(ConcurrentHashMap.java:964)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.requiresDestruction(PersistenceAnnotationBeanPostProcessor.java:393)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.filterPostProcessors(DisposableBeanAdapter.java:223)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.<init>(DisposableBeanAdapter.java:136)
    at org.springframework.beans.factory.support.AbstractBeanFactory.registerDisposableBeanIfNecessary(AbstractBeanFactory.java:1878)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:636)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    ... 127 common frames omitted

Error creating bean with name 'scopedTarget.getExample' defined in class path resource [com/example/ExampleConfig.class]: Unexpected exception during bean creation; nested exception is java.lang.IllegalStateException: The client has been closed.]

有没有办法生成一次客户端并重用它以避免在每个请求上生成客户端

标签: javaspringsoapcxf

解决方案


推荐阅读