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要传入对象实例,生成实例即可
-
-
完成结果
-
此次更新的目的
- 利用反射实现功能,让用户可以根据自己的需要,选择启动的服务,不需要知道内部的源码亦或者其他东西,进行修改参数即可启动