⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jaxrpcportclientinterceptor.java

📁 Spring API核心源代码 Spring API核心源代码 Spring API核心源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
			Service service = getJaxRpcService();
			if (service == null) {
				service = createJaxRpcService();
			}
			else {
				postProcessJaxRpcService(service);
			}

			Class portInterface = getPortInterface();
			if (portInterface != null && !alwaysUseJaxRpcCall()) {
				// JAX-RPC-compliant port interface -> using JAX-RPC stub for port.

				if (logger.isDebugEnabled()) {
					logger.debug("Creating JAX-RPC proxy for JAX-RPC port [" + this.portQName +
							"], using port interface [" + portInterface.getName() + "]");
				}
				Remote remoteObj = service.getPort(this.portQName, portInterface);

				if (logger.isDebugEnabled()) {
					Class serviceInterface = getServiceInterface();
					if (serviceInterface != null) {
						boolean isImpl = serviceInterface.isInstance(remoteObj);
						logger.debug("Using service interface [" + serviceInterface.getName() + "] for JAX-RPC port [" +
								this.portQName + "] - " + (!isImpl ? "not" : "") + " directly implemented");
					}
				}

				if (!(remoteObj instanceof Stub)) {
					throw new RemoteLookupFailureException("Port stub of class [" + remoteObj.getClass().getName() +
							"] is not a valid JAX-RPC stub: it does not implement interface [javax.xml.rpc.Stub]");
				}
				Stub stub = (Stub) remoteObj;

				// Apply properties to JAX-RPC stub.
				preparePortStub(stub);

				// Allow for custom post-processing in subclasses.
				postProcessPortStub(stub);

				this.portStub = remoteObj;
			}

			else {
				// No JAX-RPC-compliant port interface -> using JAX-RPC dynamic calls.
				if (logger.isDebugEnabled()) {
					logger.debug("Using JAX-RPC dynamic calls for JAX-RPC port [" + this.portQName + "]");
				}
			}

			this.serviceToUse = service;
		}
	}

	/**
	 * Return whether to always use JAX-RPC dynamic calls.
	 * Called by <code>afterPropertiesSet</code>.
	 * <p>Default is "false"; if an RMI interface is specified as "portInterface"
	 * or "serviceInterface", it will be used to create a JAX-RPC port stub.
	 * <p>Can be overridden to enforce the use of the JAX-RPC Call API,
	 * for example if there is a need to customize at the Call level.
	 * This just necessary if you you want to use an RMI interface as
	 * "serviceInterface", though; in case of only a non-RMI interface being
	 * available, this interceptor will fall back to the Call API anyway.
	 * @see #postProcessJaxRpcCall
	 */
	protected boolean alwaysUseJaxRpcCall() {
		return false;
	}

	/**
	 * Reset the prepared service of this interceptor,
	 * allowing for reinitialization on next access.
	 */
	protected void reset() {
		synchronized (this.preparationMonitor) {
			this.serviceToUse = null;
		}
	}

	/**
	 * Return whether this client interceptor has already been prepared,
	 * i.e. has already looked up the JAX-RPC service and port.
	 */
	protected boolean isPrepared() {
		synchronized (this.preparationMonitor) {
			return (this.serviceToUse != null);
		}
	}

	/**
	 * Return the prepared QName for the port.
	 * @see #setPortName
	 * @see #getQName
	 */
	protected QName getPortQName() {
		return this.portQName;
	}


	/**
	 * Prepare the given JAX-RPC port stub, applying properties to it.
	 * Called by {@link #afterPropertiesSet}.
	 * <p>Just applied when actually creating a JAX-RPC port stub, in case of a
	 * compliant port interface. Else, JAX-RPC dynamic calls will be used.
	 * @param stub the current JAX-RPC port stub
	 * @see #setUsername
	 * @see #setPassword
	 * @see #setEndpointAddress
	 * @see #setMaintainSession
	 * @see #setCustomProperties
	 * @see #setPortInterface
	 * @see #prepareJaxRpcCall
	 */
	protected void preparePortStub(Stub stub) {
		String username = getUsername();
		if (username != null) {
			stub._setProperty(Stub.USERNAME_PROPERTY, username);
		}
		String password = getPassword();
		if (password != null) {
			stub._setProperty(Stub.PASSWORD_PROPERTY, password);
		}
		String endpointAddress = getEndpointAddress();
		if (endpointAddress != null) {
			stub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, endpointAddress);
		}
		if (isMaintainSession()) {
			stub._setProperty(Stub.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);
		}
		if (this.customPropertyMap != null) {
			for (Iterator it = this.customPropertyMap.keySet().iterator(); it.hasNext();) {
				String key = (String) it.next();
				stub._setProperty(key, this.customPropertyMap.get(key));
			}
		}
	}

	/**
	 * Post-process the given JAX-RPC port stub. Called by {@link #prepare}.
	 * <p>The default implementation is empty.
	 * <p>Just applied when actually creating a JAX-RPC port stub, in case of a
	 * compliant port interface. Else, JAX-RPC dynamic calls will be used.
	 * @param stub the current JAX-RPC port stub
	 * (can be cast to an implementation-specific class if necessary)
	 * @see #setPortInterface
	 * @see #postProcessJaxRpcCall
	 */
	protected void postProcessPortStub(Stub stub) {
	}

	/**
	 * Return the underlying JAX-RPC port stub that this interceptor delegates to
	 * for each method invocation on the proxy.
	 */
	protected Remote getPortStub() {
		return this.portStub;
	}


	/**
	 * Translates the method invocation into a JAX-RPC service invocation.
	 * <p>Prepares the service on the fly, if necessary, in case of lazy
	 * lookup or a connect failure having happened.
	 * @see #prepare()
	 * @see #doInvoke
	 */
	public Object invoke(MethodInvocation invocation) throws Throwable {
		if (AopUtils.isToStringMethod(invocation.getMethod())) {
			return "JAX-RPC proxy for port [" + getPortName() + "] of service [" + getServiceName() + "]";
		}

		// Lazily prepare service and stub if appropriate.
		if (!this.lookupServiceOnStartup || this.refreshServiceAfterConnectFailure) {
			synchronized (this.preparationMonitor) {
				if (!isPrepared()) {
					try {
						prepare();
					}
					catch (ServiceException ex) {
						throw new RemoteLookupFailureException("Preparation of JAX-RPC service failed", ex);
					}
				}
			}
		}
		else {
			if (!isPrepared()) {
				throw new IllegalStateException("JaxRpcClientInterceptor is not properly initialized - " +
						"invoke 'prepare' before attempting any operations");
			}
		}

		return doInvoke(invocation);
	}

	/**
	 * Perform a JAX-RPC service invocation based on the given method invocation.
	 * <p>Uses traditional RMI stub invocation if a JAX-RPC port stub is available;
	 * falls back to JAX-RPC dynamic calls else.
	 * @param invocation the AOP method invocation
	 * @return the invocation result, if any
	 * @throws Throwable in case of invocation failure
	 * @see #getPortStub()
	 * @see #doInvoke(org.aopalliance.intercept.MethodInvocation, java.rmi.Remote)
	 * @see #performJaxRpcCall(org.aopalliance.intercept.MethodInvocation, javax.xml.rpc.Service)
	 */
	protected Object doInvoke(MethodInvocation invocation) throws Throwable {
		Remote stub = getPortStub();
		if (stub != null) {
			// JAX-RPC port stub available -> traditional RMI stub invocation.
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking operation '" + invocation.getMethod().getName() + "' on JAX-RPC port stub");
			}
			return doInvoke(invocation, stub);
		}
		else {
			// No JAX-RPC stub -> using JAX-RPC dynamic calls.
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking operation '" + invocation.getMethod().getName() + "' as JAX-RPC dynamic call");
			}
			return performJaxRpcCall(invocation);
		}
	}

	/**
	 * Perform a JAX-RPC service invocation based on the given port stub.
	 * @param invocation the AOP method invocation
	 * @param portStub the RMI port stub to invoke
	 * @return the invocation result, if any
	 * @throws Throwable in case of invocation failure
	 * @see #getPortStub()
	 * @see #doInvoke(org.aopalliance.intercept.MethodInvocation, java.rmi.Remote)
	 * @see #performJaxRpcCall
	 */
	protected Object doInvoke(MethodInvocation invocation, Remote portStub) throws Throwable {
		try {
			return RmiClientInterceptorUtils.doInvoke(invocation, portStub);
		}
		catch (InvocationTargetException ex) {
			Throwable targetEx = ex.getTargetException();
			if (targetEx instanceof RemoteException) {
				RemoteException rex = (RemoteException) targetEx;
				boolean isConnectFailure = isConnectFailure(rex);
				if (isConnectFailure && this.refreshServiceAfterConnectFailure) {
					reset();
				}
				throw RmiClientInterceptorUtils.convertRmiAccessException(
						invocation.getMethod(), rex, isConnectFailure, this.portQName.toString());
			}
			else if (targetEx instanceof JAXRPCException) {
				throw new RemoteProxyFailureException("Invalid call on JAX-RPC port stub", targetEx);
			}
			else {
				throw targetEx;
			}
		}
	}

	/**
	 * @deprecated as of Spring 2.0.3, in favor of the <code>performJaxRpcCall</code>
	 * variant with an explicit Service argument
	 * @see #performJaxRpcCall(org.aopalliance.intercept.MethodInvocation, javax.xml.rpc.Service)
	 */
	protected Object performJaxRpcCall(MethodInvocation invocation) throws Throwable {
		return performJaxRpcCall(invocation, this.serviceToUse);
	}

	/**
	 * Perform a JAX-RPC dynamic call for the given AOP method invocation.
	 * Delegates to {@link #prepareJaxRpcCall} and
	 * {@link #postProcessJaxRpcCall} for setting up the call object.
	 * <p>Default implementation uses method name as JAX-RPC operation name
	 * and method arguments as arguments for the JAX-RPC call. Can be
	 * overridden in subclasses for custom operation names and/or arguments.
	 * @param invocation the current AOP MethodInvocation that should
	 * be converted to a JAX-RPC call
	 * @return the return value of the invocation, if any
	 * @throws Throwable the exception thrown by the invocation, if any
	 * @see #getPortQName
	 * @see #prepareJaxRpcCall
	 * @see #postProcessJaxRpcCall
	 */
	protected Object performJaxRpcCall(MethodInvocation invocation, Service service) throws Throwable {
		QName portQName = getPortQName();

		// Create JAX-RPC call object, using the method name as operation name.
		// Synchronized because of non-thread-safe Axis implementation!
		Call call = null;
		synchronized (service) {
			call = service.createCall(portQName, invocation.getMethod().getName());
		}

		// Apply properties to JAX-RPC stub.
		prepareJaxRpcCall(call);

		// Allow for custom post-processing in subclasses.
		postProcessJaxRpcCall(call, invocation);

		// Perform actual invocation.
		try {
			return call.invoke(invocation.getArguments());
		}
		catch (RemoteException ex) {
			boolean isConnectFailure = isConnectFailure(ex);
			if (isConnectFailure && this.refreshServiceAfterConnectFailure) {
				reset();
			}
			throw RmiClientInterceptorUtils.convertRmiAccessException(
					invocation.getMethod(), ex, isConnectFailure, portQName.toString());
		}
		catch (JAXRPCException ex) {
			throw new RemoteProxyFailureException("Invalid JAX-RPC call configuration", ex);
		}
	}

	/**
	 * Prepare the given JAX-RPC call, applying properties to it. Called by {@link #invoke}.
	 * <p>Just applied when actually using JAX-RPC dynamic calls, i.e. if no compliant
	 * port interface was specified. Else, a JAX-RPC port stub will be used.
	 * @param call the current JAX-RPC call object
	 * @see #setUsername
	 * @see #setPassword
	 * @see #setEndpointAddress
	 * @see #setMaintainSession
	 * @see #setCustomProperties
	 * @see #setPortInterface
	 * @see #preparePortStub
	 */
	protected void prepareJaxRpcCall(Call call) {
		String username = getUsername();
		if (username != null) {
			call.setProperty(Call.USERNAME_PROPERTY, username);
		}
		String password = getPassword();
		if (password != null) {
			call.setProperty(Call.PASSWORD_PROPERTY, password);
		}
		String endpointAddress = getEndpointAddress();
		if (endpointAddress != null) {
			call.setTargetEndpointAddress(endpointAddress);
		}
		if (isMaintainSession()) {
			call.setProperty(Call.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);
		}
		if (this.customPropertyMap != null) {
			for (Iterator it = this.customPropertyMap.keySet().iterator(); it.hasNext();) {
				String key = (String) it.next();
				call.setProperty(key, this.customPropertyMap.get(key));
			}
		}
	}

	/**
	 * Post-process the given JAX-RPC call. Called by {@link #invoke}.
	 * <p>The default implementation is empty.
	 * <p>Just applied when actually using JAX-RPC dynamic calls, i.e. if no compliant
	 * port interface was specified. Else, a JAX-RPC port stub will be used.
	 * @param call the current JAX-RPC call object
	 * (can be cast to an implementation-specific class if necessary)
	 * @param invocation the current AOP MethodInvocation that the call was
	 * created for (can be used to check method name, method parameters
	 * and/or passed-in arguments)
	 * @see #setPortInterface
	 * @see #postProcessPortStub
	 */
	protected void postProcessJaxRpcCall(Call call, MethodInvocation invocation) {
	}

	/**
	 * Determine whether the given RMI exception indicates a connect failure.
	 * <p>The default implementation always returns <code>true</code>,
	 * assuming that the JAX-RPC provider only throws RemoteException
	 * in case of connect failures.
	 * @param ex the RMI exception to check
	 * @return whether the exception should be treated as connect failure
	 * @see org.springframework.remoting.rmi.RmiClientInterceptorUtils#isConnectFailure
	 */
	protected boolean isConnectFailure(RemoteException ex) {
		return true;
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -