1. 原理
MyBatis可以帮助我们在语句执行过程中的某一点进行拦截调用。它的实现原理就是插件采用责任链模式,通过动态代理组织多个拦截器(插件)将四大核心对象进行拦截增强变成个代理对象,从而可以改变Mybatis的默认对象的行为(诸如SQL分页改写,统计性能,打印日志等),mybatis源码环境搭建参考,通过mybatis的源码分析,我们可以更清楚的了解到策略模式和动态代理模式是如何使用的,后续在代码逻辑中可以借鉴
2. 流程图
3. 代码示例
<plugins>
<plugin interceptor="com.example.Interceptor.ParameterInterceptor">
<property name="dialect" value="mysql" />
</plugin>
</plugins>
@Intercepts({ @Signature(type = ParameterHandler.class, method = "setParameters", args = { PreparedStatement.class}) })
public class ParameterInterceptor implements Interceptor {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 这个方法是mybatis的核心方法,要实现自定义逻辑,基本都是改造这个方法,其中invocation参数可以通过反射要获取原始方法和对应参数信息
* @param invocation
* @return
* @throws Throwable
*/
public Object intercept(Invocation invocation) throws Throwable {
ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();
Object object = parameterHandler.getParameterObject();
logger.info("mybatis parameterHandler object:{}", object);
return invocation.proceed();
}
/**
* 它的作用是用来生成一个拦截对象,也就是代理对象,使得被代理的对象一定会经过intercept方法,通常都会使用mybatis提供的工具类Plugin来获取代理对象,如果有自己独特需求,可以自定义
* @param target
* @return
*/
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
/**
* 这个方法就是用来设置插件的一些属性
* @param properties
*/
public void setProperties(Properties properties) {
String dialect = properties.getProperty("dialect");
logger.info("mybatis intercept dialect:{}", dialect);
}
}