Java浅拷贝BeanUtils.copyProperties引发的RPC异常

💡 原文中文,约1600字,阅读约需4分钟。
📝

内容提要

在敏捷团队建设中,通过Suite执行器实现了一键自动化单元测试。排查过程中发现传参的报文格式有问题,经过排查和代码分析,发现是BeanUtils.copyProperties导致的。解决方案是手动赋值。后续反思是要谨慎使用BeanUtils.copyProperties。

🔎

延伸解读

浅拷贝为何引发RPC反序列化异常

BeanUtils.copyProperties 属于浅拷贝,只复制属性的引用而非创建新对象。当源对象与目标对象类型不一致时,目标对象中某些属性可能仍指向源对象的引用。在 RPC 调用中,序列化框架(如 JSF)反序列化时若找不到对应的类,就会将对象转换为 Map,导致接收方出现 ClassCastException。

排查思路:从报文到代码的逐层验证

作者先怀疑传参报文格式,通过模拟报文和本地 debug 验证调用成功;再排查序列化方式和代码改动,均未发现问题;最后通过单元测试确认服务端收到的报文格式正常,才转向代码审查,发现 BeanUtils.copyProperties 的可疑调用。这种从外到内、逐步排除的排查方法值得借鉴。

解决方案与替代工具

定位到浅拷贝问题后,作者去掉 BeanUtils.copyProperties,改为手动赋值,最终解决了异常。后续反思提出,如果对象转换场景较多,建议使用 MapStruct 这类更安全的映射工具,并强调要谨慎使用 BeanUtils.copyProperties,避免因浅拷贝引发隐蔽的序列化问题。

❓

Q&A

BeanUtils.copyProperties引发的异常是什么?

引发的异常是java.lang.ClassCastException,表示无法将HashMap转换为BatchInfo。

如何解决BeanUtils.copyProperties导致的问题?

解决方案是去掉BeanUtils.copyProperties,改为手动赋值。

在敏捷团队中如何实现自动化单元测试?

通过Suite执行器实现了一键自动化单元测试。

为什么要谨慎使用BeanUtils.copyProperties?

因为它属于浅拷贝,只调用子对象的set方法,可能导致反序列化时找不到对应的类。

如果需要频繁转换对象,应该使用什么工具?

建议使用MapStruct进行对象转换。

在排查过程中发现了什么问题?

发现传参的报文格式有问题,最终定位到BeanUtils.copyProperties的使用。

🏷️

标签

➡️

继续阅读