dubboreference注解_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。

createProxy代理里面一个重要的是:

invoker = refprotocol.refer(interfaceClass, urls.get(0));这里创建invoker方法就是调用者,所有客户端的方法都被代理到这个invoker里面

return (T) proxyFactory.getProxy(invoker);这个里面根据反射动态代理接口的方法,这样当调用接口方法时,会交给上面的invoker里面去执行invoke这样就可以将客户端请求代理到服务端去了。

4、ReferenceConfig初始化成员变量的类扩展机制,虽然dubbo称这个类扩展为怪味道(不好的实现),不影响学习

//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(type));//

//1.为空然后创建扩展加载,类型为interface com.alibaba.dubbo.rpc.Protocol;

//2.进一步实例化extensionloader

loader = (ExtensionLoader) 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 loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);//5.3获取扩展类加载器,此时可以获取到扩展工厂的类

List list = new ArrayList();

//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 factories;

public AdaptiveExtensionFactory() {

ExtensionLoader loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);

List list = new ArrayList();

for (String name : loader.getSupportedExtensions()) {

list.add(loader.getExtension(name));

}

factories = Collections.unmodifiableList(list);

}

@Override

public T getExtension(Class 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 getExtension(Class type, String name) {

if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {

ExtensionLoader 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 holder = cachedInstances.get(name);//36.从缓存中查找没找到

if (holder == null) {

cachedInstances.putIfAbsent(name, new Holder());

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> 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> 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> extensionClasses = new HashMap>();

//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> 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> 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> wrappers = cachedWrapperClasses;

if (wrappers == null) {

cachedWrapperClasses = new ConcurrentHashSet>();

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());

}

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值