首页 > 其他分享 >浅析BeanUtils中copyProperties原理

浅析BeanUtils中copyProperties原理

时间:2022-12-14 16:34:47浏览次数:43  
标签:target bean source copyProperties null BeanUtils 浅析 属性

摘要

本文浅析BeanUtils中copyProperties的原理。简述大致实现流程

源码浅析

org.springframework.beans.BeanUtils

/**
 * 将给定源bean的属性值赋值到目标bean中。
 * 注意:只要属性匹配,源类和目标类就不必相互匹配(match),甚至不必相互派生(derived from each other)。 源bean暴露但目标bean没有暴露的属性,会被自动忽略。
 * 这只是一种方便的方法。 对于更复杂的转换需求,请考虑使用完整的BeanWrapper。
* @param source 源bean
* @param target the target bean目标bean
* @throws BeansException,如果拷贝失败
* @see BeanWrapper
*/
public static void copyProperties(Object source, Object target) throws BeansException {
    copyProperties(source, target, null, (String[]) null);
}

private static void copyProperties(Object source, Object target, @Nullable Class<?> editable,
        @Nullable String... ignoreProperties) throws BeansException {

    Assert.notNull(source, "Source must not be null");
    Assert.notNull(target, "Target must not be null");

    Class<?> actualEditable = target.getClass();
    if (editable != null) {
        if (!editable.isInstance(target)) {
            throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
                    "] not assignable to Editable class [" + editable.getName() + "]");
        }
        actualEditable = editable;
    }

    // 获取target对象的PropertyDescriptor属性数组targetPds
    PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
    List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);

  // 遍历target对象属性
    for (PropertyDescriptor targetPd : targetPds) {
        // 获取其setter方法
        Method writeMethod = targetPd.getWriteMethod();
        if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
            // 获取source对象与target对象targetPd属性同名的PropertyDescriptor对象sourcePd
            PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
            if (sourcePd != null) {
                // 获取source对应属性的getter方法
                Method readMethod = sourcePd.getReadMethod();
                if (readMethod != null &&
                        // 判断是否可赋值,如上述例子:desk是DeskVO、DeskDO,返回false;而chairs都是List<?>,返回true
                        ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                    try {
                        if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                            readMethod.setAccessible(true);
                        }
                        // 通过反射获取source对象属性的值
                        Object value = readMethod.invoke(source);
                        if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                            writeMethod.setAccessible(true);
                        }
                        // 通过反射给target对象属性赋值
                        writeMethod.invoke(target, value);
                    }
                    catch (Throwable ex) {
                        throw new FatalBeanException(
                                "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
                    }
                }
            }
        }
    }
}

小结

执行过程比较简单,使用jdk提供的内省的方式属性描述类PropertyDescriptor。但是底层对象取值、赋值还是用的反射。

copyProperties是浅拷贝还是深拷贝

毫无疑问是浅拷贝

标签:target,bean,source,copyProperties,null,BeanUtils,浅析,属性
From: https://www.cnblogs.com/simplejavahome/p/16982493.html

相关文章

  • JAVA Socket超时浅析
    转自:https://developer.aliyun.com/article/270260套接字或插座(socket)是一种软件形式的抽象,用于表达两台机器间一个连接的“终端”。针对一个特定的连接,每台机器上都有......
  • java中OOM错误浅析(没有深入太多,一些粗浅的知识,可以温习用)
    嗯,生活加油鸭。。。。实习中遇到OOM错误GCoverheadlimitexceeded  问题,所以整理一下OOM异常问题:不对的地方请小伙伴留言^_^“阿里的开发手册”对OOM的描述:OOM,全称“......
  • 浅析35kV变电站综合自动化系统的结构和功能设计
    罗轩志安科瑞电气股份有限公司上海嘉定201801 摘要:变电站综合自动化系统是一个分层分布式自动控制系统,整个系统由主控层、通信层和现地单元层三层构成。本文以35kV电站......
  • 浅析智能消防应急照明和疏散指示系统在工业建筑项目上的应用
    罗轩志安科瑞电气股份有限公司上海嘉定201801  摘要:随着我国社会经济的迅猛发展与城市化建设进程的加快,大型城市综合体建筑越来越多,随之而来的消防安全管理问题不容忽视......
  • 小程序开发入门及多端开发浅析
    前言现在小程序虽然不是最火的时间段,但是小程序“触手可及,用完即走”的理念对于未知开发者保持一定的神秘和吸引力,应后端同学对小程序开发的热情,笔者在疫情期间也开发上线了......
  • 《“透视”个人大数据》项目开发小记 --(三)Android APP 开发(3)使用jni调用c++/c 应用实
       目前应用AndroidStudio可以很方便的构建完成通过JNI调用c++/c的基本架构(CMakeLists,JNI调用C部分,java连接JNI部分)。希望通过APP开发中应用实例的简要介绍,可......
  • 浅析公共娱乐场所电气火灾成因和对策
    罗轩志安科瑞电气股份有限公司上海嘉定201801  摘要:针对我国公共娱乐场所存在的电气火灾隐患多、危险性大,事故所占比例大等情况,分析公共娱乐场所发生电气火灾的各种原因......
  • 源码浅析--整体架构
    最近一直在研读jQuery源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美。其结构明晰,高内聚、低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼......
  • BCache浅析
    Bcache的wiki和git仓地址如下:http://bcache.evilpiepirate.orghttp://evilpiepirate.org/git/linux-bcache.githttp://evilpiepirate.org/git/bcache-tools.git1.作用......
  • 浅析故障电弧探测器在电气防火中的作用与应用介绍
    【摘要】: 分析了重大电气火灾数据。结合目前国内前沿的电气火灾探测技术,重点介绍了故障电弧式电气火灾监控探测器在火灾预警系统中的重要作用,给出了基于多种探测技术的电气......