Dubbo发布过程中,服务发布的实现

加载完beanDefinitions后,开始执行onrefresh()等方法。随后在finishBeanFactoryInitialization(beanFactory)方法中,对加载的BeanDefinition进行实例化和初始化。调用了beanFactory.freezeConfiguration()方法,先冻结各个BeanDefinition,然后一次加载各个BeanDefinition。然后调用preInstantiateSingletons方法:

public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                                //判断Bean对象是否继承了FactoryBean,如果是FactoryBean,则获取Bean的时候,在bean name前面拼接"&"
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
	}

方法中,首先调用了isFactoryBean(beanName)方法,用来判断Bean对象是否继承了FactoryBean

	public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
		String beanName = transformedBeanName(name);
		Object beanInstance = getSingleton(beanName, false);
		if (beanInstance != null) {
			return (beanInstance instanceof FactoryBean);
		}
		// No singleton instance found -> check bean definition.
		if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
			// No bean definition found in this factory -> delegate to parent.
			return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
		}
		return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
	}

针对 单例Bean的获取过程为

getBean() 
   ->doGetBean() 
      -> getSingleton(beanName) 
        -> getSingleton(String beanName, ObjectFactory<?> singletonFactory) 
          ->singletonFactory.getObject() 
              ->createBean(beanName, mbd, args)
              [Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. ]
              ->doCreateBean(beanName, mbdToUse, args) 
                  ->createBeanInstance(beanName, mbd, args)
                      ->instantiateBean()
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
            // Initialize the bean instance.
              ->populateBean(beanName, mbd, instanceWrapper);//暂时没有发现功能用处
                  // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
  		  // state of the bean before properties are set. This can be used, for example,
  		  // to support styles of field injection.
                  InstantiationAwareBeanPostProcessor
                  applyPropertyValues():属性赋值
              ->exposedObject = initializeBean(beanName, exposedObject, mbd);//初始化对象
              invokeAwareMethods//包括调用BeanNameAware#setBeanName,BeanClassLoaderAware#setBeanClassLoader
              BeanFactoryAware#setBeanFactory
              applyBeanPostProcessorsBeforeInitialization()
              invokeInitMethods
              applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
        ->addSingleton(String beanName, Object singletonObject)//对三级缓存进行修改


applyBeanPostProcessorsBeforeInitialization中BeanPostProcessor包括:

0 = {ApplicationContextAwareProcessor@6523} 
1 = {WebApplicationContextServletContextAwareProcessor@6524} 
2 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@6205} 
3 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@6525} 
4 = {ConfigurationPropertiesBindingPostProcessor@6526} 
5 = {InfrastructureAdvisorAutoProxyCreator@6218} "proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false"
6 = {WebServerFactoryCustomizerBeanPostProcessor@6527} 
7 = {ErrorPageRegistrarBeanPostProcessor@6528} 
8 = {CommonAnnotationBeanPostProcessor@6232} 
9 = {AutowiredAnnotationBeanPostProcessor@6396} 
10 = {ReferenceAnnotationBeanPostProcessor@6417} 
11 = {ApplicationListenerDetector@6529} 

在getSingleton(beanName)过程中,首先从缓存对象中获取

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

在循环获取bean的实例过程中,现在来分析一下dubbo:service Bean的实例过程,现在以com.bail.user.service.IUserService为例分析一下:
在createBean()的方法过程中,解析到BeanDefinition的resolvedClass类型为com.alibaba.dubbo.config.spring.ServiceBean,实例化之前,调用了resolveBeforeInstantiation()给了Bean后置处理器处理Bean的一个机会,此处调用的BeanPostProcessor类型为instantiationAware,其中在BeanPostProcessorCache缓存中有四种类型的BeanPostProcessor,如下:

	static class BeanPostProcessorCache {

		final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>();

		final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>();

		final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>();

		final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();
	}

mergedDefinition 如下:

0 = {CommonAnnotationBeanPostProcessor@6342} 
1 = {AutowiredAnnotationBeanPostProcessor@6343} 
2 = {ReferenceAnnotationBeanPostProcessor@6344} 
3 = {ApplicationListenerDetector@6861} 

IUserService 的PropertyValues为:

0 = {PropertyValue@7224} "bean property 'id'"
1 = {PropertyValue@7225} "bean property 'ref'"
2 = {PropertyValue@7226} "bean property 'methods'"
3 = {PropertyValue@7227} "bean property 'interface'"
4 = {PropertyValue@7228} "bean property 'version'"
5 = {PropertyValue@7229} "bean property 'delay'"
6 = {PropertyValue@7230} "bean property 'async'"
7 = {PropertyValue@7231} "bean property 'timeout'"
8 = {PropertyValue@7232} "bean property 'retries'"

普通属性赋值调用的是applyPropertyValues()方法。
在调用initializeBean()的方法的过程中,判断IUserService为InitializingBean类型,调用ServiceBean的afterPropertiesSet()方法,方法内部调用BeanFactoryUtils.beansOfTypeIncludingAncestors()方法依次获取providerConfigMap、applicationConfigMap、moduleConfigMap、registryConfigMap、monitorConfigMap、protocolConfigMap等信息,加载完相关信息后,从initializeBean方法返回。继续执行
执行applyBeanPostProcessorsAfterInitialization()方法,在执行ApplicationListenerDetector BeanPostProcessor后置处理时,因为IUserService instanceof ApplicationListener,所以执行了addApplicationListener,将IUserService 当做监听器添加到应用上下文中。
至此一个dubbo:service类型的Bean初始化完毕。
在执行完finishBeanFactoryInitialization()方法后,BeanDefinitionMap中的bean都初始化完成。

接下来执行finishRefresh()方法,用来publish corresponding event,发布相应的事件,在获取到对应事件的监听器后,包括两个dubbo:service,随后调用监听器的onApplicationEvent()方法。
举例查看IUserService的发布过程 export():

    public synchronized void export() {
        //在此工程中,provider、export 等为空
        if (provider != null) {
            if (export == null) {
                export = provider.getExport();
            }
            if (delay == null) {
                delay = provider.getDelay();
            }
        }
        if (export != null && !export) {
            return;
        }

        if (delay != null && delay > 0) {
            delayExportExecutor.schedule(new Runnable() {
                @Override
                public void run() {
                    doExport();
                }
            }, delay, TimeUnit.MILLISECONDS);
        } else {
            //继续执行doExport()方法
            doExport();
        }
    }

在doExport()方法中,依次执行方法,checkDefault()默认提供ProviderConfig对象,并赋值默认属性;随后完成了dubbo配置各个对象的属性赋值,然后调用doExportUrls()进行发布

    private void doExportUrls() {
        List<URL> registryURLs = loadRegistries(true);
        for (ProtocolConfig protocolConfig : protocols) {
            doExportUrlsFor1Protocol(protocolConfig, registryURLs);
        }
    }

loadRegistries
在Dubbo服务发布的过程中,第一次出现扩展点的加载是在doExportUrlsFor1Protocol()方法中,加载ConfiguratorFactory配置工厂。

        if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
                .hasExtension(url.getProtocol())) {
            url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
                    .getExtension(url.getProtocol()).getConfigurator(url).configure(url);
        }

首先根据加载类类型获取扩展类加载器,然后根据扩展点名称获取具体的扩展点。先从缓存中获取对应类型的扩展器,如果缓存中不存在,则利用构造函数创建一个新的加载器,并放入到缓存中。

public class ExtensionLoader<T> {

    private ExtensionLoader(Class<?> type) {
        this.type = type;
        objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
    }
    public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
        if (type == null)
            throw new IllegalArgumentException("Extension type == null");
        if (!type.isInterface()) {
            throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
        }
        if (!withExtensionAnnotation(type)) {
            throw new IllegalArgumentException("Extension type(" + type +
                    ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
        }

        ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
        if (loader == null) {
            EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
            loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
        }
        return loader;
    }


    public boolean hasExtension(String name) {
        if (name == null || name.length() == 0)
            throw new IllegalArgumentException("Extension name == null");
        try {
            this.getExtensionClass(name);
            return true;
        } catch (Throwable t) {
            return false;
        }
    }

    private ExtensionLoader(Class<?> type) {
        this.type = type;
        objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
    }

    public T getAdaptiveExtension() {
        Object instance = cachedAdaptiveInstance.get();
        if (instance == null) {
            if (createAdaptiveInstanceError == null) {
                synchronized (cachedAdaptiveInstance) {
                    instance = cachedAdaptiveInstance.get();
                    if (instance == null) {
                        try {
                            instance = createAdaptiveExtension();
                            cachedAdaptiveInstance.set(instance);
                        } 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());
        } catch (Exception e) {
            throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);
        }
    }
}

调用过程为:

getExtensionClass(String name)
  ->getExtensionClass(String name)

在获取到对应的协议配置为空后,根据判断url的scope选择发布方式,本案例中发布走的是本地发布,及调用exportLocal(url)方法。

    private void exportLocal(URL url) {
        //url=dubbo://10.9.233.26:20880/com.bail.user.service.IUserService?anyhost=true&application=user-provider&bind.ip=10.9.233.26&bind.port=20880&dubbo=2.6.2&generic=false&getUserById.retries=3&getUserById.timeout=3000&interface=com.bail.user.service.IUserService&methods=getUserById,queryList&pid=3560&retries=2&revision=1.0.0&side=provider&timeout=8000&timestamp=1637728161285&version=1.0.0
        if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
            //local=injvm://127.0.0.1/com.bail.user.service.IUserService?anyhost=true&application=user-provider&bind.ip=10.9.233.26&bind.port=20880&dubbo=2.6.2&generic=false&getUserById.retries=3&getUserById.timeout=3000&interface=com.bail.user.service.IUserService&methods=getUserById,queryList&pid=3560&retries=2&revision=1.0.0&side=provider&timeout=8000&timestamp=1637728161285&version=1.0.0
            URL local = URL.valueOf(url.toFullString())
                    .setProtocol(Constants.LOCAL_PROTOCOL)
                    .setHost(LOCALHOST)
                    .setPort(0);
            ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref));
            Exporter<?> exporter = protocol.export(
                    proxyFactory.getInvoker(ref, (Class) interfaceClass, local));
            exporters.add(exporter);
            logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry");
        }
    }

在exportLocal方法中,调用了protocol.export(proxyFactory.getInvoker(ref, (Class) interfaceClass, local))方法,用来暴露服务

posted @ 2021-11-29 14:33  南宫煌_慧  阅读(46)  评论(0编辑  收藏  举报