阅读 10

Dubbo笔记(一)

Dubbo源码 从API方式配置开始

/**
 * 使用api的方式配置dubbo
 * ApiProviderConfiguration
 */
public class ApiProviderConfiguration {
	
	public static void main(String[] args) throws Exception {
		// 服务实现
		OrderService orderService = new OrderServiceImpl();

		// 当前应用配置。 请学习ApplicationConfig的API
		ApplicationConfig application = new ApplicationConfig();
		application.setName("hello-world-app");
		Map<String, String> appParameters = new HashMap<String, String>();
		appParameters.put("qos.enable", "false");
		application.setParameters(appParameters);

		// 连接注册中心配置。 请学习RegistryConfig的API
		RegistryConfig registry = new RegistryConfig("224.5.6.7:1234", "multicast");
		//registry.setDynamic(true);  // 动态注册,服务出现问题自动处理

		// 服务提供者协议配置
		ProtocolConfig protocol = new ProtocolConfig();
		protocol.setName("dubbo");
		protocol.setPort(12345);
		protocol.setThreads(200);

		// 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口
		// 服务提供者暴露服务配置。请学习ServiceConfig的API
		// 此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏
		ServiceConfig<OrderService> service = new ServiceConfig<OrderService>();
		service.setApplication(application);
		service.setRegistry(registry); // 多个注册中心可以用setRegistries()
		service.setProtocol(protocol); // 多个协议可以用setProtocols()
		service.setInterface(OrderService.class);
		service.setRef(orderService);
		service.setVersion("1.0.0");

		// 暴露及注册服务
		service.export(); //入口

		System.in.read(); // 按任意键退出
	}
}
复制代码

暴露服务,检查一些配置是不是为空

检查参数的

protected synchronized void doExport() {
        if (this.unexported) {
            throw new IllegalStateException("Already unexported!");
        } else if (!this.exported) {
            this.exported = true;
            if (this.interfaceName != null && this.interfaceName.length() != 0) {
                this.checkDefault();
                if (this.provider != null) {
                    if (this.application == null) {
                        this.application = this.provider.getApplication();
                    }

                    if (this.module == null) {
                        this.module = this.provider.getModule();
                    }

                    if (this.registries == null) {
                        this.registries = this.provider.getRegistries();
                    }

                    if (this.monitor == null) {
                        this.monitor = this.provider.getMonitor();
                    }

                    if (this.protocols == null) {
                        this.protocols = this.provider.getProtocols();
                    }
                }

                if (this.module != null) {
                    if (this.registries == null) {
                        this.registries = this.module.getRegistries();
                    }

                    if (this.monitor == null) {
                        this.monitor = this.module.getMonitor();
                    }
                }

                if (this.application != null) {
                    if (this.registries == null) {
                        this.registries = this.application.getRegistries();
                    }

                    if (this.monitor == null) {
                        this.monitor = this.application.getMonitor();
                    }
                }

                if (this.ref instanceof GenericService) {
                    this.interfaceClass = GenericService.class;
                    if (StringUtils.isEmpty(this.generic)) {
                        this.generic = Boolean.TRUE.toString();
                    }
                } else {
                    try {
                        this.interfaceClass = Class.forName(this.interfaceName, true, Thread.currentThread().getContextClassLoader());
                    } catch (ClassNotFoundException var5) {
                        throw new IllegalStateException(var5.getMessage(), var5);
                    }

                    this.checkInterfaceAndMethods(this.interfaceClass, this.methods);
                    this.checkRef();
                    this.generic = Boolean.FALSE.toString();
                }

                Class stubClass;
                if (this.local != null) {
                    if ("true".equals(this.local)) {
                        this.local = this.interfaceName + "Local";
                    }

                    try {
                        stubClass = ClassHelper.forNameWithThreadContextClassLoader(this.local);
                    } catch (ClassNotFoundException var4) {
                        throw new IllegalStateException(var4.getMessage(), var4);
                    }

                    if (!this.interfaceClass.isAssignableFrom(stubClass)) {
                        throw new IllegalStateException("The local implementation class " + stubClass.getName() + " not implement interface " + this.interfaceName);
                    }
                }

                if (this.stub != null) {
                    if ("true".equals(this.stub)) {
                        this.stub = this.interfaceName + "Stub";
                    }

                    try {
                        stubClass = ClassHelper.forNameWithThreadContextClassLoader(this.stub);
                    } catch (ClassNotFoundException var3) {
                        throw new IllegalStateException(var3.getMessage(), var3);
                    }

                    if (!this.interfaceClass.isAssignableFrom(stubClass)) {
                        throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + this.interfaceName);
                    }
                }

                this.checkApplication();
                this.checkRegistry();
                this.checkProtocol();
                appendProperties(this);
                this.checkStub(this.interfaceClass);
                this.checkMock(this.interfaceClass);
                if (this.path == null || this.path.length() == 0) {
                    this.path = this.interfaceName;
                }

                this.doExportUrls();//在到这里
                ProviderModel providerModel = new ProviderModel(this.getUniqueServiceName(), this, this.ref);
                ApplicationModel.initProviderModel(this.getUniqueServiceName(), providerModel);
            } else {
                throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");
            }
        }
    }
复制代码

在循环中,url协议头部改成registry,将注册中心作为参数放到后面。url就变成下面这样。

以上方法就是做了一个协议头的转换。因为Dubbo中URL是一个非常重要的契约,所有扩展点都要遵守。所有扩展点的参数都包含URL参数,URL作为上下文信息贯穿整个扩展点设计体系。URL采用标准格式:protocol://username:passward@host:port/path?key=value&key=value.

进入这个方法
往下看暴露服务的map信息

开始注册

代理工厂。关键地方,给了3个参数,ref(接口的具体实现),(Class)interfaceClass ,注册中心的url

Invoker<?> invoker = proxyFactory.getInvoker(this.ref, this.interfaceClass, registryURL.addParameterAndEncoded("export", url.toFullString()));
DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
Exporter<?> exporter =protocol.export(wrapperInvoker);
this.exporters.add(exporter);
复制代码

看下ProxyFactory的getExtensionLoader扩展加载器都私有化了。getAdaptiveExtension属于自适应扩展

private static final ProxyFactory proxyFactory = (ProxyFactory)ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
复制代码

SPI ExtensionLoader 扩展点加载器?做了什么?怎么做到自适应?

进到ProxyFactory接口中

配置信息

Invoker和Exporter

Invoker是实体域,Dubbo的核心模型,其他模型都向它靠拢或转换成它,它代表一个可以执行体。可以将所有需要代理的方法,用Invoker进行抽象,转换。

API与SPI

Dubbo框架有两类用户,框架使用者和扩展开发者。为对两类用户进行隔离,使用者通过API,开发者使用SPI。使用者无需从编码层面知道扩展的类型,只需配置即可;扩展着也能很方便的扩展功能,不需要考虑适应不同的编码场景。Dubbo没有采用JDK的SPI,而是自己实现了一套。

进入ExtensionLoader类

类似SpringIOC

通过class反射类来构造class对象实例,injectExtension方法通过setter注入扩展类中的依赖的其他扩展点。包装类Wrapper,封装了通用的逻辑,通过有无当前扩展参数构造函数来判断,并注入依赖扩展。

在crateExtension方法中的

Set<Class<?>> wrapperClasses = this.cachedWrapperClasses;
                Class wrapperClass;
                if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
                    for(Iterator i$ = wrapperClasses.iterator(); i$.hasNext(); instance = this.injectExtension(wrapperClass.getConstructor(this.type).newInstance(instance))) {
                        wrapperClass = (Class)i$.next();
                    }
                }

                return instance;
复制代码

重要 动态生成代码(类)createAdaptiveExtensionClassCode 只会在方法上起作用 具体生成的类。扩展点的类必须有@SPI类注解和@Adaptive方法注解才会动态生成代码。

import com.alibaba.dubbo.common.extension.ExtensionLoader;
public class ProxyFactory$Adaptive implements com.alibaba.dubbo.rpc.ProxyFactory {
public com.alibaba.dubbo.rpc.Invoker getInvoker(java.lang.Object arg0, java.lang.Class arg1, com.alibaba.dubbo.common.URL arg2) throws com.alibaba.dubbo.rpc.RpcException {
if (arg2 == null) throw new IllegalArgumentException("url == null");
com.alibaba.dubbo.common.URL url = arg2;
String extName = url.getParameter("proxy", "javassist");
if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);
return extension.getInvoker(arg0, arg1, arg2);
}
public java.lang.Object getProxy(com.alibaba.dubbo.rpc.Invoker arg0, boolean arg1) 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.getParameter("proxy", "javassist");
if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);
return extension.getProxy(arg0, arg1);
}
public java.lang.Object getProxy(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.getParameter("proxy", "javassist");
if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);
return extension.getProxy(arg0);
}
}
复制代码

生成类的class

再来看看扩展点的包装类

关注下面的标签,发现更多相似文章
评论