dubbo使用註解配置,客戶端(消費端)ReferenceConfig源碼簡析

本來是要看個開源項目的,結果看着看着就看到dubbo源碼裏面去了,吸引力太大了,哈哈~

1、如果是配置文件,在com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler完成類解析註冊,當spring掃描到標籤,會createbean,完成bean設置屬性
com.alibaba.dubbo.config.spring.ReferenceBean#afterPropertiesSet,這個方法會在整個spring的上下文中查找consumer還有application,而consumer和application已經通過spring的註解註冊到spring的上下文中了,這個referencebean在配置bean的時候需要獲取consumer就直接從上下文中獲取就可以了。
2、spring掃描使用了DubboComponentScan的註解,發現這個註解有使用@import實現了ImportBeanDefinitionRegistrar類,這個類註冊了ServiceAnnotationBeanPostProcessor和ReferenceAnnotationBeanPostProcessor,使用DubboClassPathBeanDefinitionScanner掃描指定包下的服務提供方或者reference。從名字看有annotation的內容可以知道,是使用註釋才用這兩個類分別實例化service和reference
3、com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildReferenceBean這個方法就是創建客戶端bean並放到spring上下文中,這裏面也是會調用到ReferenceBean#afterPropertiesSet進行bean的設置。客戶端也就是consumer在com.alibaba.dubbo.config.ReferenceConfig#init這裏進行bean的初始化com.alibaba.dubbo.config.ReferenceConfig#createProxy該方法就創建了客戶端代理類,插一句aop切面編程也是類似就是創建一個代理類,如果你要監控數據庫連接,執行了哪些語句也可以自己寫個代理。這裏createproxy會判斷當前refer是否與server在同一個服務端裏面,如果不是就需要到註冊中心去註冊。延伸一點如果說server和reference在一個jvm裏面,那麼如何保證順序呢,可以看到ReferenceAnnotationBeanPostProcessor實現了PriorityOrdered,並且設置了最低優先級可以保證如果server和reference在同一jvm裏先加載server。
 

//com.alibaba.dubbo.config.ReferenceConfig#createProxy創建代理有用到
invoker = refprotocol.refer(interfaceClass, url);//33.調用protocoladaptive的refer
//ReferenceConfig裏面成員變量
private static final Protocol refprotocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();//24.進一步獲取protocol的自適應擴展
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();第一步調用extensionloader,發現
if (loader == null) {
	EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));//
	//1.爲空然後創建擴展加載,類型爲interface com.alibaba.dubbo.rpc.Protocol;
	//2.進一步實例化extensionloader
	loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);//全局共用一個EXTENSION_LOADERS 23.將interface com.alibaba.dubbo.rpc.Protocol的擴展加載放入緩存
}
private ExtensionLoader(Class<?> type) {
	this.type = type;
	objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
	//3.進一步擴展ExtensionFactory,遞歸調用所以extensionfactory的對象工廠爲null,遞歸結束,獲取ExtensionFactory的extensionloader。每一個需要初始化的extension都會有一個extensionfactory作爲objectfactory,而這個extensionfactory就是spi文件指定的類
}

public T getAdaptiveExtension() {4.獲取ExtensionFactory的自適應擴展。
	Object instance = cachedAdaptiveInstance.get();//25.緩存的自適應實例爲空
	if (instance == null) {
		if (createAdaptiveInstanceError == null) {
			synchronized (cachedAdaptiveInstance) {
				instance = cachedAdaptiveInstance.get();
				if (instance == null) {
					try {
						instance = createAdaptiveExtension();5.創建ExtensionFactory自適應的擴展
						cachedAdaptiveInstance.set(instance);22.緩存自適應的實例 32.緩存protocol的緩存實例
					} catch (Throwable t) {
						createAdaptiveInstanceError = t;
						throw new IllegalStateException("fail to create adaptive instance: " + t.toString(), t);
					}
				}
			}
		} else {
			throw new IllegalStateException("fail to create adaptive instance: " + createAdaptiveInstanceError.toString(), createAdaptiveInstanceError);
		}
	}

	return (T) instance;
}

private T createAdaptiveExtension() {
	try {
		return injectExtension((T) getAdaptiveExtensionClass().newInstance());//5.1獲取到自適應擴展類爲AdaptiveExtensionFactory進一步實例化。
	} catch (Exception e) {
		throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);
	}
}

public AdaptiveExtensionFactory() {//5.2實例化擴展類
	ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);//5.3獲取擴展類加載器,此時可以獲取到擴展工廠的類
	List<ExtensionFactory> list = new ArrayList<ExtensionFactory>();
	//5.4支持的擴展放入工廠,目前支持如下工廠
	//spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
	//spring=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
	for (String name : loader.getSupportedExtensions()) {
		list.add(loader.getExtension(name));
	}
	factories = Collections.unmodifiableList(list);
}

private T injectExtension(T instance) {//20.注入擴展
	try {
		if (objectFactory != null) {
		//21.extensionfactory的對象工廠爲null,跳過 
		//31.執行注入,如果有set的執行賦值,可以看到protocol生成的adaptive沒有set方法 
		//41.執行registryprotocol的屬性注入,可以看下代碼registryprotocol有set方法的就會執行注入,此時的objectFactory是AdaptiveExtensionFactory
			for (Method method : instance.getClass().getMethods()) {
				if (method.getName().startsWith("set")
						&& method.getParameterTypes().length == 1
						&& Modifier.isPublic(method.getModifiers())) {
					Class<?> pt = method.getParameterTypes()[0];
					try {
						String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
						Object object = objectFactory.getExtension(pt, property);//42.從對象工廠AdaptiveExtensionFactory裏面查找某個屬性的擴展對象
						if (object != null) {
							method.invoke(instance, object);//46.以registryfactory爲例賦值屬性也是一個可自適應擴展的類
						}
					} catch (Exception e) {
						logger.error("fail to inject via method " + method.getName()
								+ " of interface " + type.getName() + ": " + e.getMessage(), e);
					}
				}
			}
		}
	} catch (Exception e) {
		logger.error(e.getMessage(), e);
	}
	return instance;
}

@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {

    private final List<ExtensionFactory> factories;

    public AdaptiveExtensionFactory() {
        ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
        List<ExtensionFactory> list = new ArrayList<ExtensionFactory>();
        for (String name : loader.getSupportedExtensions()) {
            list.add(loader.getExtension(name));
        }
        factories = Collections.unmodifiableList(list);
    }

    @Override
    public <T> T getExtension(Class<T> type, String name) {
	//43.從factories查找類型爲registryprotocol的set屬性的擴展,此時factories有SpiExtensionFactory和SpringExtensionFactory
        for (ExtensionFactory factory : factories) {
            T extension = factory.getExtension(type, name);//44.首先執行spi,以爲有順序的從spi開始
            if (extension != null) {
                return extension;
            }
        }
        return null;
    }

}

public class SpiExtensionFactory implements ExtensionFactory {

    @Override
    public <T> T getExtension(Class<T> type, String name) {
        if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
            ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);//
			//45.進一步查找registryfatory的自適應擴展,同protocol一樣,spi文件裏面沒有自適應擴展類,會代碼編譯生成一個匿名類,並返回給上層
            if (!loader.getSupportedExtensions().isEmpty()) {
                return loader.getAdaptiveExtension();
            }
        }
        return null;
    }

}

6.獲取自適應擴展類
private Class<?> getAdaptiveExtensionClass() {
	getExtensionClasses();
	//7.該方法執行loadextensionclasses時會初始化cachedAdaptiveClass爲AdaptiveExtensionFactory,因爲默認的spi文件中指定了adaptive類,反射加載完就知道了cachedAdaptiveClass
	if (cachedAdaptiveClass != null) {//28.加載完擴展類時,發現自適應類還是沒有找到
		return cachedAdaptiveClass;
	}
	return cachedAdaptiveClass = createAdaptiveExtensionClass();//29.這一步就是要生成自適應類
}


private Class<?> createAdaptiveExtensionClass() {
	String code = createAdaptiveExtensionClassCode();
	ClassLoader classLoader = findClassLoader();
	com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
	return compiler.compile(code, classLoader);//30.這一步會生成一個匿名類Protocol$Adaptive,這裏面又會進行一系列的編譯擴展加載,本次跳過
}

package com.alibaba.dubbo.rpc;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
public class Protocol$Adaptive implements com.alibaba.dubbo.rpc.Protocol {
	//但凡涉及到extensionloader,而spi文件沒有adaptive類的就會生成一段下面代碼。爲什麼這樣呢,之前做過的項目也用過spi,但是沒有這種動態加載,按需加載,一股腦都加載到應用中
	//反射實際是比較耗時的,這種按需加載,並且緩存加載的還是很高明的。特別是wrapper這種方式,也是一種aop。
	public void destroy() {
		throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
	}
	public int getDefaultPort() {
		throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
	}
	public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.RpcException {
		if (arg0 == null) 
			throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
		if (arg0.getUrl() == null) 
			throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");com.alibaba.dubbo.common.URL url = arg0.getUrl();
		String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
		if(extName == null) 
			throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
		com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
		
		return extension.export(arg0);
	}
	public com.alibaba.dubbo.rpc.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1) throws com.alibaba.dubbo.rpc.RpcException {
		if (arg1 == null) 
			throw new IllegalArgumentException("url == null");
		com.alibaba.dubbo.common.URL url = arg1;
		String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
		if(extName == null) 
			throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
		com.alibaba.dubbo.rpc.Protocol extension = 				(com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);34.查找loader,調用擴展
	
		return extension.refer(arg0, arg1);
	}
}

ExtensionLoader.java
public T getExtension(String name) {//35.根據名稱查找擴展,reference時name爲registry
	if (name == null || name.length() == 0)
		throw new IllegalArgumentException("Extension name == null");
	if ("true".equals(name)) {
		return getDefaultExtension();
	}
	Holder<Object> holder = cachedInstances.get(name);//36.從緩存中查找沒找到
	if (holder == null) {
		cachedInstances.putIfAbsent(name, new Holder<Object>());
		holder = cachedInstances.get(name);
	}
	Object instance = holder.get();
	if (instance == null) {
		synchronized (holder) {
			instance = holder.get();
			if (instance == null) {
				instance = createExtension(name);//37.根據名稱創建擴展
				holder.set(instance);
			}
		}
	}
	return (T) instance;
}

private T createExtension(String name) {//38.根據名稱,此時的名稱是registry創建extension,也就是RegistryProtocol的擴展
	Class<?> clazz = getExtensionClasses().get(name);
	if (clazz == null) {
		throw findException(name);
	}
	try {
		T instance = (T) EXTENSION_INSTANCES.get(clazz);
		if (instance == null) {
			EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());//39.實例化RegistryProtocol
			instance = (T) EXTENSION_INSTANCES.get(clazz);
		}
		injectExtension(instance);//40.給實例化的RegistryProtocol注入屬性
		Set<Class<?>> wrapperClasses = cachedWrapperClasses;
		//47.查看registryprotocol的wrapper類有哪些,就包含了ProtocolFilterWrapper,ProtocolListenerWrapper,QosProtocolWrapper
		if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
			for (Class<?> wrapperClass : wrapperClasses) {
				instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
				////48.同樣的進行wrapper的實例化和注入擴展屬性,這句代碼真的很繞啊,可以看到是個遞歸函數,只要有instance實例化,又會作爲下一個實例化構造函數的參數,
				////最後實例化出來的就是上面順序的最後一個wrapper的實例,牛逼啊,這波反射用的6
			}
		}
		return instance;
	} catch (Throwable t) {
		throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
				type + ")  could not be instantiated: " + t.getMessage(), t);
	}
}


 private Map<String, Class<?>> loadExtensionClasses() {
	final SPI defaultAnnotation = type.getAnnotation(SPI.class);//9.此時type爲extensionfactory  26.此時type爲protocol
	if (defaultAnnotation != null) {
		String value = defaultAnnotation.value();//10.如果extension有設置名字則設置緩存缺省名稱
		if ((value = value.trim()).length() > 0) {
			String[] names = NAME_SEPARATOR.split(value);
			if (names.length > 1) {
				throw new IllegalStateException("more than 1 default extension name on extension " + type.getName()
						+ ": " + Arrays.toString(names));
			}
			if (names.length == 1) cachedDefaultName = names[0];
		}
	}

	Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>();
	//private static final String SERVICES_DIRECTORY = "META-INF/services/";
    //private static final String DUBBO_DIRECTORY = "META-INF/dubbo/";
    //private static final String DUBBO_INTERNAL_DIRECTORY = DUBBO_DIRECTORY + "internal/";
	loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY);//11.從以下路徑加載擴展類  27.protocol時加載讀取com.alibaba.dubbo.rpc.Protocol文件加載類
	loadDirectory(extensionClasses, DUBBO_DIRECTORY);
	loadDirectory(extensionClasses, SERVICES_DIRECTORY);
	return extensionClasses;
	//28.
	//com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper是wrapper
	//com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper是wrapper
	//com.alibaba.dubbo.rpc.support.MockProtocol是extension
	//com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol是extension
	//com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol是extension
	//com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocol是extensi
	//com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol是extension
	//com.alibaba.dubbo.rpc.protocol.http.HttpProtocol是extension
	//com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocol是extension
	//com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol是extension
	//com.alibaba.dubbo.registry.integration.RegistryProtocol是extension
	//com.alibaba.dubbo.qos.protocol.QosProtocolWrapper是wrapper
}

//12.讀取以上擴展類的路徑
private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader, java.net.URL resourceURL) {
	try {
		BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), "utf-8"));
		try {
			String line;
			while ((line = reader.readLine()) != null) {
				final int ci = line.indexOf('#');
				if (ci >= 0) line = line.substring(0, ci);
				line = line.trim();
				if (line.length() > 0) {
					try {
						String name = null;
						int i = line.indexOf('=');
						if (i > 0) {
							name = line.substring(0, i).trim();
							line = line.substring(i + 1).trim();
						}
						if (line.length() > 0) {
							loadClass(extensionClasses, resourceURL, Class.forName(line, true, classLoader), name);
						}
					} catch (Throwable t) {
						IllegalStateException e = new IllegalStateException("Failed to load extension class(interface: " + type + ", class line: " + line + ") in " + resourceURL + ", cause: " + t.getMessage(), t);
						exceptions.put(line, e);
					}
				}
			}
		} finally {
			reader.close();
		}
	} catch (Throwable t) {
		logger.error("Exception when load extension class(interface: " +
				type + ", class file: " + resourceURL + ") in " + resourceURL, t);
	}
}
//extensionfactory 1.有以下三個實現
adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
spring=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory

//13.loadClass
private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name) throws NoSuchMethodException {
	if (!type.isAssignableFrom(clazz)) {//14.Determines if the class or interface represented by this,判斷clazz是不是type的實現
		throw new IllegalStateException("Error when load extension class(interface: " +
				type + ", class line: " + clazz.getName() + "), class "
				+ clazz.getName() + "is not subtype of interface.");
	}
	if (clazz.isAnnotationPresent(Adaptive.class)) {//15.是否是指定註釋的類
		if (cachedAdaptiveClass == null) {//16.緩存自適應類AdaptiveExtensionFactory,這個類擴展工廠可以看到沒有放到extensionClasses,cachedAdaptiveClass賦值
			cachedAdaptiveClass = clazz;
		} else if (!cachedAdaptiveClass.equals(clazz)) {//17.如果不一致,則拋出異常,也就是一系列的實現只能一個adaptive的
			throw new IllegalStateException("More than 1 adaptive class found: "
					+ cachedAdaptiveClass.getClass().getName()
					+ ", " + clazz.getClass().getName());
		}
	} else if (isWrapperClass(clazz)) {//18.是否是一個類的wrapper
		Set<Class<?>> wrappers = cachedWrapperClasses;
		if (wrappers == null) {
			cachedWrapperClasses = new ConcurrentHashSet<Class<?>>();
			wrappers = cachedWrapperClasses;
		}
		wrappers.add(clazz);
	} else {
		clazz.getConstructor();
		if (name == null || name.length() == 0) {//19.取實現類的名字
			name = findAnnotationName(clazz);
			if (name == null || name.length() == 0) {
				if (clazz.getSimpleName().length() > type.getSimpleName().length()
						&& clazz.getSimpleName().endsWith(type.getSimpleName())) {
					name = clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - type.getSimpleName().length()).toLowerCase();
				} else {
					throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
				}
			}
		}
		String[] names = NAME_SEPARATOR.split(name);
		if (names != null && names.length > 0) {
			Activate activate = clazz.getAnnotation(Activate.class);
			if (activate != null) {//20.擴展工廠沒有activate
				cachedActivates.put(names[0], activate);
			}
			for (String n : names) {//21.不能有重名的,有的話拋異常
				if (!cachedNames.containsKey(clazz)) {
					cachedNames.put(clazz, n);
				}
				Class<?> c = extensionClasses.get(n);
				if (c == null) {
					extensionClasses.put(n, clazz);
				} else if (c != clazz) {
					throw new IllegalStateException("Duplicate extension " + type.getName() + " name " + n + " on " + c.getName() + " and " + clazz.getName());
				}
			}
		}
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章