服务暴露首先调用ServiceBean的onApplicationEvent(),即spring容器刷新时发出事件。
public void onApplicationEvent(ApplicationEvent event) {
if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
if (isDelay() && ! isExported() && ! isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
export();
}
}
}
复制代码
ServiceConfig
public synchronized void export() {
doExportUrls();//暴露地址
}
private void doExportUrls() {//将注册的所有url匹配上对应的协议在服务端暴露出来
List<URL> registryURLs = loadRegistries(true);// 加载所有的注册中心,服务有可能注册在多个注册中心
/*registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&back=127.0.0.1:2182,127.0.0.1:2183&dubbo=2.0.0&owner=william&pid=4963®istry=zookeeper×tamp=1515744545112*/
for (ProtocolConfig protocolConfig : protocols) { 不同协议的注册。dubbo/hessian
doExportUrlsFor1Protocol(protocolConfig, registryURLs);
//protocolConfig <dubbo:protocol name="dubbo" port="20880" id="dubbo" />
}
}
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
//配置为none不暴露
if (! Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
//配置不是remote的情况下做本地暴露 (配置为remote,则表示只暴露远程服务)
if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
exportLocal(url);
///dubbo://192.168.12.871:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=4963&side=provider×tamp=1515748905578
}
///省略暴露远程服务
}
}
//拿到要暴露接口的invoke
private void exportLocal(URL url) {
if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
URL local = URL.valueOf(url.toFullString())
.setProtocol(Constants.LOCAL_PROTOCOL)
.setHost(NetUtils.LOCALHOST)
.setPort(0);
Exporter<?> exporter = protocol.export(
proxyFactory.getInvoker(ref, (Class) interfaceClass, local));
exporters.add(exporter);
logger.info("Export dubbo service " + interfaceClass.getName() +" to local registry");
}
}
复制代码
首先得到实现类的invoke
injvm://127.0.0.1/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=3861&side=provider×tamp=1515738460249
利用protocol.export(invoke),放到exportMap(key,this) key=com.alibaba.dubbo.demo.DemoService this=injvm://127.0.0.1/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=4832&side=provider×tamp=1515743334454