Mybatis是java后臺(tái)開發(fā)必不可少的DAO工具,開發(fā)過程中經(jīng)常遇到需要擴(kuò)展框架功能的地方,這時(shí)了解攔截器就很有必要了,本文主要介紹攔截器的接口、位置和原理用法等,并給出了簡(jiǎn)要的示例。
最近整理的Java架構(gòu)學(xué)習(xí)視頻和大廠項(xiàng)目底層知識(shí)點(diǎn),需要的同學(xué)歡迎私信我【資料】發(fā)給你~一起學(xué)習(xí)進(jìn)步!
一、接口定義
public interface Interceptor {
? Object intercept(Invocation invocation) throws Throwable;? ? ?
? Object plugin(Object target);? ?
? void setProperties(Properties properties);
}
- intercept方法用于攔截處調(diào)用,業(yè)務(wù)需要實(shí)現(xiàn)自定義邏輯
- plugin方法用于封裝目標(biāo)對(duì)象,通過該方法可以返回一個(gè)代理,官方提供了示例:return Plugin.wrap(target, this)
- setProperties方法可以配置自定義相關(guān)屬性,即:接口實(shí)現(xiàn)對(duì)象的參數(shù)配置
二、攔截位置
- Executor是 Mybatis的內(nèi)部執(zhí)行器,它負(fù)責(zé)調(diào)用StatementHandler操作數(shù)據(jù)庫(kù),并把結(jié)果集通過 ResultSetHandler進(jìn)行自動(dòng)映射。
- StatementHandler是Mybatis封裝jdbc執(zhí)行sql的對(duì)象。
- ParameterHandler是Mybatis實(shí)現(xiàn)Sql入?yún)⒃O(shè)置的對(duì)象,插件可以改變Sql的參數(shù)默認(rèn)設(shè)置。
- ResultSetHandler是Mybatis把ResultSet集合映射成POJO的接口對(duì)象,可以對(duì)Mybatis的結(jié)果集自動(dòng)映射進(jìn)行修改。
- 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 一定要在分頁(yè)插件下面(主要是為了避免 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攔截器主要采用責(zé)任鏈+JDK動(dòng)態(tài)代理的方式,將攔截對(duì)象一層層包裝成代理對(duì)象然后返回注入框架,這樣框架使用的時(shí)候會(huì)一層層剝開,并調(diào)用對(duì)應(yīng)的攔截方法。
四、攔截示例
<-- 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) {
? }
}
來源:網(wǎng)易工程師-肖恒進(jìn)
有任何問題歡迎留言交流~
整理總結(jié)不易,如果覺得這篇文章有意思的話,歡迎轉(zhuǎn)發(fā)、收藏,給我一些鼓勵(lì)~
有想看的內(nèi)容或者建議,敬請(qǐng)留言!
最近利用空余時(shí)間整理了一些精選Java架構(gòu)學(xué)習(xí)視頻和大廠項(xiàng)目底層知識(shí)點(diǎn),需要的同學(xué)歡迎私信我發(fā)給你~一起學(xué)習(xí)進(jìn)步!有任何問題也歡迎交流~
Java日記本,每日存檔超實(shí)用的技術(shù)干貨學(xué)習(xí)筆記,每天陪你前進(jìn)一點(diǎn)點(diǎn)~