根据设计生成两个接口,IRpcSend send方法返回数据要求包装成QResult对象

public interface IRpcSend {
public <T> QResult<T> send(byte command, Object... args);
}
public interface IRpcReceive {
public <T> T receive(byte command, Objec[] args);
}
public interface IRpcContext {
RpcContext getContext();
void setContext(RpcContext ctx);
}
public interface QResult<T> extends Future<T> {

    /**
* 是否出错
* */
public boolean isError();
/**
* 获取返回结果
* */
public T getResult();
/**
* 设置结果
* */
public void setResult(T result);
}
 @SuppressWarnings("unchecked")
public abstract class QRpcFactory {
private static Method SEND_METHOD = ReflectUtil.getMethod(IRpcSend.class, "send");
private static Method RECEIVE_METHOD = ReflectUtil.getMethod(IRpcReceive.class, "receive"); private static Map<Short, Class<?>> SEND_CLASS = new HashMap<>();
private static Map<Short, IRpcReceive> RECEIVE = new HashMap<>(); public static <T> T loadSendProxy(Class<T> target, QNode... nodes) {
T ret = loadSendPorxy0(target);
IRpcContext ctx = (IRpcContext) ret;
ctx.setContext(RpcContext.of(nodes));
return ret;
} public static <T> T loadSendProxy(Class<T> target, Long... ids) {
T ret = loadSendPorxy0(target);
IRpcContext ctx = (IRpcContext) ret;
ctx.setContext(RpcContext.of(ids));
return ret;
} public static <T> T loadSendProxy(Class<T> target, String... addresses) {
T ret = loadSendPorxy0(target);
IRpcContext ctx = (IRpcContext) ret;
ctx.setContext(RpcContext.of(addresses));
return ret;
} private static <T> T loadSendPorxy0(Class<T> target) {
QModel modelAnno = ReflectUtil.getAnno(target, QModel.class);
Class<?> proxyClass = SEND_CLASS.get(modelAnno.value());
T ret = null;
try {
ret = (T) proxyClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return ret;
} public static <T> T loadLocalProxy(Class<T> target) {
QModel modelAnno = ReflectUtil.getAnno(target, QModel.class);
Object ret = RECEIVE.get(modelAnno.value());
return (T) ret;
} public static IRpcReceive loadReceiveProxy(short model) {
IRpcReceive ret = RECEIVE.get(model);
return ret;
}
}

QRpcFactory

 public static void registerSendProxy(Class<?> target) {
if (!target.isInterface()) {
throw new RuntimeException("class is not Interface : " + target);
}
QModel modelAnno = ReflectUtil.getAnno(target, QModel.class);
String proxyClassName = target.getCanonicalName() + "$$send$$";
ClassPool classPool = JavassistHepler.classPool;
CtClass ctClass = classPool.makeClass(proxyClassName); try {
// 设置接口
CtClass[] interfaces = new CtClass[3];
interfaces[0] = classPool.get(target.getName());
interfaces[1] = classPool.get(IRpcSend.class.getName());
interfaces[2] = classPool.get(IRpcContext.class.getName());
ctClass.setInterfaces(interfaces); {
// 添加ctx字段
final String ctxName = RpcContext.class.getName();
CtField ctField = new CtField(classPool.get(ctxName), "ctx", ctClass);
ctField.setModifiers(Modifier.PRIVATE);
ctClass.addField(ctField);
// 添加ctx get set 方法
CtMethod ctMethod = CtMethod.make("public " + ctxName + " getContext(){return ctx;}", ctClass);
ctMethod.setModifiers(Modifier.PUBLIC);
ctClass.addMethod(ctMethod); ctMethod = CtMethod.make("public void setContext(" + ctxName + " value){ ctx =value;}", ctClass);
ctMethod.setModifiers(Modifier.PUBLIC);
ctClass.addMethod(ctMethod);
} // 生成send method 调用静态方法减少书写复杂
{
final String body = " return ($r){ " + resultType + QRpcFactory.class.getName() + ".proxySend(this,$2, (short)" + modelAnno.value() + " ,(byte) $1);}";
JavassistHepler.addMethod(ctClass, SEND_METHOD, body);
} // 生成代理方法
for (Method method : target.getDeclaredMethods()) {
QCommond commond = method.getAnnotation(QCommond.class);
if (commond == null) {
continue;
} String resultType = "";
if (void.class != method.getReturnType()) {
resultType = " return ($r) ";
}
final String body = "{ " + resultType + " this.send((byte)" + commond.value() + ",$args); }";
JavassistHepler.addMethod(ctClass, method, body);
} // 保存记录
Class<?> newClass = ctClass.toClass();
ctClass.detach();
SEND_CLASS.put(modelAnno.value(), newClass); } catch (Exception e) {
e.printStackTrace();
}
}
public static QResult proxySend(IRpcContext target, Object[] args, short model, byte commondIndex) {
System.out.println("model : " + model + " commondIndex : " + commondIndex);
return null;
}

测试理论:

    @QModel(1)
public interface TestObject {
@QCommond(1)
public void a(int a, String b); @QCommond(2)
public void setAge(int value); @QCommond(3)
public QResult<Integer> getAge(); @QCommond(4)
public void setObj(TestObject1 obj); @QCommond(5)
public void test(int a,Integer b,Double c ,List<Integer> d,Integer[] e );
} public class TestObject1 {
public int a = 67;
} public static class TestObjectImpl implements TestObject {
private int age; @Override
public void a(int a, String b) {
System.out.println("a : " + a + " " + b);
} @Override
public void setAge(int value) {
age = value;
} @Override
public QResult<Integer> getAge() {
return QResultWrapper.of(age);
} @Override
public void setObj(TestObject1 obj) {
System.out.println(obj.a);
} @Override
public void test(int a, Integer b, Double c ,List<Integer> d,Integer[] e ) { }
}
 public class TestRpcProxy {
@Test
public void testSend() {
QRpcFactory3.registerSendProxy(TestObject.class);
TestObject proxy = QRpcFactory3.loadSendProxy(TestObject.class, 1L); proxy.a(1, "b");
QResult<Integer> ret = proxy.getAge();
}
}

由于发送处理涉及netty,先不考虑通信处理实现,在实现写框架过程,依赖越少实现越简单。所以每个实例对象构造出来时必须能正常工作

[编织消息框架][JAVA核心技术]动态代理应用7-IRpcSend实现的更多相关文章

  1. [编织消息框架][JAVA核心技术]动态代理介绍

    由于java是种强类型静态语言,在执行时无法动态生成代码,静态语言基本都有这特性 动态生成代码有几种好处,也是弱类型语言的优点 1.部份逻辑可以实现热更新 2.远程调用实现非常适合 3.能动态生成扩展 ...

  2. [编织消息框架][JAVA核心技术]动态代理应用12-总结

    动态代理这篇比较长,是框架组成的重要基础 回顾下学到的应用技术 1.异常应用 2.annotation技术 3.数值与逻辑分享 4.jdk.cglib.javassist等动态代理技术 5.懒处理.预 ...

  3. [编织消息框架][JAVA核心技术]动态代理应用4

    基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...

  4. [编织消息框架][JAVA核心技术]动态代理应用8-IRpcReceive实现

    private static Map<Short, Map<Byte, Method>> RECEIVE_METHOD_INFO = new HashMap<>() ...

  5. [编织消息框架][JAVA核心技术]动态代理应用4-annotationProcessor

    基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...

  6. [编织消息框架][JAVA核心技术]动态代理应用2

    接下来如何实现 第一步:先把服务类,调用方法转换成数字,方便传输 第二步:提取元信息,提取又有三种方式,三种各有优点,最优方式是第一种 1.编译java时处理 2.程序启动时处理,预处理 3.调用时处 ...

  7. [编织消息框架][JAVA核心技术]动态代理应用5-javassist

    基础部份: 修改class我们用到javassist,在pom.xml添加 <properties> <javassist.version>3.18.2-GA</java ...

  8. [编织消息框架][JAVA核心技术]动态代理应用9-扫描class

    之前介绍的annotationProcessor能在编译时生成自定义class,但有个缺点,只能每次添加/删除java文件才会执行,那天换了个人不清楚就坑大了 还记得之前介绍的编译时处理,懒处理,还有 ...

  9. [编织消息框架][JAVA核心技术]动态代理应用10-水平扩展方案

    服务分为系统服务同用户服务两种 水平扩展是基于系统服务,而拆分方式又有几种方案,按数据跟业务情况来做决策 1.每个服务独立存储(图1):每个服务只负责一个或多个领域实体存储,A服务不能直接修改B服务的 ...

随机推荐

  1. indexOf 和 lastIndexOf的区别

    indexOf 和  lastIndexOf 是什么? indexOf 和 lastIndexOf 都是索引文件 indexOf 是查某个指定的字符串在字符串首次出现的位置(索引值) (也就是从前往后 ...

  2. 【JDK1.8】JDK1.8集合源码阅读——IdentityHashMap

    一.前言 今天我们来看一下本次集合源码阅读里的最后一个Map--IdentityHashMap.这个Map之所以放在最后是因为它用到的情况最少,也相较于其他的map来说比较特殊.就笔者来说,到目前为止 ...

  3. codeforge免费下载账号 积分账号 共享账号

    codeforge网站下载代码很好,没有积分怎么办?那么多好的matlab代码,matlab程序,C,JAVA等等,都要充值啊!!! 请用下面共享的codeforge账号密码========> ...

  4. Angular之指令Directive系列

    项目筹备近期开启Angular学习,指令比较难理解所以记录备案,推荐Angualr实战学习视频大漠穷秋 Angular实战 一.指令directive概述 指令可以对元素绑定事件监听或者改变DOM结构 ...

  5. css3的动画特效--元素旋转

    开发中,视觉要你实现一个元素的旋转问题,比如说如下图所示: 思路:首先动画动效肯定离不开anmimation动画. 和transition动画一样,animation动画也是CSS3动画的一种,这类动 ...

  6. 关于xshell:Connection closed by foreign host

    因为原来系统网有时掉,有时卡(同局域网别人没事),重新做了系统. 装了xmanager3,在用xshell连接linux服务器时,提示:服务器发送了一个无效的密钥,然后输出:Connection cl ...

  7. ios应用程序国际化

    1.程序名称国际化: 在Xcode中新建项目后,能够在project的info选项卡中找到Localization的项目,能够加入应用程序须要支持的国际语言. 回到项目中能够发如今InfoPlist. ...

  8. Codeforces 29D Ant on the Tree 树的遍历 dfs序

    题目链接:点击打开链接 题意: 给定n个节点的树 1为根 则此时叶子节点已经确定 最后一行给出叶子节点的顺序 目标: 遍历树并输出路径.要求遍历叶子节点时依照给定叶子节点的先后顺序訪问. 思路: 给每 ...

  9. 【SqlServer】【问题收集】删除同一张表中完全相同的记录

    1   概述 在Sqlserver中,当通过SqlServer设计器删除同一张表中两条完全相同的记录时,会弹出如下提示: 点击“是” 弹出如下提示,不让删除 2   问题解决 这个问题很简单,用DEL ...

  10. MyBatis_动态SQL

    一.动态SQL 动态SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据提交的查询条件进行查询. 动态SQL,即通过MyBatis提供的各种标签对条件作出判断以实现动态拼接SQL语句. 二. ...