插件的原理:
1.每個建立出來的對象都不是直接傳回
interceptorChain.pluginAll(parameterHandler);
2.擷取到所有的Interceptor(攔截器)(插件需要實作的接口)
調用interceptor.plugin(target);傳回target包裝後的對象
3.插件機制,我們可以使用插件為目标對象建立一個代理對象,AOP(面向切面)
-
我們的插件可以為四大對象建立出代理對象
代理對象就可以攔截到四大對象的每一個執行。
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
自定義攔截器的步驟:
1.編寫攔截器
public class MyFirstPlugin implements Interceptor {
/**
* 攔截目标對象方法的執行
* @param invocation
* @return
* @throws Throwable
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("MyFirstPlugin...intercept"+invocation.getMethod());
//動态的改變一下sql運作的參數,以前1号學生,實際查詢5号學生
Object target = invocation.getTarget();
// System.out.println("目前攔截到的對象"+invocation.getTarget());
//拿到StatementHandler==>ParameterHandler==>parameterObject
//拿到target的中繼資料
MetaObject metaObject = SystemMetaObject.forObject(target);
Object value = metaObject.getValue("parameterHandler.parameterObject");
// System.out.println("sql語句用的參數是"+value);
//修改完sql語句要執行的參數
metaObject.setValue("parameterHandler.parameterObject",5);
//放行的方法
Object proceed = invocation.proceed();
return proceed;
}
/**
* 包裝目标對象,将增強的對象和攔截器包裝起來并傳回
* @param target
* @return
*/
@Override
public Object plugin(Object target) {
System.out.println("MyFirstPlugin..plugin:mybatis将要包裝的對象"+target);
//我們可以借助Plugin的wrap方法來使用目前Interceptor包裝我們的目标對象
Object wrap = Plugin.wrap(target, this);
//傳回目前target建立的動态代理
return wrap;
}
/**
* 将插件注冊時的property屬性
* @param properties
*/
@Override
public void setProperties(Properties properties) {
// System.out.println("插件配置的資訊");
}
}
2.編寫 簽名注解
/**
* 完成插件簽名:
* 告訴Mybatis目前插件用來攔截哪個對象的哪個方法
*/
@Intercepts(
{
@Signature(type = StatementHandler.class,
method = "parameterize",args = java.sql.Statement.class)
})
3.配置
<plugins>
<!-- 分頁插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--<!– config params as the following –>-->
<!--<property name="dialect" value="mysql"/>-->
<property name="reasonable" value="true"/>
<!--<property name="dialect" value="mysql"/>-->
</plugin>
<plugin interceptor="com.itt.plugins.MyFirstPlugin">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</plugin>
</plugins>
- 測試