zoukankan      html  css  js  c++  java
  • 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))方法,用来暴露服务

  • 相关阅读:
    一道某高大上互联网公司的笔试题分享
    人机博弈-吃子棋游戏(四)搜索算法
    人机博弈-吃子棋游戏(三)走法生成
    人机博弈,吃子棋游戏(二)如何算气
    eclipse手动导入dtd文件
    spring BeanFactory概述
    xp的虚拟机如何访问本地主机上的文件
    XML Schema 简介
    DTD 简介
    spring开发相关网址
  • 原文地址:https://www.cnblogs.com/nangonghui/p/15586664.html
Copyright © 2011-2022 走看看