如何以线程安全的方式使用CXF客户端

如何以线程安全的方式使用CXF客户端

本文介绍了如何以线程安全的方式使用CXF客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 apache-cxf 的wsdl2java命令为以下服务创建了客户端存根。

I have created the client stub for below service using apache-cxf's wsdl2java command.http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL


然后我调用 getWeatherInformation()方法,如下所示。

Weather weatherService = new Weather();
WeatherSoap weatherSoap = weatherService.getWeatherSoap();
ArrayOfWeatherDescription result = weatherSoap.getWeatherInformation();

我已经读过cxf客户端是线程安全的。但是我怀疑在多个线程中使用相同的 WeatherSoap 实例是否安全?还是应该/可以跨多个线程使用 Weather 类的实例?
谢谢。

I have read that cxf clients are thread safe. But I have a doubt whether it is safe to use the same WeatherSoap instance accross multiple threads? Or instead should/can I use an instance of Weather class, accross multiple threads?Thanks.

编辑:



我要做的是向公众公开了RESTful API,如果有人调用该REST服务,我调用另一个SOAP服务。上面的代码用于调用SOAP服务。我想知道的是我应该为每个休息请求执行以上所有行,还是可以重用 Weather WeatherSoap 来满足所有REST请求。


What I do is I have exposed a RESTful API to public and if somebody calls that rest service I call another SOAP service. Above code is used to call the SOAP service. What I want to know is should I execute all the above lines for each rest request or can I reuse an instance of Weather or WeatherSoap to serve all the REST requests.

推荐答案

是的CXF是线程安全的,您可以对天气使用单个实例/单个实例和WeatherSoap,您可以认为cxf类似于servlet引擎,该引擎为您处理所有基础结构,例如传输,数据绑定。我有类似的用例,其中有一个前端表示层和许多网络服务器,可以在它们之间进行交互,其余部分用于表示和实现业务逻辑以及与服务器交互的SOAP。因此,我在休息层实现了一个肥皂客户端。我的要求是我需要分割休息请求并调用具有800ms时间延迟的并行soap调用。我对整个安装程序进行了性能测试,并且没有遇到任何线程问题。

Yes CXF is thread safe, you can use single instance/singleton for Weather and WeatherSoap, you can think of cxf as similar to servlet engine which handles all the infrastructure for you such as transport, databinding for you. I had similar usecase, where I had a front end presentation layer and number of network servers, to interact between these I had a rest for presentation and SOAP which implements business logic as well as interacts with servers. Hence I implemented a soap client in rest layer. I had requirement were I needed split rest request and invoke parallel soap calls which had time delays 800ms. I performance tested the entire setup and did not run-up into any thread issues.

因此要介绍客户端实现

纯Java

public class MySoapClient{

  private static WeatherSoap weatherSoap;

  private MySoapClient(){
  }

  public static WeatherSoap getClient(){

    if(weatherSoap==null){
        Weather weatherService = new Weather();
        weatherSoap= weatherService.getWeatherSoap();
    }
    return weatherSoap;
  }

}

然后我将修改Weather类

And I would modify the Weather class to get SOAP url from properties file.

@WebServiceClient(name = "Weather",
                  wsdlLocation = "classpath:weather.wsdl",
                  targetNamespace = "http://ws.cdyne.com/WeatherWS/")
public class Weather extends Service {

    private static final Logger LOG = LoggerFactory.getLogger(Weather.class);
    public final static URL WSDL_LOCATION;
    public final static QName SERVICE = new QName("http://ws.cdyne.com/WeatherWS/", "Weather");
    public final static QName WeatherHttpPost = new QName("http://ws.cdyne.com/WeatherWS/", "WeatherHttpPost");
    public final static QName WeatherHttpGet = new QName("http://ws.cdyne.com/WeatherWS/", "WeatherHttpGet");
    public final static QName WeatherSoap12 = new QName("http://ws.cdyne.com/WeatherWS/", "WeatherSoap12");
    public final static QName WeatherSoap = new QName("http://ws.cdyne.com/WeatherWS/", "WeatherSoap");
    static {
        URL url = null;
        try {
            url = new URL(MyPropertiesUtil.getProperty("app.weather.url"));
        } catch (MalformedURLException e) {
            LOG.error(e.getMessage(), e);
        }
        if (url == null) {
            LOG.error("an issue with your url");
        }
        WSDL_LOCATION = url;
    }

    public Weather(URL wsdlLocation) {
        super(wsdlLocation, SERVICE);
    }

    public Weather(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public Weather() {
        super(WSDL_LOCATION, SERVICE);
    }


    //All the other interface methods

}

使用Spring

如果您使用spring,则可以使事情变得更简单。通过使用如下所示的配置文件消除Weather.java类,并让cxf为您生成代理。

if you are using spring you can make things even simpler, you can eliminate Weather.java class by using configuration file as shown below and let cxf generate proxy for you.

<jaxws:client id="weatherSoap" serviceClass="com.cdyne.ws.weatherws.WeatherSoap" address="${app.weather.url}" />

商务舱如下所示。

@Component
MyBusinessLogic{

  @Autowired
  private WeatherSoap weatherSoap;

  public ArrayOfWeatherDescription getOutput(){
    return weatherSoap.getWeatherInformation();
  }

}

这篇关于如何以线程安全的方式使用CXF客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 17:19