Java BeanUtils 类作用、语法与示例详解
目录
- 一、BeanUtils 的核心作用
- 二、Apache Commons BeanUtils
- 核心方法
- 三、Spring BeanUtils
- 核心方法(更简洁高效)
- 四、最佳实践与注意事项
- 1. 选择指南
- 2. 性能对比
- 3. 常见问题解决
- 五、实际应用场景
- 场景1:DTO/VO 转换
- 场景2:表单对象绑定
- 场景3:动态配置注入
- 场景4:对象合并
- 总结:BeanUtils 作用
一、BeanUtils 的核心作用
BeanUtils 是 Apache Commons 和 Spring Framework 提供的工具类,主要用于简化 JavaBean 的操作。核心功能包括:
- 属性拷贝:对象间同名属性自动复制
- 动态访问:通过字符串名称操作属性
- 类型转换:自动处理不同类型间的转换
- 嵌套访问:支持
address.city
格式的链式访问
JavaBean 定义:符合规范的 POJO 类
- 有无参构造函数
- 属性私有化
- 提供 getter/setter 方法
二、Apache Commons BeanUtils
核心方法
方法 | 作用 | 示例 |
---|---|---|
copyProperties(dest, orig) | 复制同名属性 | BeanUtils.copyProperties(userDTO, user); |
getProperty(bean, name) | 获取属性值 | String name = BeanUtils.getProperty(user, "name"); |
setProperty(bean, name, value) | 设置属性值 | BeanUtils.setProperty(user, "age", "30"); |
describe(bean) | 对象转 Map | Map<String, String> map = BeanUtils.describe(use编程客栈r); |
populate(bean, properties) | Map 转对象 | BeanUtils.populate(user, map); |
使用示例
// 添加依赖 // <dependency> // <groupId>commons-beanutils</groupId> // <artifactId>commons-beanutils</artifactId> // <version>1.9.4</version> // </dependency> import org.apachehttp://www.devze.com.commons.beanutils.BeanUtils; public class CommonsExample { public static void main(String[] args) throws Exception { // 1. 创建源对象 User source = new User("Alice", 25, new Address("New York")); // 2. 创建目标对象 UserDTO target = new UserDTO(); // 3. 属http://www.devze.com性拷贝(同名属性自动复制) BeanUtils.copyProperties(target, source); System.out.println(target); // 输出: UserDTO{name='Alice', age=25, city='New York'} // 4. 动态获取属性 String city = BeanUtils.getProperty(source, "address.city"); System.out.println(city); // 输出: New York // 5. 动态设置属性 BeanUtils.setProperty(target, "age", "30"); // 字符串自动转int // 6. 对象转Map Map<String, String> mapjavascript = BeanUtils.describe(source); System.out.println(map); // {name=Alice, age=25, address=Address[city=New York]} // 7. Map转对象 Map<String, Object> data = new HashMap<>(); data.put("name", "Bob"); data.put("age", "35"); // 字符串自动转换 data.put("address.city", "London"); // 嵌套属性 User newUser = new User(); BeanUtils.populate(newUser, data); System.out.println(newUser.getAddress().getCity()); // 输出: London } } // JavaBean 类 class User { private String name; private int age; private Address address; // 无参构造器、getter/setter 省略 } class UserDTO { private String name; private int age; private String city; // 对应 address.city // 无参构造器、getter/setter 省略 } class Address { private String city; // 构造器、getter/setter 省略 }
三、Spring BeanUtils
核心方法(更简洁高效)
方法 | 作用 | 特点 |
---|---|---|
copyProperties(source, target) | 属性复制 | 无类型转换,性能更好 |
copyProperties(source, target, ignoreProperties) | 带忽略属性的复制 | 跳过指定属性 |
使用示例
// 添加依赖 // <dependency> // <groupId>org.springframework</groupId> // <artifactId>spring-beans</artifactId> // <version>5.3.2编程0</version> // </dependency> import org.springframework.beans.BeanUtils; public class SpringExample { public static void main(String[] args) { User source = new User("Alice", 25, new Address("New York")); UserDTO target = new UserDTO(); // 1. 基础属性复制 BeanUtils.copyProperties(source, target); System.out.println(target.getCity()); // 输出: null (不自动处理嵌套) // 2. 带忽略属性的复制 BeanUtils.copyProperties(source, target, "age"); // 忽略age属性 System.out.println(target.getAge()); // 输出: 0 (默认值) // 3. 自定义属性处理器 class CustomConverter implements Converter { public Object convert(Class type, Object value) { if(value instanceof User) { return ((User) value).getAddress().getCity(); } return null; } } // 4. 处理嵌套属性(需自定义) String city = (String) new CustomConverter().convert(String.class, source); target.setCity(city); System.out.println(target.getCity()); // 输出: New York } }
四、最佳实践与注意事项
1. 选择指南
场景 | 推荐工具 |
---|---|
需要类型转换 | Apache BeanUtils |
高性能场景 | Spring BeanUtils |
嵌套属性访问 | Apache BeanUtils |
简单属性复制 | Spring BeanUtils |
2. 性能对比
3. 常见问题解决
问题1:嵌套属性复制失败
// Apache 解决方案 BeanUtils.setProperty(target, "address.city", "Paris"); // Spring 解决方案(需自定义) class AddressMapper { public static void map(User source, UserDTO target) { target.setCity(source.getAddress().getCity()); } }
问题2:类型转换错误
// 注册自定义转换器 ConvertUtils.register(new Converter() { public Object convert(Class type, Object value) { return LocalDate.parse(value.toString()); } }, LocalDate.class); // 现在可以处理字符串转LocalDate BeanUtils.setProperty(target, "birthDate", "2023-01-01");
问题3:忽略特定属性
// Spring 方式 BeanUtils.copyProperties(source, target, "password", "sensitiveData"); // Apache 方式(需额外处理) Map<String, String> map = BeanUtils.describe(source); map.remove("password"); BeanUtils.populate(target, map);
五、实际应用场景
场景1:DTO/VO 转换
// Controller层 public UserDTO getUser(Long id) { User user = userService.findById(id); UserDTO dto = new UserDTO(); BeanUtils.copyProperties(user, dto); return dto; }
场景2:表单对象绑定
// 接收表单提交 public String createUser(@ModelAttribute UserForm form) { User user = new User(); BeanUtils.copyProperties(form, user); userService.save(user); return "redirect:/users"; }
场景3:动态配置注入
// 从配置文件中读取设置 @Value("${app.settings}") private Map<String, String> settings; public void applySettings() { AppConfig config = new AppConfig(); BeanUtils.populate(config, settings); }
场景4:对象合并
public User mergeUserChanges(User original, User changes) { User merged = new User(); BeanUtils.copyProperties(original, merged); // 复制原始数据 BeanUtils.copyProperties(changes, merged); // 覆盖变更数据 return merged; }
总结:BeanUtils 作用
- 消除样板代码:减少 getter/setter 调用
- 提升开发效率:简化对象操作
- 增强灵活性:支持动态属性访问
- 降低耦合度:解耦对象操作逻辑
精彩评论