apache dubbo核心源码分析

dubbo版本:2.7.5
dubbo源码下载地址

spi

自适应扩展点:

ExtensionLoader.getExtensionLoader(XXX.class).getAdaptiveExtension();

指定名称扩展点:

ExtensionLoader.getExtensionLoader(XXX.class).egtExtension(name);

激活扩展点:

ExtensionLoader.getExtensionLoader(XXX.class).getActivateExtension(url,key);
Java spi实现

Service Provider Interface
jdk内置的一种服务提供发现机制
作用:服务的扩展实现
例如:数据库连接
jdk提供了java.sql.Driver接口
这个驱动类在jdk中没有实现,由不同数据库厂商实现
约定: 所有扩展点必须放在resources/META-INF/services目录下
SPI机制会扫描这个路径下的属性文件以完成加载

dubbo自定义协议扩展点

没有使用JDK内置的SPI机制
dubbo SPI相关逻辑被封装在ExtensionLoader类中
通过ExtensionLoader可以加载指定的实现类
2个规则:
1.需要在resources目录下创建任一目录结构:
META-INF/dubbo,META-INF/dubbo/internal,META-INF/service
在对应目录下创建全路径命名的文件
dubbo会去这3个目录下加载相应扩展点
2.内容是key-value形式的数据
key是字符串,value是一个对应扩展点实现
这样方式可以按照需要加载指定的实现类
步骤:
1.在一个依赖dubbo框架工程中,创建一个扩展点及一个实现
扩展点需要声明SPI注解

@SPI("myDriver")
public interface MyDriver {
    String connect();
}

实现类

@Service
public class MyDriverImpl implements MyDriver {

    @Override
    public String connect() {
        return "connect db success";
    }
}

在resources/META-INF/dubbo目录下创建以spi接口命名的文件
com.zyl.dubbo.servive.spi.MyDriver

myDriver=com.zyl.dubbo.service.spi.MyDriver

创建测试类,获取指定名称扩展点实现

@SpringBootTest
@RunWith(SpringRunner.class)
public class DubboTest {

    @Test
    public void testSPI() {
        ExtensionLoader<MyDriver> extensionLoader = ExtensionLoader.getExtensionLoader(MyDriver.class);
        MyDriver myDriver = extensionLoader.getExtension("myDriver");//指定名称扩展点
        System.out.println(myDriver.connect());
    }
}
dubbo spi源码分析

1.ExtensionLoader.getExtensionLoader()获得ExtensionLoader实例
先从缓存中获取与扩展类对应的ExtensionLoader
如果缓存未命中,则创建一个新的实例EXTENSION_LOADERS集合缓存起来
在ExtensionLoader构造方法中,初始化一个objectfACTORY,后续用到,暂时不管
ExtensionLoader

public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
		//省略前置判断
        ExtensionLoader<T> loader = (ExtensionLoader)EXTENSION_LOADERS.get(type);
        if (loader == null) {
            EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader(type));
            loader = (ExtensionLoader)EXTENSION_LOADERS.get(type);
        }
        return loader;
    }
   
   //构造方法
       private ExtensionLoader(Class<?> type) {
        this.type = type;
        this.objectFactory = type == ExtensionFactory.class ? null : (ExtensionFactory)getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension();
    }

2.getExtension()获得指定方法名称的扩展点并返回

public T getExtension(String name) {
        if (StringUtils.isEmpty(name)) {
            throw new IllegalArgumentException("Extension name == null");
        } else if ("true".equals(name)) {
        	//如果name=="true",返回一个默认的扩展实现
            return this.getDefaultExtension();
        } else {
        	//创建一个holder对象,用户缓存该扩展点的实例
            Holder<Object> holder = this.getOrCreateHolder(name);
            Object instance = holder.get();
            //缓存不存在,则创建一个实例
            if (instance == null) {
                synchronized(holder) {
                    instance = holder.get();
                    if (instance == null) {
                        instance = this.createExtension(name);
                        holder.set(instance);
                    }
                }
            }

            return instance;
        }
    }

步骤:先查缓存,缓存未命中,则创建一个扩展对象
createExtension():去指定的路径下查找name对应的扩展点实现,并且实例化后返回

private T createExtension(String name) {
		//根据name返回扩展类
        Class<?> clazz = (Class)this.getExtensionClasses().get(name);
        if (clazz == null) {
            throw this.findException(name);
        } else {
            try {
            	//从缓存中查找该类是否已经被初始化
                T instance = EXTENSION_INSTANCES.get(clazz);
                if (instance == null) {
                    EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
                    instance = EXTENSION_INSTANCES.get(clazz);
                }
                //依赖注入
                this.injectExtension(instance);
                //通过wrapper进行包装
                Set<Class<?>> wrapperClasses = this.cachedWrapperClasses;
                Class wrapperClass;
                if (CollectionUtils.isNotEmpty(wrapperClasses)) {
                    for(Iterator var5 = wrapperClasses.iterator(); var5.hasNext(); instance = this.injectExtension(wrapperClass.getConstructor(this.type).newInstance(instance))) {
                        wrapperClass = (Class)var5.next();
                    }
                }

                return instance;
            } catch (Throwable var7) {
                throw new IllegalStateException("Extension instance (name: " + name + ", class: " + this.type + ") couldn't be instantiated: " + var7.getMessage(), var7);
            }
        }
    }

getExtensionClasses()返回Map集合
key和value分别对应配置文件中的key和value
1.从缓存中获取已经被加载的扩展类
2.如果未命中缓存,则调用loadExtensionClasses()加载扩展类

    private Map<String, Class<?>> getExtensionClasses() {
        Map<String, Class<?>> classes = cachedClasses.get();
        if (classes == null) {
            synchronized (cachedClasses) {
                classes = cachedClasses.get();
                if (classes == null) {
                    classes = loadExtensionClasses();
                    cachedClasses.set(classes);
                }
            }
        }
        return classes;
    }

loadExtensionClasses()
loadDirectory()加载指定文件目录下的配置文件,根据传入的type全路径名找到对应的文件,解析内容后,保存加载到extensionClasses集合中

private Map<String, Class<?>> loadExtensionClasses() {
		//获得当前扩展接口的默认扩展对象,并且缓存
        cacheDefaultExtensionName();

        Map<String, Class<?>> extensionClasses = new HashMap<>();
        //加载指定文件目录下的配置文件
        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName());
        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
        loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName());
        loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
        loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName());
        loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
        return extensionClasses;
    }

cacheDefaultExtensionName()
1.获得指定扩展接口的@SPI注解
2.得到@SPI注解中的名字,保存到cachedDefaultName属性中

private void cacheDefaultExtensionName() {
		//获得type类声明的注解@SPI
        final SPI defaultAnnotation = type.getAnnotation(SPI.class);
        if (defaultAnnotation != null) {
        	//得到注解中定义的value值
            String value = defaultAnnotation.value();
            if ((value = value.trim()).length() > 0) {
                String[] names = NAME_SEPARATOR.split(value);
                if (names.length > 1) {
                    throw new IllegalStateException("More than 1 default extension name on extension " + type.getName()
                            + ": " + Arrays.toString(names));
                }
                if (names.length == 1) {
                    cachedDefaultName = names[0];
                }
            }
        }
    }

以dubbo中的org.apache.dubbo.rpc.protocol接口为例,在spi注解中有一个默认值dubbo
意味着如果没有显示指定协议类型, 默认采用dubbo协议发布服务

@SPI(""dubbo)
public interface Protocol{
	//...
}

createExtension()
针对扩展类进行包装
用到装饰器模式,通过装饰器模式来增强扩展类的功能

Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            if (CollectionUtils.isNotEmpty(wrapperClasses)) {
                for (Class<?> wrapperClass : wrapperClasses) {
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }

dubbo源码包中META-INF/dubbo/internal目录下
org.apache.dubbo.rpv.Protocol文件

filter=org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper

会对当前扩展点中原油的扩展类进行包装
假设当前扩展点是DubboProtocol
实际返回的扩展类对象可能为:
ProtocolFilterWrapper(ProtocolListenerWrapper(DubboOrotocol))

Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            if (CollectionUtils.isNotEmpty(wrapperClasses)) {
                for (Class<?> wrapperClass : wrapperClasses) {
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }

cachedWrapperClasses集合就是当前扩展点中适配的wrapper类
在loadDirectory()初始化的
loadDirectory()->loadResource()->loadClass()

private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name) throws NoSuchMethodException {
        //...
        if (clazz.isAnnotationPresent(Adaptive.class)) {
            cacheAdaptiveClass(clazz);
        } else if (isWrapperClass(clazz)) {
            cacheWrapperClass(clazz);
        } else {
        clazz.getconstructor();
        	//...
        }
    }

isWrapperClass为true,表示当前clazz是一个装饰器类
判断clazz类中是否存在一个带有扩展类的构造函数

public class ProtocolListenerWrapper implements Protocol {

    private final Protocol protocol;

    public ProtocolListenerWrapper(Protocol protocol) {
        if (protocol == null) {
            throw new IllegalArgumentException("protocol == null");
        }
        this.protocol = protocol;
    }
}

isWrappercalss()

    private void cacheWrapperClass(Class<?> clazz) {
        if (cachedWrapperClasses == null) {
            cachedWrapperClasses = new ConcurrentHashSet<>();
        }
        cachedWrapperClasses.add(clazz);
    }

得到这些装饰器类后,保存到cachedWrapperClasses集合
遍历集合,通过wrapper class.getconstructor(type).newInstance(instance)进行实例化

自适应扩展点

自适应扩展点(Adaptive)也可以理解为适配器扩展点
能够根据上下文动态匹配一个扩展类

ExtensionLoader.getExtensionLoader(class).getAdaptiveExtension();

通过@Adaptive注解声明,使用方式
1.@Adaptive注解定义在类上面,表示当前类为自适应扩展类

@Adaptive
public class AdaptiveCompiler implements Compiler {
    @Override
    public Class<?> compile(String code, ClassLoader classLoader) {
        return null;
    }
}

AdaptiveCompiler类就是自适应扩展类,通过ExtensionLoader.getExtensionLoader(Compiler.class).getAdaptiveExtension();
可以返回AdaptiveComipler类的实例
2.@Adaptive注解定义在方法层面,会通过动态代理的方式生成一个动态字节码,
进行自适应式配

@SPI("dubbo")
public interface Protocol {
    int getDefaultPort();
    
    @Adaptive
    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;

    @Adaptive
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;

	void destroy();
}

2个方法声明了@Adaptive注解,意味着这是一个自适应方法

Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

prptocol实例,是一个动态代理类,实现方法级别自适应调用
调用export()方法时,会根据上下文自动匹配到某个具体的实现类export方法中
getAdaptiveExtension()
1.从缓存中获取自适应扩展点实例
2.如果缓存未命中,则通过createAdaptiveExtension()创建自适应扩展点

    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("Failed to create adaptive instance: " + t.toString(), t);
                        }
                    }
                }
            } else {
                throw new IllegalStateException("Failed to create adaptive instance: " + createAdaptiveInstanceError.toString(), createAdaptiveInstanceError);
            }
        }

        return (T) instance;
    }

createAdaptiveExtension()
1.getAdaptiveExtensionClass()获得一个自适应扩展点实例
2.injectExtension()完成依赖注入

    private T createAdaptiveExtension() {
        try {
            return injectExtension((T) getAdaptiveExtensionClass().newInstance());
        } catch (Exception e) {
            throw new IllegalStateException("Can't create adaptive extension " + type + ", cause: " + e.getMessage(), e);
        }
    }

getAdaptiveExtensionclasses()
1.通过getExtensionClasses()加载当前传入类型的所有扩展点,缓存到一个集合中
2.如果cachedAdaptiveClass为空,则调用createAdaptiveExtensionClass()进行创建

    private Class<?> getAdaptiveExtensionClass() {
        getExtensionClasses();
        if (cachedAdaptiveClass != null) {
            return cachedAdaptiveClass;
        }
        return cachedAdaptiveClass = createAdaptiveExtensionClass();
    }

createAdaptiveExtensionClass():动态字节码的生成和加载
1.code是一个动态拼接的类
2.通过complier进行动态编译

    private Class<?> createAdaptiveExtensionClass() {
        String code = new AdaptiveClassCodeGenerator(type, cachedDefaultName).generate();
        ClassLoader classLoader = findClassLoader();
        org.apache.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
        return compiler.compile(code, classLoader);
    }

Protocol$Adaptive是一个动态生成的自适应扩展类

        Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
        protocol.export(...);

调用protocol.export()时,实际会调用Protocol#Adaptive类中export()方法,
根据dubbo服务配置的协议名称,通过getExtension()获得相应的扩展类
Protocol$Adaptive适配器模式,根据上下文信息自动适配到相应的协议扩展点来完成服务发布

dubbo中IOC和AOP

IOC

动态地向某个对象提供它所需要的其他对象
通过Dependency Injection(依赖注入)来实现的
createExtension()

{
		//...
        try {
            T instance = (T) EXTENSION_INSTANCES.get(clazz);
            if (instance == null) {
                EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
                instance = (T) EXTENSION_INSTANCES.get(clazz);
            }
            injectExtension(instance);
           //...
            return instance;
        } catch (Throwable t) {
            //...
    }

injectExtension()依赖注入实现

  1. 遍历被加载的扩展类中所有的set方法
  2. 得到set方法中的参数类型,如果参数类型是对象类型,则获得这个set方法中的属性名
  3. 使用自适应扩展点加载该属性名对应的扩展类
  4. 调用set方法完成赋值
private T injectExtension(T instance) {
        try {
            if (objectFactory != null) {
                for (Method method : instance.getClass().getMethods()) {
                    if (isSetter(method)) {
               			//遍历被加载的扩展类中所有set方法
                        if (method.getAnnotation(DisableInject.class) != null) {
                            continue;
                        }
                        //获得扩展类中方法的参数类型
                        Class<?> pt = method.getParameterTypes()[0];
                        //不是对象类型,跳过
                        if (ReflectUtils.isPrimitives(pt)) {
                            continue;
                        }
                        try {
                        	//获得方法对应的属性名称
                            String property = getSetterProperty(method);
                           //根据class及name,使用自适应扩展点加载并且通过set方法赋值                            Object object = objectFactory.getExtension(pt, property);
                            if (object != null) {
                                method.invoke(instance, object);
                            }
                        } catch (Exception e) {
                            logger.error("Failed to inject via method " + method.getName()
                                    + " of interface " + type.getName() + ": " + e.getMessage(), e);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return instance;
    }

如果当前加载的扩展类中存在一个成员对象,并为它提供了set方法
就会通过自适应扩展点进行加载并赋值

AOP

把业务逻辑和功能逻辑分离,在运行期间或者类加载期间进行织入

Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            if (CollectionUtils.isNotEmpty(wrapperClasses)) {
                for (Class<?> wrapperClass : wrapperClasses) {
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }

AOP思想体现是基于Wrapper装饰器类实现对原有的扩展类instance进行包装

dubbo和spring集成原理

服务发布主要有以下几个步骤
1.添加dubbo-spring-boot-starter依赖
2.定义org.apache.dubbo.config.annotation.Service注解
3.声明@DubboComponentScan,用于扫描@Service注解

@DubboComponentScan注解解析

主要通过@Import导入一个DubboComponentScanRegistrar类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboComponentScanRegistrar.class)
public @interface DubboComponentScan {

    String[] value() default {};

    String[] basePackages() default {};
    
    Class<?>[] basePackageClasses() default {};
}

DubboComponentScanRegistrar实现ImportBeanDefinitionRegistrar,并且重写registerBeanDefinitions()方法
1.获取扫描包的路径,在默认情况,扫描当前配置类所在包
2.注册@Service注解的解析类
3.注册@Reference注解的解析类

@Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		//获取扫描包路径
        Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
		//注册@Service的解析类
        registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);
		//注册@Reference的解析类
        registerReferenceAnnotationBeanPostProcessor(registry);
    }

ImportBeanDefinitionRegistrar是spring提供一种动态注入bean机制,类似ImportSelector
在registerBeanDefinitions()方法中,主要会实例化一些BeanDefinition注入Spring Ioc容器
registerServiceAnnotationBeanPostProcessor()方法:
把ServiceAnnotationBeanPostProcessor注册到容器

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();
        //将beanDefinition注册到Ioc容器
        BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);

    }

@DubboComponentScan注入
ServiceAnnotationBeanPostProcessor和ReferenceAnnotationBeanPoastProcessor对象
ServiceAnnotationBeanPostProcessor解析@Service注解
ReferenceAnnotationBeanPostProcessor解析@Reference注解

ServiceAnnotationBeanPostProcessor

核心逻辑:解析@Service注解

public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
        ResourceLoaderAware, BeanClassLoaderAware {
}

BeanDefinitionRegistryPostProcessor中定义的postProcessBeanDefinitionRegistry()
实现自定义的注册bean定义逻辑
1.调用registerBeans注册DubboBootstrapApplicationListener类
2.通过resolvePackagesToScan对packagesToScan参数进行去空格处理,并把配置文件中配置的扫描参数也一起处理一下
3.调用registerServerBeans()完成bean注册

@Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

        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!");
            }
        }

    }

核心逻辑registerServiceBeans()方法中,会查找需要扫描的指定包里有@Service注解的类
并注册成Bean
1.定义DubboClassPathDefinitionscanner扫描对象,扫描指定路径下的类,将符合条件的类装配Ioc容器中
2.BeanNameGenerator是Beans体系中比较重要的一个组件,通过一定的算法计算出需要装配的bean的name
3.addIncludeFilter设置scan的过滤条件,只扫描@Servioce注解装饰的类
4.遍历指定的包,通过findServiceBeanDefinitionHolders查找@Service注解修饰的类
5.通过registerServiceBean完成bean注册

private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
		//定义扫描对象
        DubboClassPathBeanDefinitionScanner scanner =
                new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);
                
		//beanName解析器
        BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
        scanner.setBeanNameGenerator(beanNameGenerator);
        
		//添加过滤器,用于过滤@Service注解修饰的对象
        scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));

        scanner.addIncludeFilter(new AnnotationTypeFilter(com.alibaba.dubbo.config.annotation.Service.class));

        for (String packageToScan : packagesToScan) {

            scanner.scan(packageToScan);
			
			//查找@Service修饰的类
            Set<BeanDefinitionHolder> beanDefinitionHolders =
                    findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);

            if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {

                for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                	//注册bean
                    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 + "]");
                }

            }

        }

    }

扫描指定路径下添加@Service注解的类,通过registerServiceBean注册ServiceBean
registerServiceBean(),ServiceBean是指org.apache.dubbo.config.spring.ServiceBean
1.resolveClass获取BeanDefinitionHolder中的Bean
2.findServiceAnnotation()会从beanClass类中找到@Service注解
3.getAnnotationAttributes获得注解中的属性,例如:loadBanance,cluster…
4.resolveServiceInterfaceClass()获得beanClass对应的接口定义
在@Service(interfaceClass=IHelloService.class)注解也可以声明interfaceClass
注解中声明的优先级最高,如果没有声明该属性,从父类中查找
5.buildServiceBeanDefinition用来构造org.apache.dubbo.config.spring.ServiceBean对象,每个dubbo服务的发布,最终都会出现一个ServiceBean
6.调用registerBeanDefinition将ServiceBean注入Ioc容器

private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry,
                                     DubboClassPathBeanDefinitionScanner scanner) {

		//获得需要发布的服务类
        Class<?> beanClass = resolveClass(beanDefinitionHolder);

		//得到该服务类上的注解
        Annotation service = findServiceAnnotation(beanClass);

        //获得注解中的属性,例如:cluster...
        AnnotationAttributes serviceAnnotationAttributes = getAnnotationAttributes(service, false, false);
		
		//获得服务类的接口声明
        Class<?> interfaceClass = resolveServiceInterfaceClass(serviceAnnotationAttributes, beanClass);

        String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();
		
		//构件ServiceBean
        AbstractBeanDefinition serviceBeanDefinition =
                buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName);

        // ServiceBean Bean name
        String beanName = generateServiceBeanName(serviceAnnotationAttributes, interfaceClass);

        if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
        	
        	//完成注册
            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?");
            }

        }

    }

并不是像普通的bean注入一样,直接将IHelloService对象的实例注入容器
而是注入一个ServiceBean对象,并不需要把自己注入spring Ioc容器中
需要把自己发布到网络上,提供给网络上的服务消费者来访问

当所有bean都处理完成之后,spring Ioc会发布一个事件
当触发这个事件时,会触发onContectRefreshedEvent方法
在这个方法中,可以看到dubbo服务启动的触发机制
dubboBootstrap.start()
进入org.apache.dubbo.config.ServiceConfig类中的export()方法
这个方法启动一个网络监听,从而实现服务发布

你可能感兴趣的:(apache,dubbo,驱动开发)