BeanUtils 初探

本文详细介绍了Apache Commons BeanUtils组件的功能及使用方法,包括属性复制(copyProperties)、填充(populate)、克隆(cloneBean)等核心方法,并探讨了其背后的内省机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实习的时候碰上有人用BeanUtils,感觉很方便,省了很多胶水代码的工作,但是自己当时用的时候,发现它还是有一些问题,但是没有仔细琢磨,现在有时间了,琢磨一下.

Apache common.BeanUtils 作用

BeanUtils提供了一些方法,用来从一个简单的Java对象(JavaBean)中,提出属性,或者实现给其他JavaBean拷贝属性.
这样,就可以省略此前容易出错的各种通过setter的方式DO转DTO等的工具方法.

原理

JDK提供了内省的机制,对JavaBean类型的类做了额外的工具来获取,设置,遍历属性.内省机制是通过私有属性的公开getter/setter方法来实现的,所以,BeanUtils能操作的属性,必须有公开的getter/setter方法,否则,BeanUtils默认这个JavaBean没有对应属性.
内省机制的基础,自然是Java的反射机制.

参考

深入理解JavaBean(1):JavaBean的内省与BeanUtils库

方法介绍

copyProperties(Object dest,Object orig)

这个方法是用的最多的了吧,功能就是把源(orig)JavaBean的各种属性,拷贝给目标(dest)JavaBean.

需要注意的是:

  1. 源和目标的属性名应当完全一样
  2. 这个方法可以一定限度内将相同属性名,但是类型不同的属性做一个转化,如果确定没有这种需求的话,可以使用PropertyUtilscopyProperties方法,PropertyUtils更快一点.
  3. 属性不是数组或者Mapl类型,并且没有getter,setter方法的,这个方法不能拷贝
  4. 这个方法和另一个方法populate(Object dest,Map properties)类似,不同点是populate专用来处理需要被拷贝的属性存放在map中的情况,而copyProperties无此限制.
  5. 对于java.util.Date类型的属性,如果源JavaBean为null,那么使用该方法会抛异常,可以通过自定义类继承BeanUtils,内容如下,来避免这个问题
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;

public class BeanUtilsEx extends BeanUtils {
    static{
        //这里,如果源为null,这里的设置目标的默认值为null,自然,也可以设置为其他
        ConvertUtils.register(new DateConverter(null),Date.class);
    }

    //覆盖父类方法
    public static void copyProperties(Object dest,Object orig){
        try {
            BeanUtils.copyProperties(dest,orig);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

}

参考

  1. BeanUtils.copyProperties属性拷贝日期为空异常
  2. copyProperties文档

populate方法

功能与上面提到的copyProperties类似,只是入参的源是Map

cloneBean(Object bean)

用于利用入参的JavaBean,生成一个一样的JavaBean,返回值是Object,需要显式转换

需要注意的是:

  1. 不需要源Bean实现Clonable
  2. 拷贝是浅拷贝,属性共用同一个对象

describe(Object bean)

从源Bean中,用属性名和属性的值,填充一个Map,返回

需要注意的是:

  1. 返回的Map不是泛型的,但是key和value都是String类型,value不是String 类型的会被BeanUtils内的Convert转换成String

参考

  1. BeanUtils.describe与PropertyUtils.describe区别

getMappedProperty(Object bean,String name,String key) 与 getMappedProperty(Object bean,String name)

从源Java中提取指定Map类型,属性名为入参name的属性,返回值转换成String.
由于是Map类型,所以进一步的属性值,需要通过Map的key来指定,所以有了第三个参数String key,对于使用getMappedProperty(Object bean,String name)的形式,key需要拼接到参数name中,类似与"mapParam(key)"

使用示例

public class Pojo{
    private Map<String,String> param;

    public Map<String,String> getParam(){return param;}

    public void setParam(Map<String,String> param){this.param=param;}
}
public class BeanUtilsTest{

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException{
        Map<String String> map=new HashMap<>();
        map.put("test1","1");
        map.put("test2","2");

        Pojo pojo=new Pojo();
        BeanUtils.copyProperty(pojo,"param",map);

        System.out.println(BeanUtils.getMappedProperty(pojo,"param(test1)"));
        System.out.println(BeanUtils.getMappedProperty(pojo,"param","test2"));

    }
}

getIndexedProperty(Object bean,String name,int index) 与 getIndexedProperty(Object bean,String name)

getMappedProperty(Object bean,String name,String key)getMappedProperty(Object bean,String name)类似,不过这次源Bean内的属性是数组,此外,name的形式也有不同,从Mapped的那种map(key),要改成array[index]的形式.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值