From 4f26d3aba57ef6c53614350a9760a6d87ffdd3e7 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 20 Jun 2023 10:27:02 +0800 Subject: [PATCH] add record support --- .../dromara/hutool/core/bean/BeanDesc.java | 34 +++++++++++++++++-- .../dromara/hutool/core/bean/BeanUtil.java | 24 ++++++------- .../core/convert/impl/RecordConverter.java | 2 +- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanDesc.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanDesc.java index 15e7e5538..d5c5f28f5 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanDesc.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanDesc.java @@ -16,8 +16,8 @@ import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.map.CaseInsensitiveMap; import org.dromara.hutool.core.reflect.FieldUtil; -import org.dromara.hutool.core.reflect.method.MethodUtil; import org.dromara.hutool.core.reflect.ModifierUtil; +import org.dromara.hutool.core.reflect.method.MethodUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.BooleanUtil; @@ -152,6 +152,36 @@ public class BeanDesc implements Serializable { * 只有与属性关联的相关Getter和Setter方法才会被读取,无关的getXXX和setXXX都被忽略 */ private void init() { + if (RecordUtil.isRecord(this.beanClass)) { + initForRecord(); + } else{ + initForBean(); + } + } + + /** + * 针对Record类的反射初始化 + */ + private void initForRecord() { + final Method[] getters = MethodUtil.getPublicMethods(this.beanClass, method -> 0 == method.getParameterCount()); + for (final Field field : FieldUtil.getFields(this.beanClass)) { + // 排除静态属性和对象子类 + if (!ModifierUtil.isStatic(field) && !FieldUtil.isOuterClassField(field)) { + for (final Method getter : getters) { + if (field.getName().equals(getter.getName())) { + //record对象,getter方法与字段同名 + final PropDesc prop = new PropDesc(field, getter, null); + this.propMap.putIfAbsent(prop.getFieldName(), prop); + } + } + } + } + } + + /** + * 普通Bean初始化 + */ + private void initForBean() { final Method[] gettersAndSetters = MethodUtil.getPublicMethods(this.beanClass, MethodUtil::isGetterOrSetterIgnoreCase); PropDesc prop; for (final Field field : FieldUtil.getFields(this.beanClass)) { @@ -299,7 +329,7 @@ public class BeanDesc implements Serializable { if (StrUtil.startWith(fieldName, "is", ignoreCase)) { // isName -》 isName - if(StrUtil.equals(fieldName, m.getName(), ignoreCase)){ + if (StrUtil.equals(fieldName, m.getName(), ignoreCase)) { return true; } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java index bab0b19c5..747aed932 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java @@ -12,6 +12,7 @@ package org.dromara.hutool.core.bean; +import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.bean.copier.BeanCopier; import org.dromara.hutool.core.bean.copier.CopyOptions; import org.dromara.hutool.core.bean.copier.ValueProvider; @@ -19,6 +20,7 @@ import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.collection.set.SetUtil; import org.dromara.hutool.core.convert.Convert; +import org.dromara.hutool.core.convert.impl.RecordConverter; import org.dromara.hutool.core.lang.mutable.MutableEntry; import org.dromara.hutool.core.map.CaseInsensitiveMap; import org.dromara.hutool.core.map.MapUtil; @@ -27,24 +29,12 @@ import org.dromara.hutool.core.reflect.ConstructorUtil; import org.dromara.hutool.core.reflect.FieldUtil; import org.dromara.hutool.core.reflect.ModifierUtil; import org.dromara.hutool.core.text.StrUtil; -import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.util.ObjUtil; -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.beans.PropertyEditor; -import java.beans.PropertyEditorManager; +import java.beans.*; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; @@ -678,10 +668,16 @@ public class BeanUtil { * @param ignoreProperties 不拷贝的的属性列表 * @return 目标对象 */ + @SuppressWarnings("unchecked") public static T copyProperties(final Object source, final Class tClass, final String... ignoreProperties) { if (null == source) { return null; } + if(RecordUtil.isRecord(tClass)){ + // issue#I7EO3U + // 转换record时,ignoreProperties无效 + return (T) RecordConverter.INSTANCE.convert(tClass, source); + } final T target = ConstructorUtil.newInstanceIfPossible(tClass); copyProperties(source, target, CopyOptions.of().setIgnoreProperties(ignoreProperties)); return target; diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/RecordConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/RecordConverter.java index bd9db80ca..6fd5b18b3 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/RecordConverter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/RecordConverter.java @@ -46,7 +46,7 @@ public class RecordConverter extends AbstractConverter { valueProvider = (ValueProvider) value; } else if (value instanceof Map) { valueProvider = new MapValueProvider((Map) value); - } else if (BeanUtil.isWritableBean(value.getClass())) { + } else if (BeanUtil.isReadableBean(value.getClass())) { valueProvider = new BeanValueProvider(value); }