手写RPC框架(六)

v1.4

小更新

更新事项 暂定目标对启动类进行修改 直接集合

  • 这个就直接看代码吧 不是特别难 难的地方我会点出来

    • 启动引导类直接进行修改 可以传参 可以这样 当然 我想到了可以注解传参
      注解构造 注解构造

      package annotation;
      
      //两个参数分别代表的是什么方法和启用的数量
      
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      //注解在类上  然后根据方法获得对应的属性进行判断
      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface RpcMethodCluster {
          String[] method();
          int[] startNum();
      }
      
    • 调用类改造

      //通用启动类 将启动的逻辑藏在ServerBootStrap中
      //注解 看你像启动多少个服务和对应的方法
      @RpcMethodCluster(method = {"Hello","Bye"},startNum = {2,3})
      public class ServerCall {
          public static void main(String[] args) throws IOException, InterruptedException, KeeperException, NoSuchMethodException {
              ServerBootStrap.start();
          }
      }
      
    • 启动类改造

          public static void start() throws IOException, InterruptedException, KeeperException, NoSuchMethodException {
      
              //先对ZK进行初始化
              ZK.init();
              Class<ServerBootStrap> serverBootStrapClass = ServerBootStrap.class;
              RpcServerBootStrap annotation = serverBootStrapClass.getAnnotation(RpcServerBootStrap.class);
              //当前服务端启动器 class对象
              String currentServerBootStrapVersion = annotation.version();
      
              //获取对应的方法和个数 然后进行启动
              //1.获取对应方法 在获取对应的注解  注解中的属性
              RpcMethodCluster nowAnnotation = ServerCall.class.getAnnotation(RpcMethodCluster.class);
              String[] methods = nowAnnotation.method();
              int[] startNums = nowAnnotation.startNum();
              //如果不存在那就返回
              if (methods.length==0)return;
              //2.需要组合在一起传过去  如果不组合分别传 我怕就是端口号会出现问题
              StringBuilder methodBuilder = new StringBuilder();
              StringBuilder numBuilder = new StringBuilder();
              for (String method : methods) {
                  methodBuilder.append(method);
                  methodBuilder.append(",");
              }
              methodBuilder.deleteCharAt(methodBuilder.length()-1);
              for (int startNum : startNums) {
                  numBuilder.append(startNum);
                  numBuilder.append(",");
              }
              numBuilder.deleteCharAt(numBuilder.length()-1);
      
              switch (currentServerBootStrapVersion)
              {
                  case "1.0":
                      NIOProviderBootStrap10.main(null);
                      break;
                  case "1.1":
                      NIOProviderBootStrap11.main(null);
                      break;
                  case "1.2":
                      NIOProviderBootStrap12.main(null);
                      break;
                  case "1.4":
                      NIOProviderBootStrap14.main(new String[]{methodBuilder.toString(), numBuilder.toString()});
                      break;
                  default:
                      System.out.println("太着急了兄弟,这个版本还没出呢!要不你给我提个PR");
              }
          }
      }
      
    • 对应版本启动类改造

      public class NIOProviderBootStrap14 {
          static volatile int port = 6666;
          public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
              //对应的方法和对应的方法数量要启动多少 启动的端口不一样 不能写死 首先是
              String methodStr = args[0];
              String numStr = args[1];
              String[] methods = methodStr.split(",");
              String[] nums = numStr.split(",");
              //进行创建  可能会出问题 这边的端口
              for (int i = 0; i < methods.length; i++) {
                  String methodName = methods[i];
                  for (Integer methodNum = 0; methodNum < Integer.valueOf(nums[i]); methodNum++) {
                      new Thread(new Runnable() {
                          @Override
                          public void run() {
                              try {
                                  NIONonBlockingServer14.start(methodName,port++);
                              } catch (IOException e) {
                                  e.printStackTrace();
                              } catch (InterruptedException e) {
                                  e.printStackTrace();
                              } catch (KeeperException e) {
                                  e.printStackTrace();
                              }
                          }
                      }).start();
                  }
              }
          }
      }
      
    • 真正服务功能调用类改造

      //这里要有新逻辑了 根据获得的方法名 去找到相应的方法
      //方法我们保存在固定位置 同时含有固定后缀
      String className = method + "ServiceImpl";
      Class<?> methodClass = Class.forName("provider.api."+className);
      //实例 要获取对应的实例 或者子对象才能进行反射执行方法
      Object instance = methodClass.newInstance();
      
      //要传入参数的类型
      String response = (String) methodClass.
          getMethod("say" + method,String.class).
          invoke(instance, msg);
      
  • 问题

    • 出了bug 客户端连接上直接掉线 正在排查 原因是服务提供端的问题:Class.forName()找不到对应的类报了异常ClassNotFoundException 解决:类名和路径名不一样,用.隔开而不是/,同时注意包从src.java之后开始 这之前放着会有一定的问题

    • 解决上面的问题又出现bug 说方法找不到,因为我的方法是有参构造,我忘记传参数了

    • 还有问题 就是invoke要传入对象实例,生成实例即可

  • 完成结果

  • 此次更新的目的

    1. 利用反射实现功能,让用户可以根据自己的需要,选择启动的服务,不需要知道内部的源码亦或者其他东西,进行修改参数即可启动
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值