使用BeanCopier工具类拷贝JavaBean

JavaBean拷贝

深拷贝和浅拷贝概念

浅拷贝 Shallow Copy

对基本类型的属性会进行值传递,当修改其中一个对象中的属性时,不会影响另一个对象中的属性
对引用数据的属性,比如数组或某类对象,会进行引用传递,及两个对象中的属性指向同一个实例对象,修改对象会相互影响。

深拷贝 Deep Copy

深拷贝就是对引用类型的数据,也进行拷贝,开辟新的内存空间,两个bean之间相互修改自己的属性不产生影响。

开源工具类

  • apache的BeanUtils 原理-反射
  • apache的PropertyUtils 原理-反射
  • spring的BeanUtils 原理-反射
  • cglib的BeanCopier 原理-动态代理,性能很高,是反射的几十倍或数百倍

说明:反射的性能很差,有人做过这几种拷贝工具的性能测试,发现通过反射实现的功能性能很差,不建议在生产环境使用

BeanCopiers使用说明
注意事项

BeanCopier只有在属性名称和类型都相同的情况下才会进行copy。

工具类用例1(使用同步锁)
/**
 * BeanCopier工具类, 运用了享元模式进行实现
 *
 * @author icetea
 */
public class BeanCopierUtils {

    /**
     * BeanCopier缓存(享元模式)
     */
    private static Map<String, BeanCopier> beanCopierCacheMap = new HashMap<>();

    /**
     * 将source对象的属性拷贝到target对象中去
     *
     * @param source source对象
     * @param target target对象
     */
    public static void copyProperties(Object source, Object target) {
        String cacheKey = source.getClass().toString() + target.getClass().toString();
    
        BeanCopier beanCopier = null;
    
        // 为了线程安全使用双重锁机制
        if (!beanCopierCacheMap.containsKey(cacheKey)) {
            synchronized (BeanCopierUtils.class) {
                if (!beanCopierCacheMap.containsKey(cacheKey)) {
                    // 进入到这里会创建一个BeanCopier实例并且放在缓存map中
                    beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
                    beanCopierCacheMap.put(cacheKey, beanCopier);
                } else {
                    beanCopier = beanCopierCacheMap.get(cacheKey);
                }
            }
        } else {
            beanCopier = beanCopierCacheMap.get(cacheKey);
        }
    
        beanCopier.copy(source, target, null);
    }
}
工具类用例1(使用jdk8的concurrentHashMap)
/**
 * BeanCopier工具类, 运用了享元模式进行实现
 *
 * @author icetea
 */
public class BeanCopierUtils {

    /**
     * BeanCopier缓存(享元模式)
     */
    private static final Map<String, BeanCopier> BEAN_COPIER_MAP = new ConcurrentHashMap<>();

    /**
     * 将source对象的属性拷贝到target对象中去
     *
     * @param source source对象
     * @param target target对象
     */
    public static void copyProperties(Object source, Object target) {
        String cacheKey = source.getClass().toString() + target.getClass().toString();
        // 查看concurrentHashMap的实现方法介绍可以得知该方法为原子方法,保证了线程安全
        BeanCopier beanCopier = BEAN_COPIER_MAP.computeIfAbsent(cacheKey, k -> BeanCopier.create(source.getClass(), target.getClass(), false));
        beanCopier.copy(source, target, null);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值