首页 > 代码库 > [编织消息框架][JAVA核心技术]动态代理应用7-实现设计
[编织消息框架][JAVA核心技术]动态代理应用7-实现设计
根据设计生成两个接口,IRpcSend send方法返回数据要求包装成QResult对象
public interface IRpcSend { public <T> QResult<T> send(byte command, Object... args);}
public interface IRpcReceive { public <T> T receive(byte command, Object... 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);}
1 @SuppressWarnings("unchecked") 2 public abstract class QRpcFactory { 3 private static Method SEND_METHOD = ReflectUtil.getMethod(IRpcSend.class, "send"); 4 private static Method RECEIVE_METHOD = ReflectUtil.getMethod(IRpcReceive.class, "receive"); 5 6 private static Map<Short, Class<?>> SEND_CLASS = new HashMap<>(); 7 private static Map<Short, IRpcReceive> RECEIVE = new HashMap<>(); 8 9 public static <T> T loadSendProxy(Class<T> target, QNode... nodes) {10 T ret = loadSendPorxy0(target);11 IRpcContext ctx = (IRpcContext) ret;12 ctx.setContext(RpcContext.of(nodes));13 return ret;14 }15 16 public static <T> T loadSendProxy(Class<T> target, Long... ids) {17 T ret = loadSendPorxy0(target);18 IRpcContext ctx = (IRpcContext) ret;19 ctx.setContext(RpcContext.of(ids));20 return ret;21 }22 23 public static <T> T loadSendProxy(Class<T> target, String... addresses) {24 T ret = loadSendPorxy0(target);25 IRpcContext ctx = (IRpcContext) ret;26 ctx.setContext(RpcContext.of(addresses));27 return ret;28 }29 30 private static <T> T loadSendPorxy0(Class<T> target) {31 QModel modelAnno = ReflectUtil.getAnno(target, QModel.class);32 Class<?> proxyClass = SEND_CLASS.get(modelAnno.value());33 T ret = null;34 try {35 ret = (T) proxyClass.newInstance();36 } catch (InstantiationException | IllegalAccessException e) {37 throw new RuntimeException(e);38 }39 return ret;40 }41 42 public static <T> T loadLocalProxy(Class<T> target) {43 QModel modelAnno = ReflectUtil.getAnno(target, QModel.class);44 Object ret = RECEIVE.get(modelAnno.value());45 return (T) ret;46 }47 48 public static IRpcReceive loadReceiveProxy(short model) {49 IRpcReceive ret = RECEIVE.get(model);50 return ret;51 }52 }
1 // register 2 public static void registerSendProxy(Class<?> target) { 3 if (!target.isInterface()) { 4 throw new RuntimeException("class is not Interface : " + target); 5 } 6 QModel modelAnno = ReflectUtil.getAnno(target, QModel.class); 7 String proxyClassName = target.getCanonicalName() + "$$$$"; 8 ClassPool classPool = JavassistHepler.classPool; 9 CtClass ctClass = classPool.makeClass(proxyClassName);10 11 try {12 // 设置接口13 CtClass[] interfaces = new CtClass[3];14 interfaces[0] = classPool.get(target.getName());15 interfaces[1] = classPool.get(IRpcSend.class.getName());16 interfaces[2] = classPool.get(IRpcContext.class.getName());17 ctClass.setInterfaces(interfaces);18 19 {20 // 添加ctx字段21 final String ctxName = RpcContext.class.getName();22 CtField ctField = new CtField(classPool.get(ctxName), "ctx", ctClass);23 ctField.setModifiers(Modifier.PRIVATE);24 ctClass.addField(ctField);25 // 添加ctx get set 方法26 CtMethod ctMethod = CtMethod.make("public " + ctxName + " getContext(){return ctx;}", ctClass);27 ctMethod.setModifiers(Modifier.PUBLIC);28 ctClass.addMethod(ctMethod);29 30 ctMethod = CtMethod.make("public void setContext(" + ctxName + " value){ ctx =value;}", ctClass);31 ctMethod.setModifiers(Modifier.PUBLIC);32 ctClass.addMethod(ctMethod);33 }34 35 // 生成send method 调用静态方法减少书写复杂36 {37 Method method = SEND_METHOD;38 String resultType = " return ($r)";39 final String body = "{ " + resultType + QRpcFactory3.class.getName() + ".proxy(this,$args, (short)" + modelAnno.value() + " ,(byte) $1);}";40 41 Class<?> returnType = method.getReturnType();42 CtMethod ctMethod = new CtMethod(classPool.get(returnType.getName()), method.getName(), JavassistHepler.toCtClassArray(method.getParameterTypes()), ctClass);43 ctMethod.setModifiers(method.getModifiers());44 ctMethod.setBody(body);45 ctClass.addMethod(ctMethod);46 }47 48 // 生成代理方法49 Map<Byte, String> methodMap = new HashMap<>();50 for (Method method : target.getDeclaredMethods()) {51 QCommond commond = method.getAnnotation(QCommond.class);52 if (commond == null) {53 continue;54 }55 methodMap.put(commond.value(), method.getName());56 57 String resultType = "";58 if (void.class != method.getReturnType()) {59 resultType = " return ($r) ";60 }61 final String body = "{ " + resultType + " this.send((byte)" + commond.value() + ",$args); }";62 Class<?> returnType = method.getReturnType();63 CtMethod ctMethod = new CtMethod(classPool.get(returnType.getName()), method.getName(), JavassistHepler.toCtClassArray(method.getParameterTypes()), ctClass);64 ctMethod.setModifiers(method.getModifiers());65 ctMethod.setBody(body);66 ctClass.addMethod(ctMethod);67 }68 69 // 保存记录70 Class<?> ret = ctClass.toClass();71 ctClass.detach();72 SEND_CLASS.put(modelAnno.value(), ret);73 74 } catch (Exception e) {75 e.printStackTrace();76 }77 }78 79 public static QResult proxy(IRpcContext target, Object[] args, short model, byte commondIndex) {80 System.out.println("model : " + model + " commondIndex : " + commondIndex);81 return null;82 }
测试理论:
public class TestRpcSendProxy { @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(); } public static void main(String[] args) { QRpcFactory3.registerSendProxy(TestObject.class); TestObject proxy = QRpcFactory.loadSendProxy(TestObject.class, 1L); proxy.a(1, "b"); QResult<Integer> ret = proxy.getAge(); }}
由于发送处理涉及netty,先不考虑通信处理实现,在实现写框架过程,依赖越少实现越简单。所以每个实例对象构造出来时必须能正常工作
[编织消息框架][JAVA核心技术]动态代理应用7-实现设计
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。