SOFARPC —— SPI 解析

一、前言

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

二、特点

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

★按需加载
★单例设置
★别名
★设置扩展类的优先级,可进行覆盖
★指定扩展类位置
★解耦
SOFARPC的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下的扩展描述文件,我们便可以实现*扩展。

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

 /**
* <p>代表这个类或者接口是可扩展的,默认单例、不需要编码</p>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface Extensible { /**
* 指定自定义扩展文件名称,默认就是全类名
*
* @return 自定义扩展文件名称
*/
String file() default ""; /**
* 扩展类是否使用单例,默认使用
*
* @return 是否使用单例
*/
boolean singleton() default true; /**
* 扩展类是否需要编码,默认不需要
*
* @return 是否需要编码
*/
boolean coded() default false;
}
 /**
* 扩展点
*
* @author <a href=mailto:zhanggeng.zg@antfin.com>GengZhang</a>
* @see Extensible
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface Extension {
/**
* 扩展点名字
*
* @return 扩展点名字
*/
String value(); /**
* 扩展点编码,默认不需要,当接口需要编码的时候需要
*
* @return 扩展点编码
* @see Extensible#coded()
*/
byte code() default -1; /**
* 优先级排序,默认不需要,大的优先级高
*
* @return 排序
*/
int order() default 0; /**
* 是否覆盖其它低{@link #order()}的同名扩展
*
* @return 是否覆盖其它低排序的同名扩展
* @since 5.2.0
*/
boolean override() default false; /**
* 排斥其它扩展,可以排斥掉其它低{@link #order()}的扩展
*
* @return 排斥其它扩展
* @since 5.2.0
*/
String[] rejection() default {};
}
上一篇:Qt 打开指定的文件


下一篇:mybatis动态sql排序无效