• [编织消息框架][JAVA核心技术]动态代理应用7-IRpcSend实现


    根据设计生成两个接口,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);
    }
     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 }
    QRpcFactory
     1 public static void registerSendProxy(Class<?> target) {
     2     if (!target.isInterface()) {
     3         throw new RuntimeException("class is not  Interface : " + target);
     4     }
     5     QModel modelAnno = ReflectUtil.getAnno(target, QModel.class);
     6     String proxyClassName = target.getCanonicalName() + "$$send$$";
     7     ClassPool classPool = JavassistHepler.classPool;
     8     CtClass ctClass = classPool.makeClass(proxyClassName);
     9 
    10     try {
    11         // 设置接口
    12         CtClass[] interfaces = new CtClass[3];
    13         interfaces[0] = classPool.get(target.getName());
    14         interfaces[1] = classPool.get(IRpcSend.class.getName());
    15         interfaces[2] = classPool.get(IRpcContext.class.getName());
    16         ctClass.setInterfaces(interfaces);
    17 
    18         {
    19             // 添加ctx字段
    20             final String ctxName = RpcContext.class.getName();
    21             CtField ctField = new CtField(classPool.get(ctxName), "ctx", ctClass);
    22             ctField.setModifiers(Modifier.PRIVATE);
    23             ctClass.addField(ctField);
    24             // 添加ctx get set 方法
    25             CtMethod ctMethod = CtMethod.make("public " + ctxName + " getContext(){return ctx;}", ctClass);
    26             ctMethod.setModifiers(Modifier.PUBLIC);
    27             ctClass.addMethod(ctMethod);
    28 
    29             ctMethod = CtMethod.make("public void setContext(" + ctxName + " value){ ctx =value;}", ctClass);
    30             ctMethod.setModifiers(Modifier.PUBLIC);
    31             ctClass.addMethod(ctMethod);
    32         }
    33 
    34         // 生成send method 调用静态方法减少书写复杂
    35         {
    36           37            38             final String body = " return ($r){ " + resultType + QRpcFactory.class.getName() + ".proxySend(this,$2, (short)" + modelAnno.value() + "  ,(byte) $1);}";
    39             JavassistHepler.addMethod(ctClass, SEND_METHOD, body);
    40         }
    41 
    42         // 生成代理方法
    43         for (Method method : target.getDeclaredMethods()) {
    44             QCommond commond = method.getAnnotation(QCommond.class);
    45             if (commond == null) {
    46                 continue;
    47             }
    48 
    49             String resultType = "";
    50             if (void.class != method.getReturnType()) {
    51                 resultType = " return ($r) ";
    52             }
    53             final String body = "{ " + resultType + " this.send((byte)" + commond.value() + ",$args); }";
    54             JavassistHepler.addMethod(ctClass, method, body);
    55         }
    56 
    57         // 保存记录
    58         Class<?> newClass = ctClass.toClass();
    59         ctClass.detach();
    60         SEND_CLASS.put(modelAnno.value(), newClass);
    61 
    62     } catch (Exception e) {
    63         e.printStackTrace();
    64     }
    65 }
    66 public static QResult proxySend(IRpcContext target, Object[] args, short model, byte commondIndex) {
    67     System.out.println("model : " + model + " commondIndex : " + commondIndex);
    68     return null;
    69 }

    测试理论:

        @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,先不考虑通信处理实现,在实现写框架过程,依赖越少实现越简单。所以每个实例对象构造出来时必须能正常工作

  • 相关阅读:
    CF117C Cycle (竞赛图找环)
    P1144 最短路计数 (bfs/SPFA)
    RabbitMQ.Client API (.NET)中文文档
    四元组
    .Net Standard Http请求实例
    .Net Standard简介
    Lambda表达式(lambda expression)⭐⭐⭐⭐⭐
    CSS
    工具类css框架
    Sass
  • 原文地址:https://www.cnblogs.com/solq111/p/6688615.html
Copyright © 2020-2023  润新知