修复因使用反射读取JSON自定义类型导致性能下降为原来1/3的问题

by SHA-1: 5b2d2050d2251c735c9bb41aebd40b632fd1d33f
This commit is contained in:
zhoupeng 2023-08-07 18:54:01 +08:00
parent 5889435e09
commit 7a30dff976
3 changed files with 28 additions and 7 deletions

View File

@ -8,7 +8,6 @@ import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import java.io.Serializable;
import java.lang.reflect.Field;
@ -83,10 +82,8 @@ public class CopyOptions implements Serializable {
return null;
}
final String name = value.getClass().getName();
if(ArrayUtil.contains(new String[]{"cn.hutool.json.JSONObject", "cn.hutool.json.JSONArray"}, name)){
// 由于设计缺陷导致JSON转Bean时无法使用自定义的反序列化器此处采用反射方式修复bug此类问题会在6.x解决
return ReflectUtil.invoke(value, "toBean", ObjectUtil.defaultIfNull(type, Object.class));
if(value instanceof IJSONTypeConverter) {
return ((IJSONTypeConverter)value).toBean(ObjectUtil.defaultIfNull(type, Object.class));
}
return Convert.convertWithCheck(type, value, null, ignoreError);

View File

@ -0,0 +1,23 @@
package cn.hutool.core.bean.copier;
import java.lang.reflect.Type;
/**
* JSON自定义转换扩展接口,因core模块无法直接调用json模块而创建,
* 使用此接口避免使用反射调用toBean方法而性能太差
*
* @author mkeq
*/
public interface IJSONTypeConverter {
/**
* 转为实体类对象
*
* @param <T> Bean类型
* @param type {@link Type}
* @return 实体类对象
* @since 3.0.8
*/
<T> T toBean(Type type);
}

View File

@ -1,6 +1,7 @@
package cn.hutool.json;
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.bean.copier.IJSONTypeConverter;
import cn.hutool.core.lang.TypeReference;
import java.io.Serializable;
@ -13,7 +14,7 @@ import java.lang.reflect.Type;
*
* @author Looly
*/
public interface JSON extends Cloneable, Serializable {
public interface JSON extends Cloneable, Serializable, IJSONTypeConverter {
/**
* 获取JSON配置
@ -177,7 +178,7 @@ public interface JSON extends Cloneable, Serializable {
* @since 3.0.8
*/
default <T> T toBean(Type type) {
return JSONConverter.jsonConvert(type, this, getConfig());
return toBean(type, getConfig().isIgnoreError());
}
/**