此次遇到的問題是com.alibaba.dubbo.rpc.protocol.dubbo.telnet.InvokeTelnetHandler.findMethod中一個bug
遍歷全部方法時,首次匹配到方法名m.getName()和入參方法名method一致,且參數個數 m.getParameterTypes().length 同入參args.size()相同的方法,將invokeMethod設置爲此方法,而後繼續遍歷方法列表。立即 invokeMethod != null 後,再次發現方法名m.getName()和參數方法名method一致,且參數個數 m.getParameterTypes().length 同入參args.size()相同的方法時,應該判斷當前方法的參數m.getParameterTypes()和args是否匹配,而不是invokeMethod.getParameterTypes()和args是否匹配.spa
private static Method findMethod(Exporter<?> exporter, String method, List<Object> args) { Invoker<?> invoker = exporter.getInvoker(); Method[] methods = invoker.getInterface().getMethods(); Method invokeMethod = null; for (Method m : methods) { if (m.getName().equals(method) && m.getParameterTypes().length == args.size()) { if (invokeMethod != null) { // 重載 if (isMatch(invokeMethod.getParameterTypes(), args)) { invokeMethod = m; break; } } else { invokeMethod = m; } invoker = exporter.getInvoker(); } } return invokeMethod; } private static boolean isMatch(Class<?>[] types, List<Object> args) { if (types.length != args.size()) { return false; } for (int i = 0; i < types.length; i ++) { Class<?> type = types[i]; Object arg = args.get(i); if (ReflectUtils.isPrimitive(arg.getClass())) { if (! ReflectUtils.isPrimitive(type)) { return false; } } else if (arg instanceof Map) { String name = (String) ((Map<?, ?>)arg).get("class"); Class<?> cls = arg.getClass(); if (name != null && name.length() > 0) { cls = ReflectUtils.forName(name); } if (! type.isAssignableFrom(cls)) { return false; } } else if (arg instanceof Collection) { if (! type.isArray() && ! type.isAssignableFrom(arg.getClass())) { return false; } } else { if (! type.isAssignableFrom(arg.getClass())) { return false; } } } return true; }