开源rpc框架
https://github.com/joyrpc/joyrpc.git
采用微内核架构
定义插件的接口,抽象为扩展点,还能设置扩展点名字
@Extensible("consumer")
public interface Consumer extends Ordered {
}
加载实现扩展点的所有插件
public <T, M> ExtensionPoint<T, M> getOrLoadExtensionPoint(final Class<T> extensible,
final ExtensionLoader loader,
final Comparator<ExtensionMeta<?, ?>> comparator,
final Classify<T, M> classify) {
if (extensible == null) {
return null;
}
//判断是否重复添加
ExtensionPoint<T, M> result = getExtensionPoint(extensible);
if (result == null) {
//获取扩展点注解
Extensible annotation = extensible.getAnnotation(Extensible.class);
//构造扩展点名称
Name<T, String> extensibleName = new Name<>(extensible, annotation != null && !annotation.value().isEmpty() ? annotation.value() : extensible.getName());
//加载插件
List<ExtensionMeta<T, M>> metas = new LinkedList<ExtensionMeta<T, M>>();
load(extensible, extensibleName, loader, classify, metas);
//排序
Comparator<ExtensionMeta<?, ?>> c = comparator == null ? AscendingComparator.INSTANCE : comparator;
metas.sort(c);
result = (ExtensionPoint<T, M>) add(new ExtensionSpi(extensibleName, metas, c, classify));
}
return result;
}
/**
* 加载扩展点
*
* @param extensible 扩展类型
* @param extensibleName 扩展点名称
* @param loader 扩展加载器
* @param classify 扩展分类器
* @param metas 扩展元数据集合
* @param <T>
* @param <M>
*/
protected <T, M> void load(final Class<T> extensible, final Name<T, String> extensibleName,
final ExtensionLoader loader, final Classify<T, M> classify,
final List<ExtensionMeta<T, M>> metas) {
//加载插件
Collection<Plugin<T>> plugins = loader == null ? this.loader.load(extensible) : loader.load(extensible);
for (Plugin<T> plugin : plugins) {
Class<T> pluginClass = plugin.name.getClazz();
Extension extension = pluginClass.getAnnotation(Extension.class);
ExtensionMeta<T, M> meta = new ExtensionMeta<T, M>();
//记录加载器信息,便于卸载加载器
meta.setLoader(plugin.loader);
meta.setExtensible(extensibleName);
meta.setName(plugin.name);
meta.setProvider(extension != null && !extension.provider().isEmpty() ? extension.provider() : pluginClass.getName());
meta.setInstantiation(plugin.instantiation == null ? Instantiation.ClazzInstance.INSTANCE : plugin.instantiation);
meta.setTarget(plugin.target);
meta.setSingleton(plugin.isSingleton() != null ? plugin.isSingleton() :
(!Prototype.class.isAssignableFrom(pluginClass) && (extension == null || extension.singleton())));
//获取插件,不存在则创建
T target = meta.getTarget();
M name;
if (classify != null) {
name = classify.type(target, meta.getName());
} else if (Type.class.isAssignableFrom(pluginClass)) {
name = ((Type<M>) target).type();
} else {
name = (M) (extension != null && !extension.value().isEmpty() ? extension.value() :
pluginClass.getName());
}
meta.setExtension(new Name<>(pluginClass, name));
meta.setOrder(Ordered.class.isAssignableFrom(pluginClass) ? ((Ordered) target).order() :
(extension == null ? Ordered.ORDER : extension.order()));
//判断是否禁用了该插件
if (!Disable.isDisable(meta)) {
metas.add(meta);
}
}
}
@Extension(value = "myConsumer", provider = "test")
public class MyConsumer implements Consumer {
@Override
public int order() {
return ORDER;
}
}
@Extension("myConsumer1")
public class MyConsumer1 implements Consumer, Ordered {
@Override
public int order() {
return 0;
}
}
@Extension("myConsumer1")
@ConditionalOnJava("1.6")
@ConditionalOnClass("xxx.ddf123.df")
public class MyConsumer2 implements Consumer, Ordered {
@Override
public int order() {
return -1;
}
}
resources/META-INF/services/io.joyrpc.extension.Consumer
io.joyrpc.extension.MyConsumer
io.joyrpc.extension.MyConsumer1
io.joyrpc.extension.MyConsumer2