阿里面試,問到Mybatis攔截器,3年Java答不上來?

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)~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容