-
Notifications
You must be signed in to change notification settings - Fork 49
JPlugin扩展开发
sunlet edited this page May 13, 2022
·
14 revisions
对于Jplugin容器管理的Bean,系统自动处理RefXXX引用关系。可以你自己new 出来的对象,默认不会自动处理。如果希望处理,执行以下操作:
PluginEnvirement.getInstance().resolveRefAnnotation(object);
注意:在启动阶段,这个调用完毕以后相关Ref不会立即生效,但是会在后续阶段专门对属性赋值。
-
步骤一:写一个实现类实现IAnnoForAttrHandler 接口,泛型是标注类。比如:下面是RefService的实现:
public class ServiceAttrAnnoHandler implements IAnnoForAttrHandler<RefService> { public static IServiceExtensionResolver serviceExtensionResolver; public Class<RefService> getAnnoClass() { return RefService.class; } public Class getAttrClass() { return Object.class; } /** * 先查找RuleService,再查找Service */ public Object getValue(Object theObject, Class fieldType, RefService anno) { Object o=null; try { // 发生查找错误,不要抛出异常,后续查找 if (serviceExtensionResolver != null) { o = serviceExtensionResolver.resolve(theObject, fieldType, anno); } } catch (RuntimeException e) { o = null; } if (o == null){ o = get(fieldType,anno); } return o; } private Object get(Class fieldType, RefService anno) { if (anno.name().equals("")) return ServiceFactory.getService(fieldType); else return ServiceFactory.getService(anno.name(), fieldType); } } 补充说明:如果有必要可以实现接口的 另一个defualt方法 default Object getValue(Object theObject,Class fieldType,Field f, T anno) ,可以获取到的信息更多一些。
-
步骤二:在Plugin的构造函数当中,加入下面一句:
public Plugin(){ ... ExtensionKernelHelper.addAnnoAttrHandlerExtension(this, 步骤一的类名.class); ... }
和其他容器集成时,JPlugin的启动可以分成两阶段进行:第一阶段准备好所有JPlugin管理的扩展对象;第二阶段进行初始化。
比如和Spring集成,启动步骤可以按照如下规划:
步骤1:启动JPlugin的步骤1
PluginEnvirement.getInstance().startup(null,PluginEnvirement.STARTTYPE_FIRST)
步骤2:初始化spring beans
......
步骤3:启动JPlugin步骤2
PluginEnvirement.getInstance().startup(null,PluginEnvirement.STARTTYPE_SECOND)
有时候我们希望在JPlugin扩展实例上增加方法级的标注支持,比如对方法加锁@Lock。 这类需求可以通过Extension拦截器来实现ExtensionInterceptor。
假如你想增加标注@Lock
步骤一:先写一个@Lock的标注类,这步省略了
步骤二:注册一个拦截器扩展,可以在Plugin.java构造函数加入
public class Plugin{
public Plugin(){
ExtensionKernelHelper.addExtensionInterceptorExtension(this, LockIncept.class,null,EP_SERVICE,null,null , Lock.class);
//xxxxxxx
}
}
步骤三:步骤二当中LockIncept的实现代码
public class LockInceptextends AbstractExtensionInterceptor {
@Override
protected Object execute(FilterChain fc, ExtensionInterceptorContext ctx) throws Throwable {
try{
getYourLock();
//拦截方法的操作可以从ctx当中获取到当前执行的方法等上下文信息
return fc.next(ctx)
}finally{
releaseYourLock();
}
}
}