首先定义两个插件MyPlugin和MyPlugin2。都采用分离代理对象链的方式处理。因为后配置MyPlugin2所以先进行Myplugin2。两个插件代码几乎一样。问题来了,
statementHandler = (StatementHandler)object;
是第一次错误的位置报
org.apache.ibatis.plugin.Plugin cannot be cast to org.apache.ibatis.executor.statement.StatementHandler
去掉该行之后
String sql = (String)metaStatementHandler.getValue("delegate.boundSql.sql");报错</font>There is no getter for property named 'delegate' in 'class org.apache.ibatis.plugin.Plugin'
我想知道多个插件不能分离代理对象操作吗?
插件配置:
<plugin interceptor="com.ssm.chapter8.plugin.MyPlugin">
<property name="dbType" value="mysql"/>
</plugin>
<plugin interceptor="com.ssm.chapter8.plugin.MyPlugin2">
<property name="dbType" value="mysql2"/>
</plugin>
MyPlugin的intercept方法:
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
//进行绑定
MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
Object object = null;
/*分离代理对象链(由于目标类可能被多个拦截器[插件]拦截,从而形成多次代理,通过循环可以分离出最原始的目标类)*/
while(metaStatementHandler.hasGetter("h")){
object = metaStatementHandler.getValue("h");
metaStatementHandler = SystemMetaObject.forObject(object);
}
statementHandler = (StatementHandler)object;String sql = (String)metaStatementHandler.getValue("delegate.boundSql.sql")
Long parameterObject = (Long)metaStatementHandler.getValue("delegate.boundSql.parameterObject");
log.info("执行的SQL:【"+sql+"】");
log.info("before......");
//如果当前代理的事一个非代理对象,那么它就会回调用真实拦截对象的方法
//如果不是,那么它就会调度下一个插件代理对象的invoke方法
Object obj = invocation.proceed();
log.info("after......");
return obj;
}
MyPlugin2的intercept方法:
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
//进行绑定
MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
Object object = null;
/*分离代理对象链(由于目标类可能被多个拦截器[插件]拦截,从而形成多次代理,通过循环可以分离出最原始的目标类)*/
while(metaStatementHandler.hasGetter("h")){
object = metaStatementHandler.getValue("h");
metaStatementHandler = SystemMetaObject.forObject(object);
}
statementHandler = (StatementHandler)object;
String sql = (String)metaStatementHandler.getValue("delegate.boundSql.sql");
Long parameterObject = (Long)metaStatementHandler.getValue("delegate.boundSql.parameterObject");
log.info("Myplugin2执行的SQL:【"+sql+"】");
log.info("Myplugin2参数:【"+parameterObject+"】");
log.info("Myplugin2before......");
//如果当前代理的事一个非代理对象,那么它就会回调用真实拦截对象的方法
//如果不是,那么它就会调度下一个插件代理对象的invoke方法
Object obj = invocation.proceed();
log.info("Myplugin2after......");
return obj;
}
// 分离最后一个代理对象的目标类
– 技术来源于生活 5年前while (metaStatementHandler.hasGetter("target")) {
Object object = metaStatementHandler.getValue("target");
metaStatementHandler = MetaObject.forObject(object, OBJECT_FACTORY, OBJECT_WRAPPER_FACTORY);
}