mybatis-plus
mybatis-plus copied to clipboard
如果在插件中使用装饰模式增强、并非jdk动态代理时,会导致com.baomidou.mybatisplus.core.toolkit.PluginUtils#realTarget获取实际处理对象失败
如果在插件中使用装饰模式增强、并非jdk动态代理时,会导致com.baomidou.mybatisplus.core.toolkit.PluginUtils#realTarget获取实际处理对象失败
当前使用版本 mybatisplus所有版本
当前环境信息 Java8 + Mysql5.7
描述bug现象 之前使用mybatis,自定义了很多插件,插件使用装饰模式增强,并非JDK动态代理。 最近打算升级到mybatis-plus,发现在com.baomidou.mybatisplus.core.toolkit.PluginUtils#realTarget处报错,此方法并未分离出来实际对象。
提供问题复现步骤
拦截器示例:使用装饰模式增强StatementHandler.prepare
@Component
public class MyInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) {
return null;
}
@Override
public Object plugin(Object target) {
if ( target instanceof StatementHandler ) {
return new StatementHandlerWrap((StatementHandler) target); //此处只演示StatementHandler,装饰其他对象也会造成同样异常
}
return target;
}
private static class StatementHandlerWrap implements StatementHandler {
private final StatementHandler h; //模拟jdk动态代理后的目标对象属性名
private StatementHandlerWrap(StatementHandler statementHandler) {
this.h = statementHandler;
}
@Override
public Statement prepare(Connection connection, Integer timeout) throws SQLException {
//增强代码
return h.prepare(connection, timeout);
}
@Override
public void parameterize(Statement statement) throws SQLException {
h.parameterize(statement);
}
@Override
public void batch(Statement statement) throws SQLException {
h.batch(statement);
}
@Override
public int update(Statement statement) throws SQLException {
return h.update(statement);
}
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
return h.query(statement, resultHandler);
}
@Override
public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
return h.queryCursor(statement);
}
@Override
public BoundSql getBoundSql() {
return h.getBoundSql();
}
@Override
public ParameterHandler getParameterHandler() {
return h.getParameterHandler();
}
}
}
异常信息:
Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'delegate' in 'class xxx.xxx.MyInterceptor$StatementHandlerWrap'
at org.apache.ibatis.reflection.Reflector.getGetInvoker(Reflector.java:374)
at org.apache.ibatis.reflection.MetaClass.getGetInvoker(MetaClass.java:164)
at org.apache.ibatis.reflection.wrapper.BeanWrapper.getBeanProperty(BeanWrapper.java:162)
at org.apache.ibatis.reflection.wrapper.BeanWrapper.get(BeanWrapper.java:49)
at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:122)
at com.baomidou.mybatisplus.core.toolkit.PluginUtils.mpStatementHandler(PluginUtils.java:72)
at com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor.beforePrepare(BlockAttackInnerInterceptor.java:53)
at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:102)
...
实际原因: com.baomidou.mybatisplus.core.toolkit.PluginUtils#realTarget,只有在入参target是JDK代理对象时,才会执行获取实际对象逻辑。