-
Notifications
You must be signed in to change notification settings - Fork 1
Implement_extension_loader
Geng Zhang edited this page Feb 18, 2017
·
2 revisions
为了对RPC各个环节的都有充足的可扩展性,提供SPI的能力。 所以内部的实现和第三方实现都是绝对平等的。
- 提供一个注解,可以在接口类或者抽象类上面加,表示该类为一个扩展点
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface Extensible { /** * 指定自定义扩展文件名称,默认就是全类名 * * @return 自定义扩展文件名称 */ String file() default ""; /** * 扩展类是否使用单例,默认使用 * * @return 是否使用单例 */ boolean singleton() default true; /** * 扩展类是否需要编码,默认不需要 * * @return 是否需要编码 */ boolean coded() default false; }
- 提供一个注解,表示该类为一个扩展实现
@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; }
- 通过META-INF/service/bsoa下的接口描述文件来进行SPI描述
-
指定扩展点
@Extensible(singleton = false) public abstract class Client { }
-
指定扩展实现类
@Extension("failover") public class FailoverClient extends AbstractClient { }
-
扩展描述文件
META-INF/services/bsoa/io.bsoa.rpc.client.Client
failover=io.bsoa.rpc.client.FailoverClient 或者直接 io.bsoa.rpc.client.FailoverClient
加载需要调用方法ExtensionLoader(Class<T> interfaceClass, ExtensionLoaderListener<T> listener)
主要逻辑如下:
- 首先读取
bsoa_default.json
和bsoa.json
,找到扩展描述文件存放的文件夹:extension.load.path
属性 - 找到接口类对应的扩展描述文件的文件名(默认就是接口名,也可以自己指定)
- 循环加载这个文件下的扩展描述文件,按行读取。 注意:同一个接口的同一个别名对应唯一的一个实现类,不能重复。
- 保存扩展实现类的alias和实现类的对应关系。
- 如果ExtensionLoaderListener不为空,则通知Listener。
- 使用时调用方法
public T getExtension(String alias){}
- 从加载时保存的对应关系中找到实现类。
- 如果扩展点是单例模式的,那么返回单例,否则返回一个新的实例
Copyright www.bsoa.io 2016-2017