博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[编织消息框架][JAVA核心技术]动态代理应用8-IRpcReceive实现
阅读量:5101 次
发布时间:2019-06-13

本文共 5057 字,大约阅读时间需要 16 分钟。

1     private static Map
> RECEIVE_METHOD_INFO = new HashMap<>(); 2 3 public static
T registerReceiveProxy(Object obj) { 4 Class
target = obj.getClass(); 5 if (target.isInterface()) { 6 throw new RuntimeException("class is Interface : " + target); 7 } 8 QModel modelAnno = ReflectUtil.getAnno(target, QModel.class); 9 String proxyClassName = target.getCanonicalName() + "$$receive$$";10 ClassPool classPool = JavassistHepler.classPool;11 CtClass ctClass = classPool.makeClass(proxyClassName);12 13 try {14 // 设置接口,继承 target15 CtClass[] interfaces = new CtClass[1];16 interfaces[0] = classPool.get(IRpcReceive.class.getName());17 ctClass.setInterfaces(interfaces);18 ctClass.setSuperclass(JavassistHepler.getCtClass(target));19 {20 // 添加this字段21 final String ctxName = target.getName();22 CtField ctField = new CtField(classPool.get(ctxName), "_this", ctClass);23 ctField.setModifiers(Modifier.PRIVATE | Modifier.FINAL);24 // 添加json 忽略anno25 ctField.getFieldInfo2().addAttribute(JavassistHepler.addAnno(JsonIgnore.class, ctClass));26 ctClass.addField(ctField);27 }28 29 Map
methods = new HashMap<>();30 RECEIVE_METHOD_INFO.put(modelAnno.value(), methods);31 32 // 生成代理方法33 ReflectUtil.foreachMethods(target, (method) -> {34 QCommond commond = method.getAnnotation(QCommond.class);35 if (commond == null) {36 return;37 }38 methods.put(commond.value(), method);39 String resultType = "";40 if (void.class != method.getReturnType()) {41 resultType = " return ($r) ";42 }43 final String body = "{ " + resultType + "_this." + method.getName() + "($$); }";44 JavassistHepler.addMethod(ctClass, method, body);45 });46 47 // 生成receive method48 {49 final String body = "{return ($r) " + QRpcFactory.class.getName() + ".proxyReceive(_this,$2, (short)" + modelAnno.value() + " ,(byte) $1);}";50 JavassistHepler.addMethod(ctClass, RECEIVE_METHOD, body);51 }52 53 // 添加构造方法 new XXProxy(XX)54 CtConstructor ctConstructor = new CtConstructor(JavassistHepler.toCtClassArray(target), ctClass);55 ctConstructor.setBody("{ this._this = $1; }");56 ctConstructor.setModifiers(Modifier.PUBLIC);57 ctClass.addConstructor(ctConstructor);58 Class
newClass = ctClass.toClass();59 Constructor
constructor = (Constructor
) newClass.getConstructor(target);60 constructor.setAccessible(true);61 ctClass.detach();62 Object ret = constructor.newInstance(obj);63 RECEIVE.put(modelAnno.value(), (IRpcReceive) ret);64 return (T) ret;65 } catch (Exception e) {66 throw new RuntimeException(e);67 }68 }69 70 // 因为 javassist $$ 表达式访问的 参数类型 为 object 获取不到目标类型,所以只能用 invoke 处理71 public static Object proxyReceive(Object target, Object[] args, short model, byte commondIndex) {72 Map
methods = RECEIVE_METHOD_INFO.get(model);73 try {74 return methods.get(commondIndex).invoke(target, args);75 } catch (Exception e) {76 throw new QRpcException(QCode.ENHANCE_ERROR_RPC_NOFIND_MODEL, "proxyReceive ", e);77 }78 }79 }

 

@Test    public void testReceive() {            TestObject proxy = QRpcFactory.registerReceiveProxy(new TestObjectImpl());        proxy.a(1, "b");        proxy.setAge(30);        QResult
ret = proxy.getAge(); System.out.println(ret.getResult()); Object[] args = new Object[1]; args[0] =18; ((IRpcReceive) proxy).receive((byte) 2, args); ret = proxy.getAge(); System.out.println(ret.getResult()); args[0] = new TestObject1(); ((IRpcReceive) proxy).receive((byte) 4, args); } @Test public void testObjectArgs() { QRpcFactory.registerReceiveProxy(new TestObjectImpl()); IRpcReceive obj = QRpcFactory.loadReceiveProxy((short)1); int a=30; Integer b= 30; double c=1d; List
d = new ArrayList<>(); Integer[] e = new Integer[0]; Object[] args = new Object[5]; args[0] =a; args[1] =b; args[2] =c; args[3] =d; args[4] =e; obj.receive((byte)5, args); }

 

在实际开发时 因为 javassist $$ 表达式访问的参数类型为object 获取不到目标类型,编译时出现错误

Type 'java/lang/Object' (current frame, stack[1]) is not assignable to integer

所以只能用 invoke 处理 

转载于:https://www.cnblogs.com/solq111/p/6694484.html

你可能感兴趣的文章
【41】102. Binary Tree Level Order Traversal
查看>>
BZOJ_1029_[JSOI2007]_建筑抢修_(贪心+优先队列)
查看>>
None.js 第五步 Buffer(缓冲区)
查看>>
dede文章页调用当前栏目链接方法
查看>>
django 自定义标签
查看>>
第二节课课堂作业
查看>>
在线mark.down编辑器
查看>>
PAT(乙级)1016
查看>>
1、mysql创建用户和授权总结
查看>>
【学校集训】【USACO15DecG】Bessie's Dream
查看>>
团队编程项目作业5-小组评分
查看>>
隔行变色效果
查看>>
js监听滚动条滚动事件
查看>>
java web实现文件下载的注意事项
查看>>
SQL数据库
查看>>
ORA-32004: obsolete and/or deprecated parameter(s) specified
查看>>
安装中文输入法
查看>>
glassfish 自定义 jaas realm
查看>>
Glassfish 设置时区
查看>>
th:each
查看>>