我们先使用懒处理实现提取接口类上的元信息:
public abstract class QRpcFactory { public static <T> T loadProxy(Class<T> target, QNode... nodes) public static <T> T loadProxy(Class<T> target, long... ids)
}
通过工厂类绑定session id 或 node 生成代理实例
RpcContext 是处理临时上下文对象,用来记录发送目标,同处理完返回结果
public class RpcContext {
private QNode[] nodes;
private Long[] ids;
private IQCallback<?> cb; public static RpcContext of(QNode... nodes) {
RpcContext ret = new RpcContext();
ret.nodes = nodes;
return ret;
}
public static RpcContext of(Long... ids) {
RpcContext ret = new RpcContext();
ret.ids = ids;
return ret;
}
}
@SuppressWarnings("unchecked")
public abstract class QRpcFactory { public static <T> T loadProxy(Class<T> target, QNode... nodes) {
T ret = loadProxy0(target);
IRpcContext ctx = (IRpcContext) ret;
ctx.setContext(RpcContext.of(nodes));
return ret;
} public static <T> T loadProxy(Class<T> target, Long... ids) {
T ret = loadProxy0(target);
IRpcContext ctx = (IRpcContext) ret;
ctx.setContext(RpcContext.of(ids));
return ret;
} private static <T> T loadProxy0(Class<T> target) {
T ret = (T) Proxy.newProxyInstance(QRpcFactory.class.getClassLoader(), new Class[] { target, IRpcContext.class }, new InvocationHandler() {
QModel modelAnno = target.getAnnotation(QModel.class);
private short model = modelAnno.value();
private RpcContext ctx; @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("setContext")) {
this.ctx = (RpcContext) args[0];
System.out.println("setContext");
return null;
}
QCommond commondAnno = method.getAnnotation(QCommond.class);
// do send return null;
}
});
return ret;
}
public static void main(String[] args) {
TestRpcObject obj = QRpcFactory.loadProxy(TestRpcObject.class, 123L);
}
}
@QModel(1)
public interface TestRpcObject {
@QCommond(1)
public void a();
}
每次使用时再处理,是懒处理思想的核心,有的场景加上缓存、double check、ThreadLocal、WeakHashMap技术
由于要解决并发问题,所以这例子缓存用不上,对象不能是单例,而每个实例参数不一,用不了ThreadLocal来记录RpcContext
可以在loadProxy0 创建InvocationHandler 时生成RpcContext 这里为了示例一个接口类如何保存属性的