Bean 复制的几种框架比较

4 种复制方法:

  • Apache BeanUtils
  • Apache PropertyUtils
  • Spring BeanUtils
  • Cglib BeanCopier

测试 Bean,FromBean 与 ToBean 属性一致

public class FromBean {
    private String name;
    private int age;
    private double money;
 
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
复制代码

测试方法

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.cglib.beans.BeanCopier;

public class Test {

	public static void main(String[] args) {
		FromBean fb = new FromBean();
		fb.setAge(20);
		fb.setMoney(30000.111);
		fb.setName("测试");

		int count = 10;

		convert((tb) -> BeanUtils.copyProperties(tb, fb), count, "Apache BeanUtils.copyProperties");

		convert((tb) -> PropertyUtils.copyProperties(tb, fb), count, "Apache PropertyUtils.copyProperties");

		convert((tb) -> org.springframework.beans.BeanUtils.copyProperties(fb, tb), count, "Spring BeanUtils.copyProperties");

		BeanCopier bc = BeanCopier.create(FromBean.class, ToBean.class, false);

		convert((tb) -> bc.copy(fb, tb, null), count, "Cglib BeanCopier.copy");

	}

	public static void convert(ConvertBean cb, int count, String type) {
		try {
			System.out.println(type + "开始进行测试");
			long start = System.currentTimeMillis();
			for (int i = 0; i < count; i++) {
				ToBean tobean = new ToBean();
				cb.convertMethod(tobean);
				System.out.println(tobean.getAge());
				System.out.println(tobean.getMoney());
				System.out.println(tobean.getName());
			}
			System.out.println("耗时 " + (System.currentTimeMillis() - start) + " ms");
			System.out.println("----------------------");
		} catch (Exception e) {
			System.out.println("Exception: " + e.getMessage());
			e.printStackTrace();
		}
	}
}

@FunctionalInterface
interface ConvertBean {

	void convertMethod(ToBean tb) throws Exception;
}
复制代码

打印结果

Apache BeanUtils.copyProperties开始进行测试
耗时 1178 ms
----------------------
Apache PropertyUtils.copyProperties开始进行测试
耗时 5 ms
----------------------
Spring BeanUtils.copyProperties开始进行测试
耗时 172 ms
----------------------
Cglib BeanCopier.copy开始进行测试
耗时 0 ms
----------------------
复制代码

测试结果

单位:ms

count:10

次数:10 第一次 第二次 第三次 第四次 平均值 单次平均值
Apache BeanUtils 1178 1029 917 1019 1035.75 103.575
Apache PropertyUtils 5 4 8 4 5.25 0.525
Spring BeanUtils 172 257 123 135 171.75 17.175
Cglib BeanCopier 0 0 0 0 0 0

count:100

次数:100 第一次 第二次 第三次 第四次 平均值 单次平均值
Apache BeanUtils 1868 1258 1624 1260 1502.5 15.025
Apache PropertyUtils 16 10 18 17 15.25 0.1525
Spring BeanUtils 193 152 209 215 192.25 1.9225
Cglib BeanCopier 0 0 0 0 0 0

count:10000

次数:10000 第一次 第二次 第三次 第四次 平均值 单次平均值
Apache BeanUtils 1611 1657 1786 1572 1656.5 0.16565
Apache PropertyUtils 243 64 194 111 153 0.0153
Spring BeanUtils 551 217 433 431 408 0.0408
Cglib BeanCopier 10 6 3 7 6.5 0.00065

结论

  • 数量越大平均每次耗时越少
  • 综合 Cglib BeanCopier 性能最好,但在使用前,要先用 BeanCopier.create 定义

Cglib在测试的时候,先进行了实例的缓存,这个也是他性能较好的原因

你可能感兴趣的:(java)