irpas技术客

spring-cloud-starter-dubbo启动过程_huziayy1314_spring-cloud-starter-dubbo

大大的周 2382

一、 DubboAutoConfiguration @ConditionalOnProperty( prefix = "dubbo", name = {"enabled"}, matchIfMissing = true ) @Configuration @AutoConfigureAfter({DubboRelaxedBindingAutoConfiguration.class}) @EnableConfigurationProperties({DubboConfigurationProperties.class}) @EnableDubboConfig public class DubboAutoConfiguration implements ApplicationContextAware, BeanDefinitionRegistryPostProcessor { public DubboAutoConfiguration() { } @ConditionalOnProperty( prefix = "dubbo.scan.", name = {"base-packages"} ) @ConditionalOnBean( name = {"dubbo-service-class-base-packages"} ) @Bean public ServiceClassPostProcessor serviceClassPostProcessor(@Qualifier("dubbo-service-class-base-packages") Set<String> packagesToScan) { return new ServiceClassPostProcessor(packagesToScan); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (applicationContext instanceof ConfigurableApplicationContext) { ConfigurableApplicationContext context = (ConfigurableApplicationContext)applicationContext; DubboLifecycleComponentApplicationListener dubboLifecycleComponentApplicationListener = new DubboLifecycleComponentApplicationListener(); dubboLifecycleComponentApplicationListener.setApplicationContext(applicationContext); context.addApplicationListener(dubboLifecycleComponentApplicationListener); DubboBootstrapApplicationListener dubboBootstrapApplicationListener = new DubboBootstrapApplicationListener(); dubboBootstrapApplicationListener.setApplicationContext(applicationContext); context.addApplicationListener(dubboBootstrapApplicationListener); } } public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { this.removeBeanDefinition(registry, "dubboLifecycleComponentApplicationListener"); this.removeBeanDefinition(registry, "dubboBootstrapApplicationListener"); } private void removeBeanDefinition(BeanDefinitionRegistry registry, String beanName) { if (registry.containsBeanDefinition(beanName)) { registry.removeBeanDefinition(beanName); } } public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { } }

这是dubbo-spring-boot-starter.jar中主要的启动配置类,该类直接通过@Bean注册ServiceClassPostProcessor到Spring容器中,并通过**@EnableDubboConfig引入DubboConfigConfigurationRegistrar**,注册ReferenceAnnotationBeanPostProcessor、DubboConfigAliasPostProcessor、DubboLifecycleComponentApplicationListener、DubboBootstrapApplicationListener和DubboConfigDefaultPropertyValueBeanPostProcessor到Spring容器中。

DubboConfigDefaultPropertyValueBeanPostProcessor:用来填充AbstarctConfig.id和AbstarctConfig.name的默认值DubboConfigAliasPostProcessor:用来注册beanName和AbstarctConfig.id的别名DubboLifecycleComponentApplicationListener:用来从Spring容器中获取所有实现了org.apache.dubbo.common.context.LifeCycle接口的Bean,并执行他们的start()方法;ServiceClassPostProcessor:扫描所有@DubboService注解的类,构建成ServiceBean注册到Srping容器中;ReferenceAnnotationBeanPostProcessor:扫描Bean中所有@DubboReference注解的属性,通过ReferenceBean构建远程服务的实例,注入到相应的依赖中;DubboBootstrapApplicationListener:监听ContextRefreshedEvent和ContextClosedEvent事件,相应的执行DubboBootstrap的start()和stop()方法;

下面会详细介绍ServiceClassPostProcessor、ReferenceAnnotationBeanPostProcessor和DubboBootstrapApplicationListener的作用。

二、ServiceClassPostProcessor

该类的主要作用是将@DubboService和@org.apache.dubbo.config.annotation.Service注释的类注册到Spring容器中。

1、UML类图:

![image.png](https://img-blog.csdnimg.cn/img_convert/552634287af5a85fa577fa7e3d823a22.png#crop=0&crop=0&crop=1&crop=1&height=627&id=SZvqg&margin=[object Object]&name=image.png&originHeight=627&originWidth=1328&originalType=binary&ratio=1&rotation=0&showTitle=false&size=41560&status=done&style=none&title=&width=1328) EnvironmentAware,ResourceLoaderAware,BeanClassLoaderAware全部继承自Aware接口,用于set对应的bean到对象中。 BeanDefinitionRegistryPostProcessor:可以通过此接口传入的BeanDefinitionRegistry注册Bean到Spring容器中,或判断Spring容器是否存在某个Bean,或从Spring容器中删除某个bean;

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException; }

关于BeanDefinitionRegistryPostProcessor详细的介绍可以参考:https://blog.csdn.net/ztchun/article/details/90814135

2、 支持的注解:DubboService、org.apache.dubbo.config.annotation.Service,com.alibaba.dubbo.config.annotation.Service private final static List<Class<? extends Annotation>> serviceAnnotationTypes = asList( // @since 2.7.7 Add the @DubboService , the issue : https://github.com/apache/dubbo/issues/6007 DubboService.class, // @since 2.7.0 the substitute @com.alibaba.dubbo.config.annotation.Service Service.class, // @since 2.7.3 Add the compatibility for legacy Dubbo's @Service , the issue : https://github.com/apache/dubbo/issues/4330 com.alibaba.dubbo.config.annotation.Service.class ); 3、方法:postProcessBeanDefinitionRegistry @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { // @since 2.7.5 //这里重复注册了一次DubboBootstrapApplicationListener registerInfrastructureBean(registry, DubboBootstrapApplicationListener.BEAN_NAME, DubboBootstrapApplicationListener.class); Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan); if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) { registerServiceBeans(resolvedPackagesToScan, registry); } else { if (logger.isWarnEnabled()) { logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!"); } } }

此方法实现自接口BeanDefinitionRegistryPostProcessor: 该方法首先注册DubboBootstrapApplicationListener到Spring容器,DubboBootstrapApplicationListener用来监听ContextRefreshedEvent,Spring Context刷新完成后,调用DubboBootstrap.start()方法,启动Dubbo服务; 然后解析要扫描的报列表,从${dubbo.scan.base-packages}配置项读取扫描列表,如果扫描列表不为空,则调用registerServiceBeans方法;

4、 方法:registerServiceBeans private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) { DubboClassPathBeanDefinitionScanner scanner = new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader); BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry); scanner.setBeanNameGenerator(beanNameGenerator); // refactor @since 2.7.7 serviceAnnotationTypes.forEach(annotationType -> { scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType)); }); for (String packageToScan : packagesToScan) { // Registers @Service Bean first scanner.scan(packageToScan); // Finds all BeanDefinitionHolders of @Service whether @ComponentScan scans or not. Set<BeanDefinitionHolder> beanDefinitionHolders = findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator); if (!CollectionUtils.isEmpty(beanDefinitionHolders)) { for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) { registerServiceBean(beanDefinitionHolder, registry, scanner); } if (logger.isInfoEnabled()) { logger.info(beanDefinitionHolders.size() + " annotated Dubbo's @Service Components { " + beanDefinitionHolders + " } were scanned under package[" + packageToScan + "]"); } } else { if (logger.isWarnEnabled()) { logger.warn("No Spring Bean annotating Dubbo's @Service was found under package[" + packageToScan + "]"); } } } }

使用DubboClassPathBeanDefinitionScanner扫描所有的DubboService类,然后遍历扫描结果,调用registerServiceBean方法,注册bean到Spring容器中。

5、方法:registerServiceBean private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry, DubboClassPathBeanDefinitionScanner scanner) { //从BeanDefinitionHolder解析出beanClass; Class<?> beanClass = resolveClass(beanDefinitionHolder); //按顺序从beanClass获取@DubboService、@org.apache.dubbo.config.annotation.Service或@com.alibaba.dubbo.config.annotation.Service注解 Annotation service = findServiceAnnotation(beanClass); /** * The {@link AnnotationAttributes} of @Service annotation */ //从注解从读取属性值,用于后续构建Dubbo Service Bean时的参数; AnnotationAttributes serviceAnnotationAttributes = getAnnotationAttributes(service, false, false); //获取DubboService的接口类,如果注解中指定了接口类,则使用注解中指定的类(解析顺序interfaceClass->interfaceName),否则使用服务类实现的接口中的第一个。如果找不到接口类,则抛出异常; Class<?> interfaceClass = resolveServiceInterfaceClass(serviceAnnotationAttributes, beanClass); String annotatedServiceBeanName = beanDefinitionHolder.getBeanName(); //构建ServiceBean AbstractBeanDefinition serviceBeanDefinition = buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName); // ServiceBean Bean name //使用ServiceBeanNameBuilder生成beanName String beanName = generateServiceBeanName(serviceAnnotationAttributes, interfaceClass); //检查是否可以注册到容器中 if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean //注册ServiceBean到容器中 registry.registerBeanDefinition(beanName, serviceBeanDefinition); if (logger.isInfoEnabled()) { logger.info("The BeanDefinition[" + serviceBeanDefinition + "] of ServiceBean has been registered with name : " + beanName); } } else { if (logger.isWarnEnabled()) { logger.warn("The Duplicated BeanDefinition[" + serviceBeanDefinition + "] of ServiceBean[ bean name : " + beanName + "] was be found , Did @DubboComponentScan scan to same package in many times?"); } } }

6、方法:buildServiceBeanDefinition

private AbstractBeanDefinition buildServiceBeanDefinition(Annotation serviceAnnotation, AnnotationAttributes serviceAnnotationAttributes, Class<?> interfaceClass, String annotatedServiceBeanName) { //创建 ServiceBean BeanDefinitionBuilder BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class); AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); MutablePropertyValues propertyValues = beanDefinition.getPropertyValues(); String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol", "interface", "interfaceName", "parameters"); //从Annotation读取属性并设置到MutablePropertyValues中,比如group,version propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(serviceAnnotation, environment, ignoreAttributeNames)); // References "ref" property to annotated-@Service Bean addPropertyReference(builder, "ref", annotatedServiceBeanName); // Set interface builder.addPropertyValue("interface", interfaceClass.getName()); // Convert parameters into map builder.addPropertyValue("parameters", convertParameters(serviceAnnotationAttributes.getStringArray("parameters"))); // Add methods parameters List<MethodConfig> methodConfigs = convertMethodConfigs(serviceAnnotationAttributes.get("methods")); if (!methodConfigs.isEmpty()) { builder.addPropertyValue("methods", methodConfigs); } /** * Add {@link org.apache.dubbo.config.ProviderConfig} Bean reference */ String providerConfigBeanName = serviceAnnotationAttributes.getString("provider"); if (StringUtils.hasText(providerConfigBeanName)) { addPropertyReference(builder, "provider", providerConfigBeanName); } /** * Add {@link org.apache.dubbo.config.MonitorConfig} Bean reference */ String monitorConfigBeanName = serviceAnnotationAttributes.getString("monitor"); if (StringUtils.hasText(monitorConfigBeanName)) { addPropertyReference(builder, "monitor", monitorConfigBeanName); } /** * Add {@link org.apache.dubbo.config.ApplicationConfig} Bean reference */ String applicationConfigBeanName = serviceAnnotationAttributes.getString("application"); if (StringUtils.hasText(applicationConfigBeanName)) { addPropertyReference(builder, "application", applicationConfigBeanName); } /** * Add {@link org.apache.dubbo.config.ModuleConfig} Bean reference */ String moduleConfigBeanName = serviceAnnotationAttributes.getString("module"); if (StringUtils.hasText(moduleConfigBeanName)) { addPropertyReference(builder, "module", moduleConfigBeanName); } /** * Add {@link org.apache.dubbo.config.RegistryConfig} Bean reference */ String[] registryConfigBeanNames = serviceAnnotationAttributes.getStringArray("registry"); List<RuntimeBeanReference> registryRuntimeBeanReferences = toRuntimeBeanReferences(registryConfigBeanNames); if (!registryRuntimeBeanReferences.isEmpty()) { builder.addPropertyValue("registries", registryRuntimeBeanReferences); } /** * Add {@link org.apache.dubbo.config.ProtocolConfig} Bean reference */ String[] protocolConfigBeanNames = serviceAnnotationAttributes.getStringArray("protocol"); List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames); if (!protocolRuntimeBeanReferences.isEmpty()) { builder.addPropertyValue("protocols", protocolRuntimeBeanReferences); } return builder.getBeanDefinition(); } 三、 ServiceBean

Dubbo服务的定义类,用于封装Dubbo服务的参数,如group、version、interfaceClass,服务类对象实例等,我们可以通过自定义ServiceBean来自定义需要发布的Dubbo服务,如:

@Bean public ServiceBean<DubboMappingService> dubboDefinitionServiceBean(DubboMappingService dubboDefinitionService){ ServiceBean<DubboMappingService> serviceBean = new ServiceBean<>(); serviceBean.setVersion(CommonServiceVersion.DUBBO_DEFINITION_SERVICE);//版本 serviceBean.setGroup(this.applicationName);//将Dubbo服务的group设置为application Name serviceBean.setRef(dubboDefinitionService);//实现类对象实例 serviceBean.setInterface(DubboMappingService.class);//接口类 return serviceBean; }

需要重点关注的方法:export()和addIntoConfigManager(),后面会详细介绍

1、UML类图 ![image.png](https://img-blog.csdnimg.cn/img_convert/0793b437ac37497a40c6a805e88e2d02.png#crop=0&crop=0&crop=1&crop=1&height=1145&id=oEl8h&margin=[object Object]&name=image.png&originHeight=1145&originWidth=1658&originalType=binary&ratio=1&rotation=0&showTitle=false&size=84133&status=done&style=none&title=&width=1658)

ServiceConfig:用于Dubbo服务暴漏**InitializingBean **, 主要是用到了他的afterPropertiesSet方法,在对象实例化完毕后,调用该方法,做一些值的初始化**DisposableBean **, 主要用到他的destroy() 方法, 在spring容器showdown的时候调用。ApplicationContextAware, 为了得到applicationContextApplicationEventPublisherAware, 用于发布ServiceBeanExportedEvent,DubboMetadataAutoConfiguration中会监听此事件,发布RestMetadata;**BeanNameAware **, 用于设置Bean的名称 2、 方法:addIntoConfigManager():继承自AbstractConfig @PostConstruct public void addIntoConfigManager() { ApplicationModel.getConfigManager().addConfig(this); }

@PostConstruct:java原生注解,用于在执行构造函数后,init()前执行的方法,在Spring框架中@PostConstruct执行顺序: Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法) addIntoConfigManager():用于将ServiceBean注册到Dubbo的ConfigManager中,用于后续在DubboBootstrap.start()方法中暴露到注册中心。

3、 方法:export():继承自ServiceConfig public synchronized void export() { if (!shouldExport()) { return; } if (bootstrap == null) { bootstrap = DubboBootstrap.getInstance(); bootstrap.initialize(); } checkAndUpdateSubConfigs(); //init serviceMetadata serviceMetadata.setVersion(getVersion()); serviceMetadata.setGroup(getGroup()); serviceMetadata.setDefaultGroup(getGroup()); serviceMetadata.setServiceType(getInterfaceClass()); serviceMetadata.setServiceInterfaceName(getInterface()); serviceMetadata.setTarget(getRef()); if (shouldDelay()) { DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS); } else { doExport(); } exported(); }

用户暴露服务到注册中心,该方法在DubboBootstrap.exportServices()中被调用。

三、 ReferenceAnnotationBeanPostProcessor

自动注入@DubboReference和@org.apache.dubbo.config.annotation.Reference注解注释的属性

1、UML类图:

![image.png](https://img-blog.csdnimg.cn/img_convert/79c47cfdfa338cd0ed19f3c62b037fe2.png#crop=0&crop=0&crop=1&crop=1&height=683&id=Go0PT&margin=[object Object]&name=image.png&originHeight=683&originWidth=1868&originalType=binary&ratio=1&rotation=0&showTitle=false&size=74239&status=done&style=none&title=&width=1868) PriorityOrdered: 继承自Ordered接口,Spring OrderComparator会有限使用此接口的值进行对比排序; BeanFactoryAware:设置BeanFactory BeanClassLoaderAware:设置ClassLoader EnvironmentAware:设置Environment ApplicationContextAware:设置ApplicationContext DisposableBean:主要用到他的destroy() 方法, 在spring容器showdown的时候调用。 MergedBeanDefinitionPostProcessor:依赖注入检查。 InstantiationAwareBeanPostProcessorAdapter:实现了postProcessPropertyValues接口,用于注入依赖;

2、方法:postProcessMergedBeanDefinition

实现自接口MergedBeanDefinitionPostProcessor,在AbstractAutowireCapableBeanFactory中调用:

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }

接口实现代码:

@Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { if (beanType != null) { InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } } 3、postProcessPropertyValues

接口实现代码:

@Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getSimpleName() + " dependencies is failed", ex); } return pvs; } 4、findInjectionMetadata

扫描所有@DubboReference和@org.apache.dubbo.config.annotation.Reference注释的Field,生成

private InjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { if (metadata != null) { metadata.clear(pvs); } try { //扫描calzz中所有@DubboReference和@org.apache.dubbo.config.annotation.Reference注释的属性,并构建AnnotatedFieldElement metadata = buildAnnotatedMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } catch (NoClassDefFoundError err) { throw new IllegalStateException("Failed to introspect object class [" + clazz.getName() + "] for annotation metadata: could not find class that it depends on", err); } } } } return metadata; } 5、AnnotatedFieldElement.inject:继承自InjectionMetadata.InjectedElement

在InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法中被调用,调用Field.set方法,注入依赖

@Override protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { Class<?> injectedType = resolveInjectedType(bean, field); //获取要注入的对象,先从缓存中取,如果取不到,调用doGetInjectedBean方法构建; Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this); ReflectionUtils.makeAccessible(field); field.set(bean, injectedObject); } 6、doGetInjectedBean @Override protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception { /** * The name of bean that annotated Dubbo's {@link Service @Service} in local Spring {@link ApplicationContext} */ String referencedBeanName = buildReferencedBeanName(attributes, injectedType); /** * The name of bean that is declared by {@link Reference @Reference} annotation injection */ String referenceBeanName = getReferenceBeanName(attributes, injectedType); ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referenceBeanName, attributes, injectedType); boolean localServiceBean = isLocalServiceBean(referencedBeanName, referenceBean, attributes); prepareReferenceBean(referencedBeanName, referenceBean, localServiceBean); registerReferenceBean(referencedBeanName, referenceBean, attributes, localServiceBean, injectedType); cacheInjectedReferenceBean(referenceBean, injectedElement); return referenceBean.get(); }

构建ReferenceBean,继承自ReferenceConfig,我们常用ReferenceConfig进行Dubbo服务的泛化调用;

四、 ReferenceBean 1、UML类图

![image.png](https://img-blog.csdnimg.cn/img_convert/e1562daecc601ac80a8016236d6db30f.png#crop=0&crop=0&crop=1&crop=1&height=1136&id=Wb8ur&margin=[object Object]&name=image.png&originHeight=1136&originWidth=1279&originalType=binary&ratio=1&rotation=0&showTitle=false&size=69728&status=done&style=none&title=&width=1279) ReferenceBean也继承自AbstractConfig,同样会通过addIntoConfigManager()方法将自身注册导ConfigManager中,以便在DubboBootstrap调用referenceConfig.get()方法;

五、 DubboBootstrapApplicationListener

实现了ApplicationListener接口,监听ContextRefreshedEvent和ContextClosedEvent事件;

1、构建方法: public DubboBootstrapApplicationListener() { this.dubboBootstrap = DubboBootstrap.getInstance(); } 2、onContextRefreshedEvent private void onContextRefreshedEvent(ContextRefreshedEvent event) { dubboBootstrap.start(); } 3、onContextClosedEvent private void onContextClosedEvent(ContextClosedEvent event) { dubboBootstrap.stop(); } 六、DubboBootstrap:Dubbo的核心类,单例模式 1、initialize:初始化dubbo的环境配置, public void initialize() { if (!initialized.compareAndSet(false, true)) { 确保只执行一次 return; } ApplicationModel.initFrameworkExts(); startConfigCenter(); loadRemoteConfigs(); checkGlobalConfigs(); // @since 2.7.8 startMetadataCenter(); initMetadataService(); initMetadataServiceExports(); initEventListener(); if (logger.isInfoEnabled()) { logger.info(NAME + " has been initialized!"); } } 2、start:dubbo服务启动,主要从ConfigManager中获取ServiceConfig和ReferenceConfig,暴漏自身服务,并解析远程服务; public DubboBootstrap start() { if (started.compareAndSet(false, true)) { ready.set(false); initialize(); if (logger.isInfoEnabled()) { logger.info(NAME + " is starting..."); } // 1. export Dubbo Services exportServices(); // Not only provider register if (!isOnlyRegisterProvider() || hasExportedServices()) { // 2. export MetadataService exportMetadataService(); //3. Register the local ServiceInstance if required registerServiceInstance(); } // reference dubbo remote service referServices(); if (asyncExportingFutures.size() > 0) { new Thread(() -> { try { this.awaitFinish(); } catch (Exception e) { logger.warn(NAME + " exportAsync occurred an exception."); } ready.set(true); if (logger.isInfoEnabled()) { logger.info(NAME + " is ready."); } }).start(); } else { ready.set(true); if (logger.isInfoEnabled()) { logger.info(NAME + " is ready."); } } if (logger.isInfoEnabled()) { logger.info(NAME + " has started."); } } return this; } 3、stop: Dubbo停止服务,调用destroy()方法,销毁相关实例。 public void destroy() { if (destroyLock.tryLock()) { try { DubboShutdownHook.destroyAll(); if (started.compareAndSet(true, false) && destroyed.compareAndSet(false, true)) { unregisterServiceInstance(); unexportMetadataService(); unexportServices(); unreferServices(); destroyRegistries(); DubboShutdownHook.destroyProtocols(); destroyServiceDiscoveries(); clear(); shutdown(); release(); } } finally { destroyLock.unlock(); } } }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: # #prefix