Closed bugCats closed 5 months ago
你自己的东西让别人怎么取?
你自己的东西让别人怎么取?
至少有2种方式:
1、简单粗暴,直接判断target是否包含h属性。这样就算是使用装饰模式,被装饰对象属性名如果为h,同样可以获取到真实对象:
MetaObject handler = SystemMetaObject.forObject(target);
while (handler.hasGetter("h")) {
Object object = handler.getValue("h");
handler = SystemMetaObject.forObject(object);
}
while (handler.hasGetter("target")) {
Object object = handler.getValue("target");
handler = SystemMetaObject.forObject(object);
}
2、提供获取原始对象接口:如果使用装饰模式,装饰类再实现该接口,返回真实对象;
public interface PluginProxyAdapter {
Object theProxyObject();
}
//com.baomidou.mybatisplus.core.toolkit.PluginUtils#realTarget,优先判断PluginProxyAdapter
public static <T> T realTarget(Object target) {
if( target instanceof PluginProxyAdapter){
return realTarget(((PluginProxyAdapter) target).theProxyObject());
}
if (Proxy.isProxyClass(target.getClass())) {
MetaObject metaObject = SystemMetaObject.forObject(target);
return realTarget(metaObject.getValue("h.target"));
}
return (T) target;
}
private static class StatementHandlerWrap implements StatementHandler, PluginProxyAdapter {
private final StatementHandler h; //模拟jdk动态代理后的目标对象属性名
private StatementHandlerWrap(StatementHandler statementHandler) {
this.h = statementHandler;
}
@Override
public Object theProxyObject() {
return this.h;
}
......
}
方法总比困难多
问题解决了吗?我将关闭本issue,如需要可以reopen
如果在插件中使用装饰模式增强、并非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
异常信息:
实际原因: com.baomidou.mybatisplus.core.toolkit.PluginUtils#realTarget,只有在入参target是JDK代理对象时,才会执行获取实际对象逻辑。