Mybatis是java后台开发必不可少的DAO工具,开发过程中经常遇到需要扩展框架功能的地方,这时了解拦截器就很有必要了,本文主要介绍拦截器的接口、位置和原理用法等,并给出了简要的示例。
最近整理的Java架构学习视频和大厂项目底层知识点,需要的同学欢迎私信我【资料】发给你~一起学习进步!
一、接口定义
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
- intercept方法用于拦截处调用,业务需要实现自定义逻辑
- plugin方法用于封装目标对象,通过该方法可以返回一个代理,官方提供了示例:return Plugin.wrap(target, this)
- setProperties方法可以配置自定义相关属性,即:接口实现对象的参数配置
二、拦截位置
- Executor是 Mybatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过 ResultSetHandler进行自动映射。
- StatementHandler是Mybatis封装jdbc执行sql的对象。
- ParameterHandler是Mybatis实现Sql入参设置的对象,插件可以改变Sql的参数默认设置。
- ResultSetHandler是Mybatis把ResultSet集合映射成POJO的接口对象,可以对Mybatis的结果集自动映射进行修改。
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
三、多拦截器
<property name="plugins">
<array>
<ref bean="paginationInterceptorDDB"/>
<ref bean="rowBoundPaginationInterceptor"/>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
helperDialect=mysql
reasonable=true
supportMethodsArguments=true
params=count=countSql
autoRuntimeDialect=true
</value>
</property>
</bean>
<-- OrderBy 一定要在分页插件下面(主要是为了避免 count 也被增加排序) -->
<bean class="tk.mybatis.orderbyhelper.OrderByHelper"/>
</array>
</property>
public class InterceptorChain {
private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
public void addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
public List<Interceptor> getInterceptors() {
return Collections.unmodifiableList(interceptors);
}
}
mybatis拦截器主要采用责任链+JDK动态代理的方式,将拦截对象一层层包装成代理对象然后返回注入框架,这样框架使用的时候会一层层剥开,并调用对应的拦截方法。
四、拦截示例
<-- mybatis-config.xml -->
<plugins>
<plugin interceptor="org.mybatis.example.ExamplePlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
// ExamplePlugin.java
@Intercepts({@Signature(
type= Executor.class,
method = "update",
args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
return invocation.proceed();
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
}
}
来源:网易工程师-肖恒进
有任何问题欢迎留言交流~
整理总结不易,如果觉得这篇文章有意思的话,欢迎转发、收藏,给我一些鼓励~
有想看的内容或者建议,敬请留言!
最近利用空余时间整理了一些精选Java架构学习视频和大厂项目底层知识点,需要的同学欢迎私信我发给你~一起学习进步!有任何问题也欢迎交流~
Java日记本,每日存档超实用的技术干货学习笔记,每天陪你前进一点点~