目標:介紹遠程調用代理的設計和實現,介紹dubbo-rpc-api中的各類proxy包的源碼。
首先聲明叫作代理,代理在不少領域都存在,最形象的就是如今朋友圈的微商代理,廠家委託代理幫他們賣東西。這樣作廠家對於消費者來講就是透明的,而且代理能夠本身加上一些活動或者銷售措施,但這並不影響到廠家。這裏的廠家就是委託類,而代理就能夠抽象爲代理類。這樣作有兩個優勢,第一是能夠隱藏代理類的實現,第二就是委託類和調用方的解耦,而且可以在不修改委託類本來的邏輯狀況下新增一些額外的處理。html
代理分爲兩種,靜態代理和動態代理。java
上述稍微回顧了一下靜態代理和動態代理,那麼dubbo對於動態代理有兩種方法實現,分別是javassist和jdk。Proxy 層封裝了全部接口的透明化代理,而在其它層都以 Invoker 爲中心,只有到了暴露給用戶使用時,才用 Proxy 將 Invoker 轉成接口,或將接口實現轉成 Invoker,也就是去掉 Proxy 層 RPC 是能夠 Run 的,只是不那麼透明,不那麼看起來像調本地服務同樣調遠程服務。咱們來看看下面的圖:git
咱們能看到左邊是消費者的調用鏈,只有當消費者調用的時候,ProxyFactory纔會經過Proxy把接口實現轉化爲invoker,而且在其餘層的調用都使用的是invoker,一樣的道理,在服務提供者暴露服務的時候,也只有在最後暴露給消費者的時候纔會經過Proxy 將 Invoker 轉成接口。github
動態代理的底層原理就是字節碼技術,dubbo提供了兩種方式來實現代理:apache
該類是代理工廠的抽象類,主要處理了一下須要代理的接口,而後把代理getProxy方法抽象出來。api
public abstract class AbstractProxyFactory implements ProxyFactory { @Override public <T> T getProxy(Invoker<T> invoker) throws RpcException { return getProxy(invoker, false); } @Override public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException { Class<?>[] interfaces = null; // 得到須要代理的接口 String config = invoker.getUrl().getParameter("interfaces"); if (config != null && config.length() > 0) { // 根據逗號把每一個接口分割開 String[] types = Constants.COMMA_SPLIT_PATTERN.split(config); if (types != null && types.length > 0) { // 建立接口類型數組 interfaces = new Class<?>[types.length + 2]; // 第一個放invoker的服務接口 interfaces[0] = invoker.getInterface(); // 第二個位置放回聲測試服務的接口類 interfaces[1] = EchoService.class; // 其餘接口循環放入 for (int i = 0; i < types.length; i++) { interfaces[i + 1] = ReflectUtils.forName(types[i]); } } } // 若是接口爲空,就是config爲空,則是回聲測試 if (interfaces == null) { interfaces = new Class<?>[]{invoker.getInterface(), EchoService.class}; } // 若是是泛化服務,那麼在代理的接口集合中加入泛化服務類型 if (!invoker.getInterface().equals(GenericService.class) && generic) { int len = interfaces.length; Class<?>[] temp = interfaces; interfaces = new Class<?>[len + 1]; System.arraycopy(temp, 0, interfaces, 0, len); interfaces[len] = GenericService.class; } // 得到代理 return getProxy(invoker, interfaces); } public abstract <T> T getProxy(Invoker<T> invoker, Class<?>[] types); }
邏輯比較簡單,就是處理了url中攜帶的interfaces的值。數組
該類實現了Invoker接口,是代理invoker對象的抽象類。緩存
@Override public Result invoke(Invocation invocation) throws RpcException { try { // 調用了抽象方法doInvoke return new RpcResult(doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments())); } catch (InvocationTargetException e) { return new RpcResult(e.getTargetException()); } catch (Throwable e) { throw new RpcException("Failed to invoke remote proxy method " + invocation.getMethodName() + " to " + getUrl() + ", cause: " + e.getMessage(), e); } } protected abstract Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable;
該類最關鍵的就是這兩個方法,一個是invoke方法,調用了抽象方法doInvoke,另外一個則是抽象方法。該方法被子類實現。app
該類實現了InvocationHandler接口,動態代理類都必需要實現InvocationHandler接口,而該類實現的是對於基礎方法不適用rpc調用,其餘方法使用rpc調用。ide
public class InvokerInvocationHandler implements InvocationHandler { private final Invoker<?> invoker; public InvokerInvocationHandler(Invoker<?> handler) { this.invoker = handler; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 得到方法名 String methodName = method.getName(); // 得到參數類型 Class<?>[] parameterTypes = method.getParameterTypes(); // 若是方法參數類型是object類型,則直接反射調用 if (method.getDeclaringClass() == Object.class) { return method.invoke(invoker, args); } // 基礎方法,不使用 RPC 調用 if ("toString".equals(methodName) && parameterTypes.length == 0) { return invoker.toString(); } if ("hashCode".equals(methodName) && parameterTypes.length == 0) { return invoker.hashCode(); } if ("equals".equals(methodName) && parameterTypes.length == 1) { return invoker.equals(args[0]); } // rpc調用 return invoker.invoke(new RpcInvocation(method, args)).recreate(); } }
該類實現了本地存根的邏輯,關於本地存根的概念和使用在官方文檔中都有詳細說明。
地址: http://dubbo.apache.org/zh-cn...
public class StubProxyFactoryWrapper implements ProxyFactory { private static final Logger LOGGER = LoggerFactory.getLogger(StubProxyFactoryWrapper.class); /** * 代理工廠 */ private final ProxyFactory proxyFactory; /** * 協議 */ private Protocol protocol; public StubProxyFactoryWrapper(ProxyFactory proxyFactory) { this.proxyFactory = proxyFactory; } public void setProtocol(Protocol protocol) { this.protocol = protocol; } @Override public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException { return proxyFactory.getProxy(invoker, generic); } @Override @SuppressWarnings({"unchecked", "rawtypes"}) public <T> T getProxy(Invoker<T> invoker) throws RpcException { // 得到代理類對象 T proxy = proxyFactory.getProxy(invoker); // 若是不是返回服務調用 if (GenericService.class != invoker.getInterface()) { // 得到stub的配置 String stub = invoker.getUrl().getParameter(Constants.STUB_KEY, invoker.getUrl().getParameter(Constants.LOCAL_KEY)); // 若是配置不爲空 if (ConfigUtils.isNotEmpty(stub)) { Class<?> serviceType = invoker.getInterface(); if (ConfigUtils.isDefault(stub)) { // 根據local和stub來生成stub if (invoker.getUrl().hasParameter(Constants.STUB_KEY)) { stub = serviceType.getName() + "Stub"; } else { stub = serviceType.getName() + "Local"; } } try { // 生成stub類 Class<?> stubClass = ReflectUtils.forName(stub); if (!serviceType.isAssignableFrom(stubClass)) { throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + serviceType.getName()); } try { // 得到構造方法,該構造方法必須是帶有代理的對象的參數 Constructor<?> constructor = ReflectUtils.findConstructor(stubClass, serviceType); // 使用指定的初始化參數建立和初始化構造函數聲明類的新實例 proxy = (T) constructor.newInstance(new Object[]{proxy}); //export stub service URL url = invoker.getUrl(); if (url.getParameter(Constants.STUB_EVENT_KEY, Constants.DEFAULT_STUB_EVENT)) { url = url.addParameter(Constants.STUB_EVENT_METHODS_KEY, StringUtils.join(Wrapper.getWrapper(proxy.getClass()).getDeclaredMethodNames(), ",")); url = url.addParameter(Constants.IS_SERVER_KEY, Boolean.FALSE.toString()); try { // 暴露stub服務 export(proxy, (Class) invoker.getInterface(), url); } catch (Exception e) { LOGGER.error("export a stub service error.", e); } } } catch (NoSuchMethodException e) { throw new IllegalStateException("No such constructor \"public " + stubClass.getSimpleName() + "(" + serviceType.getName() + ")\" in stub implementation class " + stubClass.getName(), e); } } catch (Throwable t) { LOGGER.error("Failed to create stub implementation class " + stub + " in consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", cause: " + t.getMessage(), t); // ignore } } } return proxy; } @Override public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException { return proxyFactory.getInvoker(proxy, type, url); } private <T> Exporter<T> export(T instance, Class<T> type, URL url) { return protocol.export(proxyFactory.getInvoker(instance, type, url)); }
該類裏面最重要的就是getProxy方法的實現,在該方法中先根據配置生成加載stub服務類,而後經過構造方法將代理的對象進行包裝,最後暴露該服務,而後返回代理類對象。
該類繼承了AbstractProxyFactory,是jdk的代理工廠的主要邏輯。
public class JdkProxyFactory extends AbstractProxyFactory { @Override @SuppressWarnings("unchecked") public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) { // 調用了 Proxy.newProxyInstance直接得到代理類 return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker)); } @Override public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) { // 建立AbstractProxyInvoker對象 return new AbstractProxyInvoker<T>(proxy, type, url) { @Override protected Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable { // 反射得到方法 Method method = proxy.getClass().getMethod(methodName, parameterTypes); // 執行方法 return method.invoke(proxy, arguments); } }; } }
不過邏輯實現比較簡單,由於jdk中都封裝好了,直接調用Proxy.newProxyInstance方法就能夠得到代理類。
該類是基於Javassist實現的動態代理工廠類。
public class JavassistProxyFactory extends AbstractProxyFactory { @Override @SuppressWarnings("unchecked") public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) { // 建立代理 return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker)); } @Override public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) { // TODO Wrapper cannot handle this scenario correctly: the classname contains '$' // 建立Wrapper對象 final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type); return new AbstractProxyInvoker<T>(proxy, type, url) { @Override protected Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable { // 調用方法 return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments); } }; } }
在這裏看不出什麼具體的實現,感受看起來跟JdkProxyFactory差很少,下面我將講解com.alibaba.dubbo.common.bytecode.Proxy類的getProxy方法和com.alibaba.dubbo.common.bytecode.Wrapper類的getWrapper方法。
public static Proxy getProxy(Class<?>... ics) { // 得到代理類 return getProxy(ClassHelper.getClassLoader(Proxy.class), ics); } /** * Get proxy. * * @param cl class loader. * @param ics interface class array. * @return Proxy instance. */ public static Proxy getProxy(ClassLoader cl, Class<?>... ics) { // 最大的代理接口數限制是65535 if (ics.length > 65535) throw new IllegalArgumentException("interface limit exceeded"); StringBuilder sb = new StringBuilder(); // 遍歷代理接口,獲取接口的全限定名並以分號分隔鏈接成字符串 for (int i = 0; i < ics.length; i++) { // 得到類名 String itf = ics[i].getName(); // 判斷是否爲接口 if (!ics[i].isInterface()) throw new RuntimeException(itf + " is not a interface."); Class<?> tmp = null; try { // 得到與itf對應的Class對象 tmp = Class.forName(itf, false, cl); } catch (ClassNotFoundException e) { } // 若是經過類名得到的類型跟ics中的類型不同,則拋出異常 if (tmp != ics[i]) throw new IllegalArgumentException(ics[i] + " is not visible from class loader"); // 拼接類 sb.append(itf).append(';'); } // use interface class name list as key. String key = sb.toString(); // get cache by class loader. Map<String, Object> cache; synchronized (ProxyCacheMap) { // 經過類加載器得到緩存 cache = ProxyCacheMap.get(cl); if (cache == null) { cache = new HashMap<String, Object>(); ProxyCacheMap.put(cl, cache); } } Proxy proxy = null; synchronized (cache) { do { Object value = cache.get(key); // 若是緩存中存在,則直接返回代理對象 if (value instanceof Reference<?>) { proxy = (Proxy) ((Reference<?>) value).get(); if (proxy != null) return proxy; } // 是等待生成的類型,則等待 if (value == PendingGenerationMarker) { try { cache.wait(); } catch (InterruptedException e) { } } else { // 不然放入緩存中 cache.put(key, PendingGenerationMarker); break; } } while (true); } // AtomicLong自增生成代理類類名後綴id,防止衝突 long id = PROXY_CLASS_COUNTER.getAndIncrement(); String pkg = null; ClassGenerator ccp = null, ccm = null; try { ccp = ClassGenerator.newInstance(cl); Set<String> worked = new HashSet<String>(); List<Method> methods = new ArrayList<Method>(); for (int i = 0; i < ics.length; i++) { // 判斷是否爲public if (!Modifier.isPublic(ics[i].getModifiers())) { // 得到該類的包名 String npkg = ics[i].getPackage().getName(); if (pkg == null) { pkg = npkg; } else { if (!pkg.equals(npkg)) throw new IllegalArgumentException("non-public interfaces from different packages"); } } // 把接口加入到ccp的mInterfaces中 ccp.addInterface(ics[i]); // 遍歷每一個類的方法 for (Method method : ics[i].getMethods()) { // 得到方法描述 這個方法描述是自定義: // 例如:int do(int arg1) => "do(I)I" // 例如:void do(String arg1,boolean arg2) => "do(Ljava/lang/String;Z)V" String desc = ReflectUtils.getDesc(method); if (worked.contains(desc)) continue; // 若是集合中不存在,則加入該描述 worked.add(desc); int ix = methods.size(); // 得到方法返回類型 Class<?> rt = method.getReturnType(); // 得到方法參數類型 Class<?>[] pts = method.getParameterTypes(); // 新建一句代碼 // 例如Object[] args = new Object[參數數量】 StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];"); // 每個參數都生成一句代碼 // 例如args[0] = ($w)$1; // 例如 Object ret = handler.invoke(this, methods[3], args); for (int j = 0; j < pts.length; j++) code.append(" args[").append(j).append("] = ($w)$").append(j + 1).append(";"); code.append(" Object ret = handler.invoke(this, methods[" + ix + "], args);"); // 若是方法不是void類型 // 則拼接 return ret; if (!Void.TYPE.equals(rt)) code.append(" return ").append(asArgument(rt, "ret")).append(";"); methods.add(method); ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString()); } } if (pkg == null) pkg = PACKAGE_NAME; // create ProxyInstance class. String pcn = pkg + ".proxy" + id; ccp.setClassName(pcn); // 添加靜態字段Method[] methods ccp.addField("public static java.lang.reflect.Method[] methods;"); ccp.addField("private " + InvocationHandler.class.getName() + " handler;"); // 添加實例對象InvokerInvocationHandler hanler,添加參數爲InvokerInvocationHandler的構造器 ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{InvocationHandler.class}, new Class<?>[0], "handler=$1;"); // 添加默認無參構造器 ccp.addDefaultConstructor(); // 使用toClass方法生成對應的字節碼 Class<?> clazz = ccp.toClass(); clazz.getField("methods").set(null, methods.toArray(new Method[0])); // create Proxy class. // 生成的字節碼對象爲服務接口的代理對象 String fcn = Proxy.class.getName() + id; ccm = ClassGenerator.newInstance(cl); ccm.setClassName(fcn); ccm.addDefaultConstructor(); ccm.setSuperClass(Proxy.class); ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }"); Class<?> pc = ccm.toClass(); proxy = (Proxy) pc.newInstance(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } finally { // release ClassGenerator // 重置類構造器 if (ccp != null) ccp.release(); if (ccm != null) ccm.release(); synchronized (cache) { if (proxy == null) cache.remove(key); else cache.put(key, new WeakReference<Proxy>(proxy)); cache.notifyAll(); } } return proxy; }
Proxy是是生成代理對象的工具類,跟JdkProxyFactory中用到的Proxy不是同一個,JdkProxyFactory中的是jdk自帶的java.lang.reflect.Proxy。而該Proxy是dubbo基於javassit實現的com.alibaba.dubbo.common.bytecode.Proxy。該方法比較長,能夠分開五個步驟來看:
public static Wrapper getWrapper(Class<?> c) { // 判斷c是否繼承 ClassGenerator.DC.class ,若是是,則拿到父類,避免重複包裝 while (ClassGenerator.isDynamicClass(c)) // can not wrapper on dynamic class. c = c.getSuperclass(); // 若是類爲object類型 if (c == Object.class) return OBJECT_WRAPPER; // 若是緩存裏面沒有該對象,則新建一個wrapper Wrapper ret = WRAPPER_MAP.get(c); if (ret == null) { ret = makeWrapper(c); WRAPPER_MAP.put(c, ret); } return ret; } private static Wrapper makeWrapper(Class<?> c) { // 若是c不是似有類,則拋出異常 if (c.isPrimitive()) throw new IllegalArgumentException("Can not create wrapper for primitive type: " + c); // 得到類名 String name = c.getName(); // 得到類加載器 ClassLoader cl = ClassHelper.getClassLoader(c); // 設置屬性的方法第一行public void setPropertyValue(Object o, String n, Object v){ StringBuilder c1 = new StringBuilder("public void setPropertyValue(Object o, String n, Object v){ "); // 得到屬性的方法第一行 public Object getPropertyValue(Object o, String n){ StringBuilder c2 = new StringBuilder("public Object getPropertyValue(Object o, String n){ "); // 執行方法的第一行 StringBuilder c3 = new StringBuilder("public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws " + InvocationTargetException.class.getName() + "{ "); // 添加每一個方法中被調用對象的類型轉換的代碼 c1.append(name).append(" w; try{ w = ((").append(name).append(")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }"); c2.append(name).append(" w; try{ w = ((").append(name).append(")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }"); c3.append(name).append(" w; try{ w = ((").append(name).append(")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }"); Map<String, Class<?>> pts = new HashMap<String, Class<?>>(); // <property name, property types> Map<String, Method> ms = new LinkedHashMap<String, Method>(); // <method desc, Method instance> List<String> mns = new ArrayList<String>(); // method names. List<String> dmns = new ArrayList<String>(); // declaring method names. // get all public field. // 遍歷每一個public的屬性,放入setPropertyValue和getPropertyValue方法中 for (Field f : c.getFields()) { String fn = f.getName(); Class<?> ft = f.getType(); // // 排除有static 和 transient修飾的屬性 if (Modifier.isStatic(f.getModifiers()) || Modifier.isTransient(f.getModifiers())) continue; c1.append(" if( $2.equals(\"").append(fn).append("\") ){ w.").append(fn).append("=").append(arg(ft, "$3")).append("; return; }"); c2.append(" if( $2.equals(\"").append(fn).append("\") ){ return ($w)w.").append(fn).append("; }"); pts.put(fn, ft); } Method[] methods = c.getMethods(); // get all public method. boolean hasMethod = hasMethods(methods); // 在invokeMethod方法中添加try的代碼 if (hasMethod) { c3.append(" try{"); } // 遍歷方法 for (Method m : methods) { // 忽律Object的方法 if (m.getDeclaringClass() == Object.class) //ignore Object's method. continue; // 判斷方法名和方法參數長度 String mn = m.getName(); c3.append(" if( \"").append(mn).append("\".equals( $2 ) "); // 方法參數長度 int len = m.getParameterTypes().length; // 判斷方法參數長度代碼 c3.append(" && ").append(" $3.length == ").append(len); // 若相同方法名存在多個,增長參數類型數組的比較判斷 boolean override = false; for (Method m2 : methods) { if (m != m2 && m.getName().equals(m2.getName())) { override = true; break; } } if (override) { if (len > 0) { for (int l = 0; l < len; l++) { c3.append(" && ").append(" $3[").append(l).append("].getName().equals(\"") .append(m.getParameterTypes()[l].getName()).append("\")"); } } } c3.append(" ) { "); // 若是返回類型是void,則return null,若是不是,則返回對應參數類型 if (m.getReturnType() == Void.TYPE) c3.append(" w.").append(mn).append('(').append(args(m.getParameterTypes(), "$4")).append(");").append(" return null;"); else c3.append(" return ($w)w.").append(mn).append('(').append(args(m.getParameterTypes(), "$4")).append(");"); c3.append(" }"); mns.add(mn); if (m.getDeclaringClass() == c) dmns.add(mn); ms.put(ReflectUtils.getDesc(m), m); } if (hasMethod) { c3.append(" } catch(Throwable e) { "); c3.append(" throw new java.lang.reflect.InvocationTargetException(e); "); c3.append(" }"); } c3.append(" throw new " + NoSuchMethodException.class.getName() + "(\"Not found method \\\"\"+$2+\"\\\" in class " + c.getName() + ".\"); }"); // 處理get set方法 // deal with get/set method. Matcher matcher; for (Map.Entry<String, Method> entry : ms.entrySet()) { String md = entry.getKey(); Method method = (Method) entry.getValue(); if ((matcher = ReflectUtils.GETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) { String pn = propertyName(matcher.group(1)); c2.append(" if( $2.equals(\"").append(pn).append("\") ){ return ($w)w.").append(method.getName()).append("(); }"); pts.put(pn, method.getReturnType()); } else if ((matcher = ReflectUtils.IS_HAS_CAN_METHOD_DESC_PATTERN.matcher(md)).matches()) { String pn = propertyName(matcher.group(1)); c2.append(" if( $2.equals(\"").append(pn).append("\") ){ return ($w)w.").append(method.getName()).append("(); }"); pts.put(pn, method.getReturnType()); } else if ((matcher = ReflectUtils.SETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) { Class<?> pt = method.getParameterTypes()[0]; String pn = propertyName(matcher.group(1)); c1.append(" if( $2.equals(\"").append(pn).append("\") ){ w.").append(method.getName()).append("(").append(arg(pt, "$3")).append("); return; }"); pts.put(pn, pt); } } c1.append(" throw new " + NoSuchPropertyException.class.getName() + "(\"Not found property \\\"\"+$2+\"\\\" filed or setter method in class " + c.getName() + ".\"); }"); c2.append(" throw new " + NoSuchPropertyException.class.getName() + "(\"Not found property \\\"\"+$2+\"\\\" filed or setter method in class " + c.getName() + ".\"); }"); // make class long id = WRAPPER_CLASS_COUNTER.getAndIncrement(); ClassGenerator cc = ClassGenerator.newInstance(cl); cc.setClassName((Modifier.isPublic(c.getModifiers()) ? Wrapper.class.getName() : c.getName() + "$sw") + id); cc.setSuperClass(Wrapper.class); // 增長無參構造器 cc.addDefaultConstructor(); // 添加屬性 cc.addField("public static String[] pns;"); // property name array. cc.addField("public static " + Map.class.getName() + " pts;"); // property type map. cc.addField("public static String[] mns;"); // all method name array. cc.addField("public static String[] dmns;"); // declared method name array. for (int i = 0, len = ms.size(); i < len; i++) cc.addField("public static Class[] mts" + i + ";"); // 添加屬性相關的方法 cc.addMethod("public String[] getPropertyNames(){ return pns; }"); cc.addMethod("public boolean hasProperty(String n){ return pts.containsKey($1); }"); cc.addMethod("public Class getPropertyType(String n){ return (Class)pts.get($1); }"); cc.addMethod("public String[] getMethodNames(){ return mns; }"); cc.addMethod("public String[] getDeclaredMethodNames(){ return dmns; }"); cc.addMethod(c1.toString()); cc.addMethod(c2.toString()); cc.addMethod(c3.toString()); try { // 生成字節碼 Class<?> wc = cc.toClass(); // setup static field. // 反射,設置靜態變量的值 wc.getField("pts").set(null, pts); wc.getField("pns").set(null, pts.keySet().toArray(new String[0])); wc.getField("mns").set(null, mns.toArray(new String[0])); wc.getField("dmns").set(null, dmns.toArray(new String[0])); int ix = 0; for (Method m : ms.values()) wc.getField("mts" + ix++).set(null, m.getParameterTypes()); // // 建立對象而且返回 return (Wrapper) wc.newInstance(); } catch (RuntimeException e) { throw e; } catch (Throwable e) { throw new RuntimeException(e.getMessage(), e); } finally { cc.release(); ms.clear(); mns.clear(); dmns.clear(); } }
Wrapper是用於建立某個對象的方法調用的包裝器,利用字節碼技術在調用方法時進行編譯相關方法。其中getWrapper就是得到Wrapper 對象,其中關鍵的是makeWrapper方法,因此我在上面加上了makeWrapper方法的解釋,其中就是相關方法的字節碼生成過程。
該部分相關的源碼解析地址: https://github.com/CrazyHZM/i...
該文章講解了遠程調用中關於代理的部分,關鍵部分在於基於javassist實現的字節碼技術來支撐動態代理。接下來我將開始對rpc模塊的dubbo-rpc-dubbo關於dubbo協議部分進行講解。