dubbo 2標籤解析 ServiceBean 生產者服務暴漏過程
二、dubbo標籤解析
com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
}
三、ServiceBean<T> 生產者服務暴漏過程,<dubbo:service>標籤最終解析成了ServiceBean。
1、 ServiceConfig 的export方法爲暴漏服務的方法。
private void doExportUrls() {
List<URL> registryURLs = loadRegistries(true);
//loadRegistries檢查了註冊中心,如果存在設置了URL的Protocol爲registry
// url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
//可以配置多協議暴漏
for (ProtocolConfig protocolConfig : protocols) {
doExportUrlsFor1Protocol(protocolConfig, registryURLs);
}
}
2、 doExportUrlsFor1Protocol中
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
//生成了invoker,默認使用JavassistProxyFactory
Exporter<?> exporter = protocol.export(invoker);
exporters.add(exporter);
這個protocol使用的是Adaptive的,而這個invoker.url.protocol爲registry,所以實際會得到RegistryProtocol
再加上wrapper則會得到ProtocolListenerWrapper->ProtocolFilterWrapper->RegistryProtocol
3、ProtocolListenerWrapper和ProtocolFilterWrapper在export方法中對registry類型的直接通過
ProtocolFilterWrapper
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
return protocol.export(invoker);
}
return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
}
到了RegistryProtocol的export
//export invoker
final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);
doLocalExport中
final Invoker<?> invokerDelegete = new InvokerDelegete<T>(originInvoker, getProviderUrl(originInvoker));
exporter = new ExporterChangeableWrapper<T>((Exporter<T>)protocol.export(invokerDelegete), originInvoker);
bounds.put(key, exporter);
getProviderUrl(originInvoker)通過invoker的url 獲取 providerUrl的地址,這時候url的protocol就不是registry了,
而是具體的協議,比如dubbo
那麼後面的protocol.export就會使用DubboProtocol,當然同樣加上了wrapper,這兩個wrapper會在調用過程中加上
listener和filter鏈,鏈的最後就是invoker
4、DubboProtocol的export
DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
....
openServer(url)->createServer(url);
根據具體協議啓動服務器,監聽端口
5、Exchangers.bind->Transporters.bind->Server
server = Exchangers.bind(url, requestHandler);
HeaderExchanger的bind
public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
}
Transporters的bind return getTransporter().bind(url, handler);
這裏的Transporter使用的是自適應的,那麼會根據配置或者默認使用NettyTransporter
6、NettyTransporter.bind->NettyServer(url, listener);
NettyServer裏面的doOpen就是netty啓動服務端的過程。
7、回到RegistryProtocol的export,在暴漏完invoker後,接着去註冊中心註冊了服務提供者
使用zookeeper則會註冊地址/dubbo/interfaceClass/providers/{providerUrl}存儲生成者的ip,端口等,供消費者訂閱獲取使用
com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
}
三、ServiceBean<T> 生產者服務暴漏過程,<dubbo:service>標籤最終解析成了ServiceBean。
1、 ServiceConfig 的export方法爲暴漏服務的方法。
private void doExportUrls() {
List<URL> registryURLs = loadRegistries(true);
//loadRegistries檢查了註冊中心,如果存在設置了URL的Protocol爲registry
// url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
//可以配置多協議暴漏
for (ProtocolConfig protocolConfig : protocols) {
doExportUrlsFor1Protocol(protocolConfig, registryURLs);
}
}
2、 doExportUrlsFor1Protocol中
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
//生成了invoker,默認使用JavassistProxyFactory
Exporter<?> exporter = protocol.export(invoker);
exporters.add(exporter);
這個protocol使用的是Adaptive的,而這個invoker.url.protocol爲registry,所以實際會得到RegistryProtocol
再加上wrapper則會得到ProtocolListenerWrapper->ProtocolFilterWrapper->RegistryProtocol
3、ProtocolListenerWrapper和ProtocolFilterWrapper在export方法中對registry類型的直接通過
ProtocolFilterWrapper
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
return protocol.export(invoker);
}
return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
}
到了RegistryProtocol的export
//export invoker
final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);
doLocalExport中
final Invoker<?> invokerDelegete = new InvokerDelegete<T>(originInvoker, getProviderUrl(originInvoker));
exporter = new ExporterChangeableWrapper<T>((Exporter<T>)protocol.export(invokerDelegete), originInvoker);
bounds.put(key, exporter);
getProviderUrl(originInvoker)通過invoker的url 獲取 providerUrl的地址,這時候url的protocol就不是registry了,
而是具體的協議,比如dubbo
那麼後面的protocol.export就會使用DubboProtocol,當然同樣加上了wrapper,這兩個wrapper會在調用過程中加上
listener和filter鏈,鏈的最後就是invoker
4、DubboProtocol的export
DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
....
openServer(url)->createServer(url);
根據具體協議啓動服務器,監聽端口
5、Exchangers.bind->Transporters.bind->Server
server = Exchangers.bind(url, requestHandler);
HeaderExchanger的bind
public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
}
Transporters的bind return getTransporter().bind(url, handler);
這裏的Transporter使用的是自適應的,那麼會根據配置或者默認使用NettyTransporter
6、NettyTransporter.bind->NettyServer(url, listener);
NettyServer裏面的doOpen就是netty啓動服務端的過程。
7、回到RegistryProtocol的export,在暴漏完invoker後,接着去註冊中心註冊了服務提供者
使用zookeeper則會註冊地址/dubbo/interfaceClass/providers/{providerUrl}存儲生成者的ip,端口等,供消費者訂閱獲取使用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.