2017-09-01 37 views
2

我正在使用Spring WebserviceTemplate對服務進行SOAP調用。我運行性能測試來了解它在負載下的表現。我也有一個攔截器,用於將我的傳入請求中的標題參數複製到我打電話的服務中。JAXB.marshal阻止web服務調用

@Component 
public class HeaderPropagationInterceptor implements ClientInterceptor { 

    @Override 
    public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException { 
     SoapMessage request = (SoapMessage) messageContext.getRequest(); 
     Result result = request.getSoapHeader().getResult(); 
     JAXB.marshal(getRequestHeader(), result); 
     return true; 
    } 

當我跑了性能測試,我看到下面的語句阻斷4-5秒

JAXB.marshal(getRequestHeader(), result); 

是否有一個原因,這可能會阻止?

+0

您是否看到類['JAXB'](https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/JAXB.html)的javadoc?它說: 「*一般來說,性能不一定是最佳的 預計需要編寫性能關鍵代碼 的人將直接使用JAXB API的其餘部分*」 –

+0

謝謝,但它通常會在100毫秒。我只在嘗試加載測試時纔看到此問題。這是否由我​​們造成這種延遲的任何機會同步?當我打開課程時,我看到該方法是靜態的但不同步 –

+0

'JAXB.marshal'從哪裏來?這是第三方API嗎? – kolossus

回答

3

JAXB實用程序類將在第一次調用JAXBContext時創建JAXBContext(昂貴的操作)。它將被弱緩存,這意味着如果內存不足,可以回收上下文,並在以下調用中重新創建。你真的應該創建你的上下文並明確地保存它。像這樣的東西(如已被別人的意見建議)應該解決您的問題:

@Component 
public class HeaderPropagationInterceptor implements ClientInterceptor 
{ 
    private JAXBContext jaxbContext; 

    @PostConstruct 
    public void createJaxbContext() { 
     try { 
      jaxbContext = JAXBContext.newInstance(RequestHeader.class); 
     } 
     catch(JAXBException e) { 
      throw new IllegalStateException("Unable to create JAXBContext.", e); 
     } 
    } 

    @Override 
    public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException { 
     SoapMessage request = (SoapMessage) messageContext.getRequest(); 
     Result result = request.getSoapHeader().getResult(); 
     jaxbContext.createMarshaller().marshal(getRequestHeader(), result); 
     return true; 
    } 
} 

你必須與你的代碼中使用的實際的類來代替RequestHeader.class。如果性能需要進一步提高,那麼也可以使用線程本地來重新使用編組器,但是您應該進行進一步分析來驗證這是一個真正的瓶頸。祝你的項目好運!

+0

我認爲不允許在'@ PostConstruct'方法中拋出'拋出JAXBException'。參見[this](https://stackoverflow.com/questions/23153742/im-gettting-warning-from-postconstruct-annotated-init-method) 和[this](https://stackoverflow.com/questions/8740234/postconstruct-checked-exceptions)問題。 因此,您需要刪除'throws'子句,而是在您的方法中添加一些'try' /'catch'邏輯。 –

+0

@ThomasFritsch是的,你是對的。我會更新這個例子! –

+0

Thanks Per Huss !!! –