import org.apache.axis2.client.OperationClient; //导入方法依赖的package包/类
public Future> doInvokeAsync(MessageContext request, AsyncHandler callback) {
// We need the qname of the operation being invoked to know which
// AxisOperation the OperationClient should be based on.
// Note that the OperationDesc is only set through use of the Proxy. Dispatch
// clients do not use operations, so the operationDesc will be null. In this
// case an anonymous AxisService with anoymouns AxisOperations for the supported
// MEPs will be created; and it is that anonymous operation name which needs to
// be specified
QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP);
// TODO: Will the ServiceClient stick around on the InvocationContext
// or will we need some other mechanism of creating this?
// Try to create an OperationClient from the passed in ServiceClient
InvocationContext ic = request.getInvocationContext();
ServiceClient svcClient = ic.getServiceClient();
OperationClient opClient = createOperationClient(svcClient, operationName);
initOperationClient(opClient, request);
// Setup the client so that it knows whether the underlying call to
// Axis2 knows whether or not to start a listening port for an
// asynchronous response.
Boolean useAsyncMep = (Boolean)request.getProperty(Constants.USE_ASYNC_MEP);
if ((useAsyncMep != null && useAsyncMep.booleanValue())
|| opClient.getOptions().isUseSeparateListener()) {
configureAsyncListener(opClient);
} else {
if (log.isDebugEnabled()) {
log.debug(
"Asynchronous message exchange not enabled. The invocation will be synchronous.");
}
}
CallbackFuture cbf = null;
if (callback != null) {
cbf = new CallbackFuture(ic, callback);
} else {
throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr4"));
}
opClient.setCallback(cbf);
org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext();
try {
execute(opClient, false, axisRequestMsgCtx);
} catch (AxisFault af) {
if (log.isDebugEnabled()) {
log.debug(axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " +
af.getMessage());
}
/*
* Save the exception on the callback. The client will learn about the error when they try to
* retrieve the async results via the Response.get(). "Errors that occur during the invocation
* are reported via an exception when the client attempts to retrieve the results of the operation."
* -- JAXWS 4.3.3
*/
/*
* TODO: This is the appropriate thing to do here since the thrown exception may occur before
* we switch threads to the async thread. But... what happens if we've already switched over
* to the async thread? So far, it appears that the exception gets set on the FutureTask
* Concurrent object, and we never hit this scope. This means that later, when the client
* calls future.get(), no exception will be thrown despite what the spec says. The client can,
* however, retrieve errors via it's AsyncHandler.
*/
cbf.onError(af);
}
return cbf.getFutureTask();
}