当前位置: 移动技术网 > IT编程>开发语言>Java > Dubbo源码分析之SPI(二)

Dubbo源码分析之SPI(二)

2019年12月18日  | 移动技术网IT编程  | 我要评论

一、概述

  本篇文章是dubbo spi源码分析的第二篇,接着第一篇继续分析dubbo spi的内容,我们主要介绍 getdefaultextension() 获取默认扩展点方法。

由于此方法比较简单,我们略过示例部分,直接分析源码。

二、源码分析

  获取默认扩展方法getdefaultextension()是一个public、可对外提供调用的方法。我们知道,dubbo中扩展点接口必须要有@spi注解修饰,@spi注解代码如下:

 1 @documented
 2 @retention(retentionpolicy.runtime)
 3 @target({elementtype.type})
 4 public @interface spi {
 5 
 6     /**
 7      * default extension name
 8      */
 9     string value() default "";
10 
11 }

  注解可以修饰类和接口,同时提供 一个默认为空的value字段。

  这个value字段 就是本篇文章要介绍的默认扩展实现。

  现在我们来看getdefaultextension()方法内部:

1 public t getdefaultextension() {
2     getextensionclasses();
3     // cacheddefaultname为@spi中的value
4     if (null == cacheddefaultname || cacheddefaultname.length() == 0 || "true".equals(cacheddefaultname)) {
5         return null;
6     }
7     return getextension(cacheddefaultname);
8 }

  第二行方法 getextensionclasses()是加载配置文本文件,获取配置的扩展点实现类,方法执行完,会把配置文本文件的key和扩展点实现类的class对象存储在cachedclasses 成员变量中,这个我们在第一篇已经介绍过。

  接下来就是方法的关键点,成员变量cacheddefaultname 的判断了,如果cacheddefaultname 为空或为”true“ 直接返回 null,如果cacheddefaultname 不为空,则调用getextension(..)方法,返回扩展点实现类对象。这个方法我们在第一篇也已经介绍了。现在我们只需要分析cacheddefaultname的赋值点 就ok 了。

  成员变量cacheddefaultname 我们在第一篇有介绍到,不知道大家是否还有印象,我们现在看看变量定义:

1 // spi()内value,默认的接口实现
2 private string cacheddefaultname;

  私有的字符串变量。

  变量cacheddefaultname的赋值,我们先提前介绍下,其实就是在加载配置文本文件的过程中进行的,具体的方法调用链为:

1 getdefaultextension() -->getextensionclasses()-->loadextensionclasses()

  这几个方法我们都有介绍,我们现在看看loadextensionclasses():

 1 private map<string, class<?>> loadextensionclasses() {
 2     // 获取注解 spi的接口
 3     // type为传入的扩展接口,必须有@spi注解
 4     final spi defaultannotation = type.getannotation(spi.class);
 5     // 获取默认扩展实现value,如果存在,赋值给cacheddefaultname
 6     if (defaultannotation != null) {
 7         string value = defaultannotation.value();
 8         if ((value = value.trim()).length() > 0) {
 9             // @spi value 只能是一个,不能为逗号分割的多个
10             // @spi value为默认的扩展实现
11             string[] names = name_separator.split(value);
12             if (names.length > 1) {
13                 throw new illegalstateexception("more than 1 default extension name on extension " + type.getname() + ": " + arrays.tostring(names));
14             }
15             if (names.length == 1)
16                 cacheddefaultname = names[0];
17         }
18     }
19     // 加载三个目录配置的扩展类
20     map<string, class<?>> extensionclasses = new hashmap<string, class<?>>();
21     // meta-inf/dubbo/internal
22     loaddirectory(extensionclasses, dubbo_internal_directory);
23     // meta-inf/dubbo
24     loaddirectory(extensionclasses, dubbo_directory);
25     // meta-inf/services/
26     loaddirectory(extensionclasses, services_directory);
27     return extensionclasses;
28 }

  没错,对cacheddefaultname的赋值,仅此一出。

  cacheddefaultname的内容就是解析@spi注解的value内容。此处赋值后,getdefaultextension()方法的返回就是根据这个值进行扩展点获取并返回的。

三、总结

  获取默认扩展点的方法getdefaultextension() 逻辑很简单,就是解析出注解@spi的value内容,通过前一篇介绍的getextension(..)方法进行扩展点获取。如果@spi没有配置value或者设置的是”true“,getdefaultextension()方法返回的就是null。

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网