dubbo原理
1.使用
参考文档:http://dubbo.apache.org/zh-cn/docs/2.7/user/preface/background/
compile 'org.apache.dubbo:dubbo-spring-boot-starter:2.7.7'
dubbo: #当前服务id和名称 application: id: order name: order #注册中心地址及协议,同一集群内的多个地址用逗号分隔 registry: address: nacos://127.0.0.1:8848 protocol: nacos #注册中心地址协议,支持dubbo,multicast,zookeeper,redis,consul(2.7.1),sofa(2.7.2),etcd(2.7.2),nacos(2.7.2)等协议 #服务提供者协议 protocol: name: dubbo port: 20880 #服务消费者缺省值配置 consumer: timeout: 60000 check: true #启动时检查提供者是否存在,true报错,false忽略 scan: base-packages: com.yue.product.service
@EnableDiscoveryClient @SpringBootApplication @ComponentScan(basePackages = "com.yue") @EnableDubbo public class ProductApplication { public static void main(String[] args) { SpringApplication.run(ProductApplication.class, args); } }
服务提供方:
//新版dubbo注解,暴露服务 @DubboService public class ItemServiceImpl implements ItemService { @Autowired private ItemDao itemDao; @Override public List<Item> getList() { return itemDao.selectList(null); } }
服务消费方:
@RestController @RequestMapping("/order") public class OrderController { //引用服务 @DubboReference private ItemService itemService; @GetMapping("/getOrder") public ResponseResult getOrderList() { return ResponseResult.success(itemService.getList()); } }
2.启动流程
本文以Dubbo2.7.7为例
启用注解 @EnableDubbo
@EnableDubboConfig @DubboComponentScan public @interface EnableDubbo {...}
@EnableDubboConfig
@Import(DubboConfigConfigurationRegistrar.class) public @interface EnableDubboConfig {...}
//ImportBeanDefinitionRegistrar类只能通过其他类@Import的方式来加载,通常是启动类或配置类。 //使用@Import,如果括号中的类是ImportBeanDefinitionRegistrar的实现类,则会调用接口方法,将其中要注册的类注册成bean。 //实现该接口的类拥有注册bean的能力。 public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AnnotationAttributes attributes = AnnotationAttributes.fromMap( importingClassMetadata.getAnnotationAttributes(EnableDubboConfig.class.getName())); boolean multiple = attributes.getBoolean("multiple"); // 注册启用单一配置绑定 registerBeans(registry, DubboConfigConfiguration.Single.class); // 如果启用多配置,则注册启用多重配置绑定 if (multiple) { // Since 2.6.6 https://github.com/apache/dubbo/issues/3193 registerBeans(registry, DubboConfigConfiguration.Multiple.class); } // 注册普通实例 registerCommonBeans(registry); } }
static void registerCommonBeans(BeanDefinitionRegistry registry) { // Since 2.5.7 Register @Reference Annotation Bean Processor as an infrastructure Bean registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class); // Since 2.7.4 [Feature] https://github.com/apache/dubbo/issues/5093 registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME, DubboConfigAliasPostProcessor.class); // Since 2.7.5 Register DubboLifecycleComponentApplicationListener as an infrastructure Bean registerInfrastructureBean(registry, DubboLifecycleComponentApplicationListener.BEAN_NAME, DubboLifecycleComponentApplicationListener.class); // Since 2.7.4 Register DubboBootstrapApplicationListener as an infrastructure Bean registerInfrastructureBean(registry, DubboBootstrapApplicationListener.BEAN_NAME, DubboBootstrapApplicationListener.class); // Since 2.7.6 Register DubboConfigDefaultPropertyValueBeanPostProcessor as an infrastructure Bean registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME, DubboConfigDefaultPropertyValueBeanPostProcessor.class); }
@DubboComponentScan
@Import(DubboComponentScanRegistrar.class) public @interface DubboComponentScan {...}
public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistrar { //扫描服务提供包并注册ServiceAnnotationBeanPostProcessor @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { Set<String> packagesToScan = getPackagesToScan(importingClassMetadata); registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);
//注册普通实例 registerCommonBeans(registry); } //注册 private void registerServiceAnnotationBeanPostProcessor(Set<String> packagesToScan, BeanDefinitionRegistry registry) { BeanDefinitionBuilder builder = rootBeanDefinition(ServiceAnnotationBeanPostProcessor.class); builder.addConstructorArgValue(packagesToScan); builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry); } //扫描 private Set<String> getPackagesToScan(AnnotationMetadata metadata) { AnnotationAttributes attributes = AnnotationAttributes.fromMap( metadata.getAnnotationAttributes(DubboComponentScan.class.getName())); String[] basePackages = attributes.getStringArray("basePackages"); Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses"); String[] value = attributes.getStringArray("value"); // Appends value array attributes Set<String> packagesToScan = new LinkedHashSet<String>(Arrays.asList(value)); packagesToScan.addAll(Arrays.asList(basePackages)); for (Class<?> basePackageClass : basePackageClasses) { packagesToScan.add(ClassUtils.getPackageName(basePackageClass)); } if (packagesToScan.isEmpty()) { return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName())); } return packagesToScan; } }
ServiceAnnotationBeanPostProcessor.class继承ServiceClassPostProcessor.class
ServiceClassPostProcessor.class中来注册ServiceBean!!!
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { //注册应用监听器 registerBeans(registry, DubboBootstrapApplicationListener.class); //处理扫描包 Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan); if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) { //注册服务bean registerServiceBeans(resolvedPackagesToScan, registry); } else { ... } } private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) { //获取BeanDefinition扫描器,并设置beanName生成器,过滤 DubboClassPathBeanDefinitionScanner scanner = new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader); BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry); scanner.setBeanNameGenerator(beanNameGenerator); //加入要扫描的注解类型 serviceAnnotationTypes.forEach(annotationType -> { scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType)); }); for (String packageToScan : packagesToScan) { // 扫描 scanner.scan(packageToScan); // 查找所有带上面Include注解类型的BeanDefinitionHolders,无论@ComponentScan是否扫描 Set<BeanDefinitionHolder> beanDefinitionHolders = findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator); if (!CollectionUtils.isEmpty(beanDefinitionHolders)) { for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) { registerServiceBean(beanDefinitionHolder, registry, scanner); } ... } } } private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry, DubboClassPathBeanDefinitionScanner scanner) { Class<?> beanClass = resolveClass(beanDefinitionHolder); Annotation service = findServiceAnnotation(beanClass); AnnotationAttributes serviceAnnotationAttributes = getAnnotationAttributes(service, false, false); Class<?> interfaceClass = resolveServiceInterfaceClass(serviceAnnotationAttributes, beanClass); String annotatedServiceBeanName = beanDefinitionHolder.getBeanName(); AbstractBeanDefinition serviceBeanDefinition = buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName); // 生成服务名称并注册 String beanName = generateServiceBeanName(serviceAnnotationAttributes, interfaceClass); if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean registry.registerBeanDefinition(beanName, serviceBeanDefinition); ... } }
至此,ServiceBean注册完成,并未实例化和初始化。
ReferenceAnnotationBeanPostProcessor.class继承AbstractAnnotationBeanPostProcessor.class
AbstractAnnotationBeanPostProcessor又继承InstantiationAwareBeanPostProcessorAdapter并实现MergedBeanDefinitionPostProcessor接口
AbstractAnnotationBeanPostProcessor中扫描缓存以备后续注入需要
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { if (beanType != null) { //获取@DubboReference注解字段并缓存 InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } }
InstantiationAwareBeanPostProcessorAdapter在实例化时
public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs); try { 找到@DubboReference来注入 metadata.inject(bean, beanName, pvs); }...省略 return pvs; } public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Collection<InjectedElement> checkedElements = this.checkedElements; Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements); if (!elementsToIterate.isEmpty()) { //InjectedElement又分为AnnotatedFieldElement,AnnotatedMethodElement for (InjectedElement element : elementsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean '" + beanName + "': " + element); } element.inject(target, beanName, pvs); } } } //以AnnotatedFieldElement为例 protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { Class<?> injectedType = resolveInjectedType(bean, field); //获取注入bean Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this); ReflectionUtils.makeAccessible(field); field.set(bean, injectedObject); } protected Object getInjectedObject(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception { //先从缓存中获取 String cacheKey = buildInjectedObjectCacheKey(attributes, bean, beanName, injectedType, injectedElement); Object injectedObject = injectedObjectsCache.get(cacheKey); if (injectedObject == null) { //从子类创建 injectedObject = doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement); // Customized inject-object if necessary injectedObjectsCache.putIfAbsent(cacheKey, injectedObject); } return injectedObject; } 回到ReferenceAnnotationBeanPostProcessor中 protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception { // 创建一个引用bean名称 String referencedBeanName = buildReferencedBeanName(attributes, injectedType); // 注解注入声明的名称 String referenceBeanName = getReferenceBeanName(attributes, injectedType); // 创建一个 @ReferenceBean实例 ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referenceBeanName, attributes, injectedType); // 判断是否是本地服务bean boolean localServiceBean = isLocalServiceBean(referencedBeanName, referenceBean, attributes); // 注册到spring容器中 registerReferenceBean(referencedBeanName, referenceBean, attributes, localServiceBean, injectedType); // 缓存一份bean实例 cacheInjectedReferenceBean(referenceBean, injectedElement); // 如果存在则返回一个代理对象,否则立即获取 return getOrCreateProxy(referencedBeanName, referenceBean, localServiceBean, injectedType); }
至此,ReferenceBean注册完成。
DubboBootstrapApplicationListener.class启动服务
public DubboBootstrap start() { if (started.compareAndSet(false, true)) { ready.set(false); // 初始化 initialize(); if (logger.isInfoEnabled()) { logger.info(NAME + " is starting..."); } // 暴露(导出)服务 exportServices(); // 不仅提供者注册 if (!isOnlyRegisterProvider() || hasExportedServices()) { // 暴露元数据服务 exportMetadataService(); // 如果需要,注册本地服务实例 registerServiceInstance(); } // 订阅服务 referServices(); ... } return this; }
initialize();
private void initialize() { if (!initialized.compareAndSet(false, true)) { return; } //初始化FrameworkExt类,遍历执行配置管理器,环境等的初始化方法 ApplicationModel.initFrameworkExts(); //配置管理器读取并加载配置中心的配置信息,并准备环境,最后存入environment中 startConfigCenter(); //使用注册中心作为配置中心,如果有需要 useRegistryAsConfigCenterIfNecessary(); //加载远程配置 loadRemoteConfigs(); //检查全局配置 checkGlobalConfigs(); //初始化元数据服务,加载本地元数据服务提供者类 initMetadataService(); //初始化事件监听器 initEventListener(); }
exportServices();
private void exportServices() { //获取所有ServiceBean遍历调用export() configManager.getServices().forEach(sc -> { ServiceConfig serviceConfig = (ServiceConfig) sc; serviceConfig.setBootstrap(this); if (exportAsync) { ExecutorService executor = executorRepository.getServiceExporterExecutor(); Future<?> future = executor.submit(() -> { //暴露服务 sc.export(); exportedServices.add(sc); }); asyncExportingFutures.add(future); } else { sc.export(); exportedServices.add(sc); } }); }
看源码心态崩了,简单来说
1.根据url调用 doLocalExport 导出服务
2.根据 register 的值决定是否注册服务
3.向注册中心进行订阅 override 数据
服务导出详情参考:https://www.cnblogs.com/shenchen123456/p/13826528.html

浙公网安备 33010602011771号