1.同步调用:
核心原理:利用JDK的动态代理类创建service代理对象,然后在InvocationHandler中调用channel发送数据, 同时利用信号量同步等待结果返回。
相关核心代码:
创建代理:
/**
* @Title: wrapSyncProxy4Service
* @Description: 为远程服务创建同步动态代理,返回代理对象
* @author 简道
* @param serviceInterface
* 远程服务接口
* @param dispatchStrategy
* 分发策略
* @return T 返回类型
*/
@SuppressWarnings("unchecked")
private static <T> T wrapSyncProxy4Service(Class<T> serviceInterface, SyncDispatchStrategy dispatchStrategy) {
if (serviceInterface == null) {
throw new IllegalArgumentException("serviceInterface can not be null.");
} else if (!serviceInterface.isInterface()) {
throw new IllegalArgumentException("serviceInterface is required to be interface.");
} else if (dispatchStrategy == null) {
throw new IllegalArgumentException("dispatchStrategy is required to be interface.");
}
InvocationHandler requestHandler = new SyncServiceRequestHandler(serviceInterface.getSimpleName(),
dispatchStrategy);
// 创建代理
T serviceProxy = (T) Proxy.newProxyInstance(getClassLoader(serviceInterface), new Class[] { serviceInterface },
requestHandler);
return serviceProxy;
}
同步请求处理:
/**
* @Title: SyncServiceRequestHandler.java
* @Package org.summercool.hsf.proxy.strategy
* @Description: 同步请求处理
* @author 简道
* @date 2011-9-30 下午3:10:10
* @version V1.0
*/
public class SyncServiceRequestHandler implements InvocationHandler {
String serviceName;
SyncDispatchStrategy dispatchStrategy;
public SyncServiceRequestHandler(String serviceName, SyncDispatchStrategy dispatchStrategy) {
if (serviceName == null) {
throw new IllegalArgumentException("serviceName can not be null.");
} else if (dispatchStrategy == null) {
throw new IllegalArgumentException("dispatchStrategy can not be null.");
}
this.serviceName = serviceName;
this.dispatchStrategy = dispatchStrategy;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
RemoteServiceObject remoteServiceObject = new RemoteServiceObject();
remoteServiceObject.setMethodName(method.getName());
remoteServiceObject.setServiceName(serviceName);
remoteServiceObject.setArgs(args);
InvokeResult result = dispatchStrategy.dispatch(remoteServiceObject);
if (result.size() > 0) {
return result.getFirstValue();
}
return ReflectionUtil.getDefaultValue(method.getReturnType());
}
消息分发:
@Override
public InvokeResult dispatch(Object message) {
if (message == null) {
throw new IllegalArgumentException("Message can not be null.");
} else if (!service.isAlived()) {
throw new IllegalStateException("service is not alived.");
}
HsfChannel channel = getChannel(service.getGroups());
Object retObj = write(message, channel);
// 构建结果
InvokeResult invokeResult = new InvokeResult();
invokeResult.put(((HsfChannel) channel).getChannelGroup().getName(), retObj);
return invokeResult;
}
HsfChannel同步write:
public Object writeSync(Object msg) {
InvokeFuture<?> invokeFuture = writeAsync(msg);
Object retObj = null;
boolean invokeTimeout = false;
Integer timeout = LangUtil.parseInt(service.getOption(HsfOptions.SYNC_INVOKE_TIMEOUT), 60000);
if (invokeTimeout = (timeout != null && timeout > 0)) {
// 等待返回,直到Response返回或超时
retObj = invokeFuture.getResult(timeout, TimeUnit.MILLISECONDS);
}
if (!invokeTimeout) {
// 一直等待,直到Response返回
retObj = invokeFuture.getResult();
}
return retObj;
}
public V getResult(long timeout, TimeUnit unit) {
if (!isDone()) {
try {
if (!semaphore.tryAcquire(timeout, unit)) {
setCause(new HsfTimeoutException("time out."));
}
} catch (InterruptedException e) {
throw new HsfRuntimeException(e);
}
}
// check exception
if (cause != null) {
if (cause instanceof HsfRemoteServiceException) {
throw ((HsfRemoteServiceException) cause);
}
throw new HsfRuntimeException(cause);
}
//
return this.result;
}