mybatis学习之路-1(插件模块)

使用设计模式:动态代理,方法链

1.InterceptorChain 拦截链

通过方法链的模式,层层包装拦截对象,

pluginAll 通过for循环一次次封装对象,

addInterceptor 添加拦截器 要在pluginAll 之前调用才有效

getInterceptors 获取所有的拦截器

 

2.Interceptor 拦截器接口

intercept 拦截方法 在次方法内可以对拦截目标进行特殊处理

 

setProperties 通过此方法可以将配置文件中的属性设置到拦截器中

plugin 打包拦截对象 通过Plugin.wrap ->动态代理

 

eg:PluginTest

@Intercepts({

@Signature(type = Map.class, method = "get", args = {Object.class})})

public static class AlwaysMapPlugin implements Interceptor {

@Override

public Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException {

System.out.println("拦截到了方法:" + invocation.getMethod() + "\n 参数:"+invocation.getArgs().toString() + "\n 被拦截对象:" + invocation.getTarget());

//调用原有逻辑通过invocation.proceed()

return invocation.proceed();

}

}

 

@Intercepts 标名此类是一个拦截器

@Signature 标名拦截的类与方法

type 拦截的类

method 拦截的方法

args 拦截的参数

因为JAVA重载的存在,所以需要类+方法+参数才能确认拦截的方法

 

3.Invocation 封装调用对象的过程(即封装method.invoke(obj,args))

4.Plugin 插件核心类 通过此类实现对代理对象的封装,

这里使用的动态代理模式是JDK模式

wrap 包装对象,方法

//包装目标对象

public static Object wrap(Object target, Interceptor interceptor) {

//获取拦截器可以拦截的所有类和方法

Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);

Class<?> type = target.getClass();

//根据拦截器信息和当前目标的类型 取出所有可供拦截的接口

Class<?>[] interfaces = getAllInterfaces(type, signatureMap);

//如果当前对象可以被拦截 那么生成一个代理对象

if (interfaces.length > 0) {

//获取代理对象

return Proxy.newProxyInstance(

type.getClassLoader(),

interfaces,

new Plugin(target, interceptor, signatureMap));

}

return target;

}

invoke 执行方法

/**

* 根据拦截对象的类获取可供拦截的方法

*/

Set<Method> methods = signatureMap.get(method.getDeclaringClass());

if (methods != null && methods.contains(method)) {

//执行拦截器的方法

return interceptor.intercept(new Invocation(target, method, args));

}

//执行普通调用

return method.invoke(target, args);

 

getSignatureMap 解析类上的注解 获取拦截信息

 

总结:插件模块使用了方法链 + 动态代理 实现了代码的高可用,如果需要新增一个拦截器,不用关注主体流程,直接在类上加注解和标明需要拦截的类方法即可实现拦截功能;符合单一职责原则,每个类各司其职 如果自己的业务上有这种需求 也可以直接挪过来使用,有很好的拓展性

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值