BeanUtils.copyProperties的两个坑

原创  郑建华   2020-07-14   64人阅读  0 条评论

在研究对象拷贝属性的时候,踩了坑,特此记录一下。

一、使用BeanUtils.copyProperties(A,B)的时候,特别需要注意

有两个包都存在该方法,并且两个方法的参数不一致

org.apache.commons.beanutils.BeanUtils包

BeanUtils.copyProperties(dest, orig);

是由orig对象拷贝到dest对象中,也就是从B拷贝到A


org.springframework.beans.BeanUtils包

BeanUtils.copyProperties(source, target);

是有source对象拷贝到target对象中,也就是从A拷贝到B

这是第一个坑,不过,稍微有点经验的都应该知道,重点是第二个坑。


二、使用org.apache.commons.beanutils.BeanUtils工具进行转换时,一直不能成功

如图:

image.png

类:image.png

由于第一次尝试的时候,是直接在一个JAVA类中编写的

工具方法和类全部写在同一个文件中,由于一个java源文件中只能有一个public的类

所以,其他类均未采用public修饰  此处为背景


跟踪源码

在调试过程中发现,getPropertyUtils().isReadable(orig,name)返回了false

image.png

断点进入,的确返回false

image.png

readMethod值来源于getReadMethod(bean.getClass(),desc)

image.png

进入方法,797行处执行,返回false 说明该class不包含public修饰

image.png

后续执行,返回null

image.png

返回null,运行到如下代码

image.png

进入方法,第一步中,直接return (null)

image.png

再次返回到上一个方法中,null!=null值是false

image.png


经过分析,怀疑是权限问题,将Class A前面加上public修饰后,再次调试

image.png

方法内容,返回true

image.png

断点调试,进入其中,此时Modifier.isPublic返回true了

image.png

进入if内部,此时method不为空了

image.png

所以,成功进入方法内部,成功调用拷贝方法

image.png

最终,拷贝成功

image.png



一般来说,创建的Class肯定会使用public修饰,但是全部写在同一个文件中时,且使用的apache的工具包时,就会出现这种拷贝不成功的情况。


使用springframework的工具包时,及时类名未添加public修饰,也能拷贝成功

image.png

其中两个if都未进入,Modifier返回的结果是true,!true即是false

image.png

均为影响invoke方法执行,采用反射方式拷贝属性值


结论:

apache工具的底层源码,会判断class的访问权限

springframework工具的底层源码,直接使用反射,访问权限不影响


如果要使用BeanUtilsBean.copyProperties方法,要么使用springframework包的,要么Class使用public修饰。



本文地址:https://www.zjh336.cn/?id=1900
版权声明:本文为原创文章,版权归 郑建华 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?