perf:对hutool的BeanUtil工具类做补充

打印 上一主题 下一主题

主题 1673|帖子 1673|积分 5021

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
分享一个自定义的BeanUtil,继承的是hutool的工具类,然后自己扩充了几个方法;
1、实现了两个对象覆盖非空属性的功能(经常使用),不需要设置CopyOptions;
2、两个对象,对指定前缀的属性进行拷贝,其中copyExtendProperties就会拷贝对象中的extend1,extend2,extend3...等等。
  1. @Slf4j
  2. @UtilityClass
  3. public class MyBeanUtils extends BeanUtil {
  4.     /**
  5.      * 两个对象覆盖非空属性(忽略指定字段)
  6.      *
  7.      * @param source        源 bean
  8.      * @param target        目标 bean
  9.      * @param ignoresFields 忽略的字段列表
  10.      */
  11.     public static <S, T> void overrideNonNullProperties(S source, T target, String... ignoresFields) {
  12.         Map<String, Object> sourceMap = BeanUtil.beanToMap(source, false, false);
  13.         Map<String, Object> targetMap = BeanUtil.beanToMap(target, false, false);
  14.         overrideNonNullPropertiesInternal(sourceMap, target, targetMap, ignoresFields);
  15.     }
  16.     /**
  17.      * 将 Map 赋值非空属性到指定对象(忽略指定字段)
  18.      *
  19.      * @param sourceMap     源 Map
  20.      * @param target        目标 bean
  21.      * @param ignoresFields 忽略的字段列表
  22.      */
  23.     public static <T> void overrideNonNullProperties(Map<String, Object> sourceMap, T target, String... ignoresFields) {
  24.         Map<String, Object> targetMap = BeanUtil.beanToMap(target, false, false);
  25.         overrideNonNullPropertiesInternal(sourceMap, target, targetMap, ignoresFields);
  26.     }
  27.     /**
  28.      * 内部方法,处理覆盖非空属性的逻辑
  29.      *
  30.      * @param sourceMap     源对象的属性映射
  31.      * @param target        目标对象
  32.      * @param targetMap     目标对象的属性映射
  33.      * @param ignoresFields 忽略的字段列表
  34.      */
  35.     private static <T> void overrideNonNullPropertiesInternal(Map<String, Object> sourceMap, T target,
  36.                                                               Map<String, Object> targetMap, String... ignoresFields) {
  37.         // 移除忽略的字段
  38.         for (String field : ignoresFields) {
  39.             targetMap.remove(field);
  40.         }
  41.         // 遍历源对象的属性,只处理非空值,并确认目标对象中存在该字段
  42.         sourceMap.forEach((fieldName, value) -> {
  43.             if (value != null && targetMap.containsKey(fieldName)) {
  44.                 BeanUtil.setFieldValue(target, fieldName, value);
  45.             }
  46.         });
  47.     }
  48.     /**
  49.      * 将源对象的属性通过反射赋值到目标对象(只处理以 "extend" 开头的字段)
  50.      *
  51.      * @param source 源对象
  52.      * @param target 目标对象
  53.      */
  54.     public static void copyExtendProperties(Object source, Object target) {
  55.         copyPropertiesWithPrefix(source, target, "extend");
  56.     }
  57.     /**
  58.      * 将源对象的属性通过反射赋值到目标对象(只处理以指定前缀开头的字段)
  59.      *
  60.      * @param source             源对象
  61.      * @param target             目标对象
  62.      * @param propertyNamePrefix 处理的字段名前缀
  63.      * @param ignoresFields      忽略的字段列表
  64.      */
  65.     public static void copyPropertiesWithPrefix(Object source, Object target, String propertyNamePrefix, String... ignoresFields) {
  66.         Field[] fields = source.getClass().getDeclaredFields();
  67.         Set<String> ignoresSet = Set.of(ignoresFields);
  68.         for (Field field : fields) {
  69.             String fieldName = field.getName();
  70.             if (fieldName.startsWith(propertyNamePrefix)) {
  71.                 try {
  72.                     ReflectionUtils.makeAccessible(field);
  73.                     Object value = field.get(source);
  74.                     if (value != null) {
  75.                         Field targetField = getTargetField(fieldName, target.getClass());
  76.                         if (targetField != null && !ignoresSet.contains(fieldName)) {
  77.                             ReflectionUtils.makeAccessible(targetField);
  78.                             ReflectionUtils.setField(targetField, target, value);
  79.                         }
  80.                     }
  81.                 } catch (IllegalAccessException e) {
  82.                     log.error("非法访问字段: {}", fieldName, e);
  83.                 }
  84.             }
  85.         }
  86.     }
  87.     /**
  88.      * 安全地获取目标对象中的字段。
  89.      *
  90.      * @param fieldName 字段名
  91.      * @param clazz     目标对象的类对象
  92.      * @return 目标字段或null(如果未找到)
  93.      */
  94.     private static Field getTargetField(String fieldName, Class<?> clazz) {
  95.         try {
  96.             Field field = ReflectionUtils.findField(clazz, fieldName);
  97.             if (field == null) {
  98.                 log.debug("目标对象中未找到字段: {}", fieldName);
  99.             }
  100.             return field;
  101.         } catch (Exception e) {
  102.             log.error("获取目标字段异常: {}", fieldName, e);
  103.             return null;
  104.         }
  105.     }
  106. }
复制代码
ps:以下是我整理的java面试资料,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!
链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java知识宝典》 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

拉不拉稀肚拉稀

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表