如何在spring.xml中用反射替代Getter/Setter实现属性填充?
基于Spring反射实现无业务逻辑Populator的配置方案
你提到的这种方案核心是通过通用反射工具类+Spring配置替代手写的属性复制代码,完全不需要为每个对象对单独编写Populator类,以下是具体实现步骤:
1. 编写通用反射Populator类
这个类利用Spring的BeanUtils(或自定义反射逻辑)实现属性复制,并支持通过Spring配置指定需要复制的属性:
import org.springframework.beans.BeanUtils; import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; public class ReflectivePopulator<SOURCE, TARGET> { private Set<String> includedProperties; public void populate(SOURCE source, TARGET target) { if (includedProperties == null || includedProperties.isEmpty()) { // 复制所有同名且类型兼容的属性 BeanUtils.copyProperties(source, target); } else { // 仅复制配置指定的属性 String[] excludedProps = Arrays.stream(source.getClass().getDeclaredFields()) .map(field -> field.getName()) .filter(fieldName -> !includedProperties.contains(fieldName)) .toArray(String[]::new); BeanUtils.copyProperties(source, target, excludedProps); } } // Spring注入需要复制的属性列表 public void setIncludedProperties(Set<String> includedProperties) { this.includedProperties = includedProperties; } }
2. 在spring.xml中配置专属的Populator实例
针对PaymentModeModel到PaymentModeData的属性复制,直接在配置文件中指定需要复制的属性即可,无需手写专属Populator类:
<!-- 配置PaymentMode对应的反射Populator --> <bean id="paymentModePopulator" class="com.yourcompany.utils.ReflectivePopulator"> <!-- 指定需要复制的属性名 --> <property name="includedProperties"> <set> <value>code</value> <value>name</value> <value>description</value> </set> </property> </bean>
3. 业务代码中使用配置好的Populator
在需要进行属性复制的地方,直接注入这个配置好的bean并调用方法:
// 注入配置好的populator @Autowired private ReflectivePopulator<PaymentModeModel, PaymentModeData> paymentModePopulator; // 使用示例 public PaymentModeData convertToData(PaymentModeModel model) { PaymentModeData target = new PaymentModeData(); paymentModePopulator.populate(model, target); return target; }
额外说明
- 如果不需要精准控制属性,只想复制所有同名兼容属性,可以去掉
includedProperties的配置,通用Populator会自动完成全量复制。 - 若需要忽略null值复制,可以扩展
ReflectivePopulator,在反射复制时判断属性值是否为null再决定是否复制。 - 这种方案的核心价值是消除重复的模板化populator代码,尤其适合无业务逻辑的属性映射场景。
内容的提问来源于stack exchange,提问作者Farrukh Chishti
相关产品推荐
相关产品推荐

