¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.core.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.lang.SimpleCache; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.ReflectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.springframework.cglib.beans.BeanCopier; |
| | | import org.springframework.cglib.beans.BeanMap; |
| | | import org.springframework.cglib.core.Converter; |
| | | |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * beanæ·±æ·è´å·¥å
·(åºäº cglib æ§è½ä¼å¼) |
| | | * <p> |
| | | * éç¹ cglib 䏿¯æ æ·è´å°é¾å¼å¯¹è±¡ |
| | | * ä¾å¦: æºå¯¹è±¡ æ·è´å° ç®æ (é¾å¼å¯¹è±¡) |
| | | * 请åºå好`æµ
æ·è´`å`æ·±æ·è´`ååä½¿ç¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class BeanCopyUtils { |
| | | |
| | | /** |
| | | * å对象åºäºclasså建æ·è´ |
| | | * |
| | | * @param source æ°æ®æ¥æºå®ä½ |
| | | * @param desc æè¿°å¯¹è±¡ 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V copy(T source, Class<V> desc) { |
| | | if (ObjectUtil.isNull(source)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(desc)) { |
| | | return null; |
| | | } |
| | | final V target = ReflectUtil.newInstanceIfPossible(desc); |
| | | return copy(source, target); |
| | | } |
| | | |
| | | /** |
| | | * å对象åºäºå¯¹è±¡å建æ·è´ |
| | | * |
| | | * @param source æ°æ®æ¥æºå®ä½ |
| | | * @param desc 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V copy(T source, V desc) { |
| | | if (ObjectUtil.isNull(source)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(desc)) { |
| | | return null; |
| | | } |
| | | BeanCopier beanCopier = BeanCopierCache.INSTANCE.get(source.getClass(), desc.getClass(), null); |
| | | beanCopier.copy(source, desc, null); |
| | | return desc; |
| | | } |
| | | |
| | | /** |
| | | * å表对象åºäºclasså建æ·è´ |
| | | * |
| | | * @param sourceList æ°æ®æ¥æºå®ä½å表 |
| | | * @param desc æè¿°å¯¹è±¡ 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> List<V> copyList(List<T> sourceList, Class<V> desc) { |
| | | if (ObjectUtil.isNull(sourceList)) { |
| | | return null; |
| | | } |
| | | if (CollUtil.isEmpty(sourceList)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return StreamUtils.toList(sourceList, source -> { |
| | | V target = ReflectUtil.newInstanceIfPossible(desc); |
| | | copy(source, target); |
| | | return target; |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * beanæ·è´å°map |
| | | * |
| | | * @param bean æ°æ®æ¥æºå®ä½ |
| | | * @return map对象 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> Map<String, Object> copyToMap(T bean) { |
| | | if (ObjectUtil.isNull(bean)) { |
| | | return null; |
| | | } |
| | | return BeanMap.create(bean); |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°bean |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param beanClass beanç±» |
| | | * @return bean对象 |
| | | */ |
| | | public static <T> T mapToBean(Map<String, Object> map, Class<T> beanClass) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(beanClass)) { |
| | | return null; |
| | | } |
| | | T bean = ReflectUtil.newInstanceIfPossible(beanClass); |
| | | return mapToBean(map, bean); |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°bean |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param bean bean对象 |
| | | * @return bean对象 |
| | | */ |
| | | public static <T> T mapToBean(Map<String, Object> map, T bean) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(bean)) { |
| | | return null; |
| | | } |
| | | BeanMap.create(bean).putAll(map); |
| | | return bean; |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°map |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param clazz è¿åç对象类å |
| | | * @return map对象 |
| | | */ |
| | | public static <T, V> Map<String, V> mapToMap(Map<String, T> map, Class<V> clazz) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(clazz)) { |
| | | return null; |
| | | } |
| | | Map<String, V> copyMap = new LinkedHashMap<>(map.size()); |
| | | map.forEach((k, v) -> copyMap.put(k, copy(v, clazz))); |
| | | return copyMap; |
| | | } |
| | | |
| | | /** |
| | | * BeanCopier屿§ç¼å<br> |
| | | * ç¼åç¨äºé²æ¢å¤æ¬¡åå°é æçæ§è½é®é¢ |
| | | * |
| | | * @author Looly |
| | | * @since 5.4.1 |
| | | */ |
| | | public enum BeanCopierCache { |
| | | /** |
| | | * BeanCopier屿§ç¼ååä¾ |
| | | */ |
| | | INSTANCE; |
| | | |
| | | private final SimpleCache<String, BeanCopier> cache = new SimpleCache<>(); |
| | | |
| | | /** |
| | | * è·å¾ç±»ä¸è½¬æ¢å¨çæçkeyå¨{@link BeanCopier}çMapä¸å¯¹åºçå
ç´ |
| | | * |
| | | * @param srcClass æºBeançç±» |
| | | * @param targetClass ç®æ Beançç±» |
| | | * @param converter 转æ¢å¨ |
| | | * @return Mapä¸å¯¹åºçBeanCopier |
| | | */ |
| | | public BeanCopier get(Class<?> srcClass, Class<?> targetClass, Converter converter) { |
| | | final 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 |
| | | */ |
| | | private String genKey(Class<?> srcClass, Class<?> targetClass, Converter converter) { |
| | | final StringBuilder key = StrUtil.builder() |
| | | .append(srcClass.getName()).append('#').append(targetClass.getName()); |
| | | if (null != converter) { |
| | | key.append('#').append(converter.getClass().getName()); |
| | | } |
| | | return key.toString(); |
| | | } |
| | | } |
| | | |
| | | } |