面向切面-拦截器
大约 3 分钟
面向切面-拦截器
拦截器
拦截器(Interceptor)是一种非侵入式的机制,用于在函数执行前和执行后对函数进行逻辑扩展。以下是拦截器的基本特点和使用方法:
- 标识拦截器:使用方法上的
@Hook
注解可以标识方法为拦截器。拦截器分为前置拦截器和后置拦截器,前者需要实现HookBefore
接口,后者需要实现HookAfter
接口。 - 拦截器入参:拦截器的入参包含当前拦截函数的定义以及拦截函数的入参。拦截器可以根据函数定义与入参来处理执行逻辑。
- 拦截器配置:拦截器可以根据函数定义、函数类型、优先级等条件进行配置。可以使用
@Hook
注解或 Hook 模型的字段(如module
、model
、fun
、函数类型、active
)来筛选出对当前拦截方法生效的拦截器。 - 拦截器优先级:拦截器的优先级通过
priority
属性进行设置。优先级数字越小,拦截器越先执行。
拦截器提供了一种灵活的方式来扩展函数的功能,同时通过优,可以对拦截器的执行顺序和生效范围进行精细化的管理和调整。
属性解释
@Hook(module = {DemoModule.MODULE_MODULE},model = {PetShop.MODEL_MODEL},fun = {"sayHello"}, priority = Integer.MAX_VALUE, displayName = "sayHello扩展点")
这个注解的定义允许在类和方法级别使用,即 ElementType.TYPE
和 ElementType.METHOD
。 这段代码定义了一个名为 Hook
的注解,它具有以下属性:
displayName
: 用于指定拦截器的显示名称。hookType
: 拦截器类型,默认为HookTypeEnum.BEFORE
,表示前置拦截器。functionTypes
: 函数类型数组,用于指定拦截器适用的函数类型。priority
: 执行优先级,默认值为MetaValueConstants.priorityForHook
,数字越小表示优先级越高。module
: 执行模块数组,用于指定拦截器适用的执行模块。model
: 模型数组,用于指定拦截器适用的模型。fun
: 函数数组,用于指定拦截器适用的函数。description
: 拦截器的描述信息。active
: 是否激活拦截器,默认为true
。
前置拦截器举例
package pro.shushi.pamirs.demo.core.hook;
...//import
@Component
public class PetShopSayHelloHookBefore implements HookBefore {
@Override
@Hook(module = {DemoModule.MODULE_MODULE},model = {PetShop.MODEL_MODEL},fun = {"sayHello"})
public Object run(Function function, Object... args) {
if(args!=null && args[0]!=null){
PetShop arg = (PetShop)args[0];
arg.setShopName("hookbefore:"+ arg.getShopName());
}
return args;
}
}
后置拦截器举例
package pro.shushi.pamirs.demo.core.hook;
...//import
import pro.shushi.pamirs.meta.api.dto.fun.Function;
@Component
public class PetShopSayHelloHookAfter implements HookAfter {
@Override
@Hook(model = {PetShop.MODEL_MODEL},fun = {"sayHello"})
public Object run(Function function, Object ret) {
if (ret == null) {
return null;
}
PetShop result =null;
if (ret instanceof Object[]) {
Object[] rets = (Object[])((Object[])ret);
if (rets.length == 1) {
result = (PetShop)rets[0];
}
} else {
result = (PetShop)ret;
}
result.setShopName(result.getShopName()+":hookAfter");
return result;
}
}
注意点
- 不管前置拦截器,还是后置拦截器都可以配置多,根据拦截器的优先级priority属性可以对拦截器的执行顺序进行调整。priority数字越小,越先执行;
- 拦截器必须是jar依赖,不然执行会报错。配置拦截器注意配置过滤条件;
- 模块启动yml文件可以过滤不需要执行的hook,具体配置见模块之yml文件结构详解
- 不是由前端发起而是后端编程调用,默认不会生效,如果要生效请参考框架之元位指令