Spring BeanUtils.copyProperties与Apache Commons BeanUtils.copyProperties对比及属性忽略问题
解决Bean属性复制时忽略指定字段的问题
我之前也碰到过这个困扰——Apache Commons BeanUtils的copyProperties确实好用,但没法直接跳过那些不需要的元数据字段。下面给你几个实用的解决方案:
方案1:基于Apache Commons工具类封装自定义方法
既然原生方法不支持忽略,我们可以自己封装一个,利用PropertyUtils获取属性列表,过滤掉要忽略的字段后逐个复制:
import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.PropertyUtils; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class CustomBeanUtils { public static void copyPropertiesIgnoreSpecific(Object target, Object source, String... ignoreProperties) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { // 把要忽略的字段存入Set方便快速判断 Set<String> ignoreSet = new HashSet<>(Arrays.asList(ignoreProperties)); // 获取源对象的所有属性名 String[] propertyNames = PropertyUtils.getPropertyNames(source); for (String propertyName : propertyNames) { if (!ignoreSet.contains(propertyName)) { // 仅复制不在忽略列表中的属性 Object value = PropertyUtils.getProperty(source, propertyName); BeanUtils.setProperty(target, propertyName, value); } } } }
使用示例:
// 忽略created和lastUpdated两个元数据字段 CustomBeanUtils.copyPropertiesIgnoreSpecific(targetBean, sourceEntity, "created", "lastUpdated");
方案2:改用Spring的BeanUtils工具类
如果你的项目已经引入了Spring框架,直接用Spring自带的org.springframework.beans.BeanUtils.copyProperties就省心多了,它原生支持忽略指定属性:
import org.springframework.beans.BeanUtils; // 参数顺序:源对象、目标对象、要忽略的字段列表 BeanUtils.copyProperties(sourceEntity, targetBean, "created", "lastUpdated");
这个方法内部已经处理了属性过滤逻辑,代码简洁,而且Spring的BeanUtils在类型转换上做了不少优化,实用性拉满。
方案3:Map中转(适合简单场景)
如果属性数量不多,也可以先把源对象转成Map,移除不需要的字段后再复制到目标对象:
import org.apache.commons.beanutils.BeanUtils; import java.util.Map; // 将源对象转为Map Map<String, Object> sourceMap = BeanUtils.describe(sourceEntity); // 移除要忽略的字段 sourceMap.remove("created"); sourceMap.remove("lastUpdated"); // 注意:BeanUtils.describe会自动加入class属性,若目标对象无此字段需额外移除 sourceMap.remove("class"); // 将Map属性批量复制到目标对象 BeanUtils.populate(targetBean, sourceMap);
这几个方案里,我个人最推荐Spring的BeanUtils方案,除非项目无法引入Spring依赖,那自定义封装的方法也完全够用。
内容的提问来源于stack exchange,提问作者user898465
相关产品推荐
相关产品推荐

