英文:
Reuse org.apache.cxf generated client instead of always regenerate
问题
我正在尝试将自动生成的客户端存储在一个bean中,因为我总是在控制台中看到以下输出,这意味着它总是会发送一个请求到SOAP服务器来生成客户端,这大约需要1 - 1 1/2秒甚至更长时间。
创建来自WSDL的服务 {http://example.com/soap/example}ExampleService: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);
}
这似乎起初是有效的,但在第二次请求时,从Map
获取Example
时,我总是遇到以下异常:
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)
...
在名为scopedTarget.getExample
的bean创建过程中出现错误,定义在类路径资源 [com/example/ExampleConfig.class]
,出现了意外异常;嵌套异常是 java.lang.IllegalStateException: The client has been closed.
有没有一种方法可以仅生成一次客户端并重用它,以避免在每次请求时都生成客户端?
英文:
I am trying to store the automated generated client in a bean because I always see the following output in console which means it will always send a request to the SOAP server to generate the client which takes about 1 - 1 1/2 seconds or even longer.
Creating Service {http://example.com/soap/example}ExampleService from WSDL: https://test.example.com/soap/example?wsdl
The generated looks like following
@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);
}
What I have tried:
private final ExampleService exampleService;
@Bean
@RequestScope
public Example getExample() {
final EnvConfig envConfig = someService.getEnvConfig();
if (envConfig.isProd())
return someService.getExampleForTest();
return someService.getExampleForProd();
}
It is annotated with @RequestScope
as configuration may change during runtime. Calling getExampleForXXX
seems to always regenerate the client (regarding the above posted log) which takes about 1 - 1 1/2 seconds.
Then I've tried the following approach
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);
}
This seems to work at first but on the second request, when getting Example
from the Map
, I always face the following exception
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.]
Is there a way to generate the client once and reuse it to avoid generating the client on each request
专注分享java语言的经验与见解,让所有开发者获益!
评论