感謝尚硅谷的老師講解
插件:
插件存在的目的就相當於javaweb中的攔截器,可以攔截要操作的四大對象,包裝對象
額外添加內容,使得Mybatis的靈活性更強。
插件原理 :
* 在四大對象創建的時候 * 1、每個創建出來的對象不是直接返回的,而是 * interceptorChain.pluginAll(parameterHandler); * 2、獲取到所有的Interceptor(攔截器)(插件需要實現的接口); * 調用interceptor.plugin(target);返回target包裝后的對象 * 3、插件機制,我們可以使用插件為目標對象創建一個代理對象;AOP(面向切面) * 我們的插件可以為四大對象創建出代理對象; * 代理對象就可以攔截到四大對象的每一個執行;
總結:
如果是插件聲明攔截的對象,那么就會plugin返回包裝類,為其創建一個代理對象,可以對指定方法進行攔截。
public Object pluginAll(Object target) { for (Interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; }
先來簡單介紹下四大對象
一張圖明白四大對象關系:
注意: ParameterHandler和ResultSetHandler都是用TypeHander處理類型
Executor //執行增刪改查操作 StatementHandler //處理sql語句預編譯,設置參數等相關工作; ParameterHandler //設置預編譯參數用的 ResultSetHandler //處理結果集
四大對象每個創建的時候都有一個
注意:每個對象創建的時候 都會調用所有插件的plugin方法 對其進行包裝操作
interceptorChain.pluginAll(parameterHandler);
如果多個插件對一個對象的方法進行攔截,就會產生層層攔截效果 第一個對象的動態代理對象傳給第二個插件包裝
當執行目標方法的時候先調用第二個插件的intercept 然后調用第一個插件的intercept方法 最后執行真正的目標方法.
一張圖來理解執行順序:
總結:
創建動態代理的時候 是按照插件配置順序創建層層代理對象
執行目標方法,是按逆向順序執行的
轉: https://blog.csdn.net/qq_38409944/article/details/82494187