diff --git a/hutool-extra/src/main/java/cn/hutool/extra/cglib/BeanCopierCache.java b/hutool-extra/src/main/java/cn/hutool/extra/cglib/BeanCopierCache.java
index 7378b9090..2573bd7d4 100644
--- a/hutool-extra/src/main/java/cn/hutool/extra/cglib/BeanCopierCache.java
+++ b/hutool-extra/src/main/java/cn/hutool/extra/cglib/BeanCopierCache.java
@@ -1,11 +1,9 @@
package cn.hutool.extra.cglib;
import cn.hutool.core.lang.SimpleCache;
-import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.util.StrUtil;
import net.sf.cglib.beans.BeanCopier;
-
-import java.beans.PropertyDescriptor;
+import net.sf.cglib.core.Converter;
/**
* BeanCopier属性缓存
@@ -15,20 +13,39 @@ import java.beans.PropertyDescriptor;
* @since 5.4.1
*/
public enum BeanCopierCache {
+ /**
+ * BeanCopier属性缓存单例
+ */
INSTANCE;
private final SimpleCache cache = new SimpleCache<>();
/**
- * 获得属性名和{@link PropertyDescriptor}Map映射
+ * 获得类与转换器生成的key在{@link BeanCopier}的Map中对应的元素
*
* @param srcClass 源Bean的类
* @param targetClass 目标Bean的类
- * @param supplier 缓存对象产生函数
- * @return 属性名和{@link PropertyDescriptor}Map映射
+ * @param converter 转换器
+ * @return Map中对应的BeanCopier
* @since 5.4.1
*/
- public BeanCopier get(Class> srcClass, Class> targetClass, Func0 supplier) {
- return this.cache.get(StrUtil.format("{}_{}", srcClass.getName(), srcClass.getName()), supplier);
+ public BeanCopier get(Class> srcClass, Class> targetClass, Converter converter) {
+ String key = genKey(srcClass, targetClass, converter);
+ return cache.get(key, () -> BeanCopier.create(srcClass, targetClass, converter != null));
+ }
+
+ /**
+ * 获得类与转换器生成的key
+ *
+ * @param srcClass 源Bean的类
+ * @param targetClass 目标Bean的类
+ * @param converter 转换器
+ * @return 属性名和Map映射的key
+ * @since 5.4.1
+ */
+ private String genKey(Class> srcClass, Class> targetClass, Converter converter) {
+
+ return converter == null ? StrUtil.format("{}#{}", srcClass.getName(), targetClass.getName())
+ : StrUtil.format("{}#{}#{}", srcClass.getName(), targetClass.getName(), converter.getClass().getName());
}
}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/cglib/CglibUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/cglib/CglibUtil.java
index cc0e56b0d..d4f8a637e 100644
--- a/hutool-extra/src/main/java/cn/hutool/extra/cglib/CglibUtil.java
+++ b/hutool-extra/src/main/java/cn/hutool/extra/cglib/CglibUtil.java
@@ -6,6 +6,11 @@ import net.sf.cglib.beans.BeanCopier;
import net.sf.cglib.beans.BeanMap;
import net.sf.cglib.core.Converter;
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
/**
* Cglib工具类
*
@@ -22,6 +27,7 @@ public class CglibUtil {
* @param source 源bean对象
* @param targetClass 目标bean类,自动实例化此对象
* @return 目标对象
+ * @since 5.4.1
*/
public static T copy(Object source, Class targetClass) {
return copy(source, targetClass, null);
@@ -36,10 +42,11 @@ public class CglibUtil {
* @param targetClass 目标bean类,自动实例化此对象
* @param converter 转换器,无需可传{@code null}
* @return 目标对象
+ * @since 5.4.1
*/
public static T copy(Object source, Class targetClass, Converter converter) {
final T target = ReflectUtil.newInstanceIfPossible(targetClass);
- copy(source, target);
+ copy(source, target, converter);
return target;
}
@@ -48,6 +55,7 @@ public class CglibUtil {
*
* @param source 源bean对象
* @param target 目标bean对象
+ * @since 5.4.1
*/
public static void copy(Object source, Object target) {
copy(source, target, null);
@@ -66,18 +74,84 @@ public class CglibUtil {
final Class> sourceClass = source.getClass();
final Class> targetClass = target.getClass();
- final BeanCopier beanCopier = BeanCopierCache.INSTANCE.get(
- sourceClass, targetClass,
- () -> BeanCopier.create(sourceClass, targetClass, null != converter));
+ final BeanCopier beanCopier = BeanCopierCache.INSTANCE.get(sourceClass, targetClass, converter);
beanCopier.copy(source, target, converter);
}
+ /**
+ * 拷贝List Bean对象属性
+ *
+ * @param source 源bean对象list
+ * @param target 目标bean对象
+ * @param 源bean类型
+ * @param 目标bean类型
+ * @return 目标bean对象list
+ * @since 5.4.1
+ */
+ public static List copyList(List source, Supplier target) {
+ return copyList(source, target, null, null);
+ }
+
+ /**
+ * 拷贝List Bean对象属性
+ *
+ * @param source 源bean对象list
+ * @param target 目标bean对象
+ * @param converter 转换器,无需可传{@code null}
+ * @param 源bean类型
+ * @param 目标bean类型
+ * @return 目标bean对象list
+ * @since 5.4.1
+ */
+ public static List copyList(List source, Supplier target, Converter converter) {
+ return copyList(source, target, converter, null);
+ }
+
+ /**
+ * 拷贝List Bean对象属性
+ *
+ * @param source 源bean对象list
+ * @param target 目标bean对象
+ * @param callback 回调对象
+ * @param 源bean类型
+ * @param 目标bean类型
+ * @return 目标bean对象list
+ * @since 5.4.1
+ */
+ public static List copyList(List source, Supplier target, BiConsumer callback) {
+ return copyList(source, target, null, callback);
+ }
+
+ /**
+ * 拷贝List Bean对象属性
+ *
+ * @param source 源bean对象list
+ * @param target 目标bean对象
+ * @param converter 转换器,无需可传{@code null}
+ * @param callback 回调对象
+ * @param 源bean类型
+ * @param 目标bean类型
+ * @return 目标bean对象list
+ * @since 5.4.1
+ */
+ public static List copyList(List source, Supplier target, Converter converter, BiConsumer callback) {
+ return source.stream().map(s -> {
+ T t = target.get();
+ copy(source, t, converter);
+ if (callback != null) {
+ callback.accept(s, t);
+ }
+ return t;
+ }).collect(Collectors.toList());
+ }
+
/**
* 将Bean转换为Map
*
* @param bean Bean对象
* @return {@link BeanMap}
+ * @since 5.4.1
*/
public static BeanMap toMap(Object bean) {
return BeanMap.create(bean);