SOFARPC —— SPI 解析

一、前言

我之前研究过微博的Motan框架(当时接触的第一个RPC框架),当时懵懵懂懂,现在,上手SOFARPC框架,感觉比较轻松,事物的本质都是相通的。以前写博文,会逐行分析源码,慢慢地发现,源码其实就是作者的思想。看完源码后,弄懂作者的意图,可能类似读书的过程,书由厚读到薄,随着眼界的开阔,再看源码时,会带着评判的眼光,看出哪里写的好与不好,这也就是读书又由薄到厚的下一个阶段吧!废话结束,开始正文。

 

二、特点

SPI多应用于框架的建设中,方便解耦,利于扩展。SOFARPC的SPI,与原生的SPI相比,有如下特点:

★按需加载
★单例设置
★别名
★设置扩展类的优先级,可进行覆盖
★指定扩展类位置
★解耦
SOFARPC的SPI流程图如下(记住这张图):

 

三、示例

好的框架,离不开好的示例。看一下SOFARPC给我们提供的SPI示例。

public class ExtensionMain {
    public static void main(String[] args) {
        Person person = ExtensionLoaderFactory.getExtensionLoader(Person.class).getExtension("A");
// 上面这行,大家自己debug跟一下就好,代码很简单,记住上面流程图,一步步跟踪代码,之后,会有一个更深刻的认识的! person.getName(); } } @Extensible // 这个注解表示它是一个扩展点
public interface Person { void getName(); } @Extension("A") // 这个注解表示它是一个扩展类,它的别名是A public class PersonA implements Person { private final static Logger LOGGER = LoggerFactory.getLogger(PersonA.class); @Override public void getName() { LOGGER.info("li wei"); } }

在上方示例的基础上,配置META-INF下的扩展描述文件,我们便可以实现自由扩展。

这里,贴上了扩展的注解类。

 1 /**
 2  * <p>代表这个类或者接口是可扩展的,默认单例、不需要编码</p>
 3  */
 4 @Documented
 5 @Retention(RetentionPolicy.RUNTIME)
 6 @Target({ ElementType.TYPE })
 7 public @interface Extensible {
 8 
 9     /**
10      * 指定自定义扩展文件名称,默认就是全类名
11      *
12      * @return 自定义扩展文件名称
13      */
14     String file() default "";
15 
16     /**
17      * 扩展类是否使用单例,默认使用
18      *
19      * @return 是否使用单例
20      */
21     boolean singleton() default true;
22 
23     /**
24      * 扩展类是否需要编码,默认不需要
25      *
26      * @return 是否需要编码
27      */
28     boolean coded() default false;
29 }

 

 1 /**
 2  * 扩展点
 3  *
 4  * @author <a href=mailto:zhanggeng.zg@antfin.com>GengZhang</a>
 5  * @see Extensible
 6  */
 7 @Documented
 8 @Retention(RetentionPolicy.RUNTIME)
 9 @Target({ ElementType.TYPE })
10 public @interface Extension {
11     /**
12      * 扩展点名字
13      *
14      * @return 扩展点名字
15      */
16     String value();
17 
18     /**
19      * 扩展点编码,默认不需要,当接口需要编码的时候需要
20      *
21      * @return 扩展点编码
22      * @see Extensible#coded()
23      */
24     byte code() default -1;
25 
26     /**
27      * 优先级排序,默认不需要,大的优先级高
28      *
29      * @return 排序
30      */
31     int order() default 0;
32 
33     /**
34      * 是否覆盖其它低{@link #order()}的同名扩展
35      *
36      * @return 是否覆盖其它低排序的同名扩展
37      * @since 5.2.0
38      */
39     boolean override() default false;
40 
41     /**
42      * 排斥其它扩展,可以排斥掉其它低{@link #order()}的扩展
43      *
44      * @return 排斥其它扩展
45      * @since 5.2.0
46      */
47     String[] rejection() default {};
48 }

 

posted @ 2019-03-06 22:08  Mr.袋鼠  阅读(672)  评论(0编辑  收藏  举报