本來是要看個開源項目的,結果看着看着就看到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());
}
}
}
}
}