dubbo annocation scan启动过程解析

ubbo通过spring的加载而启动,本文分析了通过注解方式加载的过程.

1.      Schema扩展

通过注解加载dubbo,需要在spring的配置文件中添加:

<dubbo:annotation package="com.package.to.be.scanned" />

dubbo:annotation是dubbo基于spring的schema扩展。(Schema扩展的介绍可以参考:http://blog.csdn.net/cutesource/article/details/5864562。详细信息参考w3cshool)

dubbo的schema描述文件在dubbo-config-spring模块下。我们可以看到在其中定义的xml描述信息。

Spring会默认加载spring.handlers和spring.schemas,从而感知schema描述文档。从中我们可以看到schema的处理器:com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

DubboNamespaceHandler继承了NamespaceHandlerSupport。因此不需要实现所有的解析工作,只要将自定义schema中的元素解析器注册进来就可以。


[java]  view plain  copy
 
  1. public void init() {  
  2.         registerBeanDefinitionParser("application"new DubboBeanDefinitionParser(ApplicationConfig.classtrue));  
  3.         registerBeanDefinitionParser("module"new DubboBeanDefinitionParser(ModuleConfig.classtrue));  
  4.         registerBeanDefinitionParser("registry"new DubboBeanDefinitionParser(RegistryConfig.classtrue));  
  5.         registerBeanDefinitionParser("monitor"new DubboBeanDefinitionParser(MonitorConfig.classtrue));  
  6.         registerBeanDefinitionParser("provider"new DubboBeanDefinitionParser(ProviderConfig.classtrue));  
  7.         registerBeanDefinitionParser("consumer"new DubboBeanDefinitionParser(ConsumerConfig.classtrue));  
  8.         registerBeanDefinitionParser("protocol"new DubboBeanDefinitionParser(ProtocolConfig.classtrue));  
  9.         registerBeanDefinitionParser("service"new DubboBeanDefinitionParser(ServiceBean.classtrue));  
  10.         registerBeanDefinitionParser("reference"new DubboBeanDefinitionParser(ReferenceBean.classfalse));  
  11.         registerBeanDefinitionParser("annotation"new DubboBeanDefinitionParser(AnnotationBean.classtrue));  
  12. }  

在代码中我们可以看到被注册的annotation解析器:DubboBeanDefinitionParserParser中的privatestatic BeanDefinition parse()方法实现了解析,并返回解析后生成bean的定义。接下来我们就看一下dubbo dubbo:annotation的加载过程。

 

2. Dubbo 自定义元素加载

Spring启动后,加载配置文件信息,得到dubbo的schema元素定义信息: <dubbo:annotation package="com.package.to.be.scanned" />

         根据DubboNamespaceHandler中注册的信息,spring找到解析类并调用解析方法:DubboBeanDefinitionParser. Parse()

第一步,初始化RootBeanDefinition

第二步,获取beanid

第三步,将xml中配置的信息放到beandefinition的PropertyValues中。

最后返回AnnotationBean的BeanDefinition。

至此,annotation对应的bean定义解析完毕,spring知晓了AnnotationBean的存在。


3.  AnnotationBean运行

AnnotationBean实现了很多spring的特殊bean接口:DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor,ApplicationContextAware。这保证AnnotationBean能够在spring加载的各个时期实现自己的功能。

注解扫描的功能在beanfactory初始化完成调用接口BeanFactoryPostProcessor. postProcessBeanFactory中实现。

实现代码:

[java]  view plain  copy
 
  1. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)  
  2.             throws BeansException {  
  3.         if (annotationPackage == null || annotationPackage.length() == 0) {  
  4.             return;  
  5.         }  
  6.         if (beanFactory instanceof BeanDefinitionRegistry) {  
  7.             try {  
  8.                 // init scanner  
  9.                 Class<?> scannerClass = ReflectUtils.forName("org.springframework.context.annotation.ClassPathBeanDefinitionScanner");  
  10.                 Object scanner = scannerClass.getConstructor(new Class<?>[] {BeanDefinitionRegistry.classboolean.class}).newInstance(new Object[] {(BeanDefinitionRegistry) beanFactory, true});  
  11.                 // add filter  
  12.                 Class<?> filterClass = ReflectUtils.forName("org.springframework.core.type.filter.AnnotationTypeFilter");  
  13.                 Object filter = filterClass.getConstructor(Class.class).newInstance(Service.class);  
  14.                 Method addIncludeFilter = scannerClass.getMethod("addIncludeFilter", ReflectUtils.forName("org.springframework.core.type.filter.TypeFilter"));  
  15.                 addIncludeFilter.invoke(scanner, filter);  
  16.                 // scan packages  
  17.                 String[] packages = Constants.COMMA_SPLIT_PATTERN.split(annotationPackage);  
  18.                 Method scan = scannerClass.getMethod("scan"new Class<?>[]{String[].class});  
  19.                 scan.invoke(scanner, new Object[] {packages});  
  20.             } catch (Throwable e) {  
  21.                 // spring 2.0  
  22.             }  
  23.         }  
  24. }  

AnnotationBean的参数annotationPackage,就是在beandefinition创建时,从xml中读取到spring中。源码通过ClassPathBeanDefinitionScanner. doScan扫描annotationPackage下所有的文件。配置成bean的类会定义成BeanDefinition,注册到spring。

你可能感兴趣的:(dubbo annocation scan启动过程解析)