Performance Comparison and Source Analysis of Java Bean Copy Utilities
This article analyzes the performance and implementation differences of various Java object‑copy utilities—including Apache BeanUtils, PropertyUtils, Spring BeanCopier, and Spring BeanUtils—by examining source code, benchmarking copy operations, and recommending alternatives to avoid the inefficiencies of Apache BeanUtils.
The author introduces the common problem of object-to-object assignment in Java projects, especially under high‑traffic scenarios such as flash sales, and asks how to write efficient copy code.
Manual copying with repetitive get/set calls leads to excessive code, error‑prone assignments, large classes, violation of coding standards, and maintenance difficulties.
Although Apache BeanUtils can perform property copying, the author demonstrates a simple hand‑written example and points out that using BeanUtils may trigger serious warnings.
By inspecting the source of copyProperties in Apache BeanUtils, the performance bottlenecks become clear: each copy performs type checking and logs a debug message, which significantly slows down execution.
public static void copyProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException {
BeanUtilsBean.getInstance().copyProperties(dest, orig);
}Further detailed source code shows multiple type checks, logging, and reflection calls that contribute to the overhead.
A benchmark was conducted using jvisualvm.exe to measure the execution time of four popular utilities under different copy counts. The results are summarized in the table below:
Method
1000
10000
100000
1000000
apache BeanUtils
906 ms
807 ms
1892 ms
11049 ms
apache PropertyUtils
17 ms
96 ms
648 ms
5896 ms
spring cglib BeanCopier
0 ms
1 ms
3 ms
10 ms
spring copyProperties
87 ms
90 ms
123 ms
482 ms
The benchmark shows that Spring's cglib BeanCopier is the fastest, while Apache BeanUtils is the slowest.
Analyzing Apache PropertyUtils source reveals three key optimizations: replacing type checks with simple null checks, removing per‑copy logging, and performing the actual assignment via DynaBean and setSimpleProperty instead of the more expensive copyProperty method.
public void copyProperties(Object dest, Object orig) {
// null checks
if (dest == null) { throw new IllegalArgumentException("No destination bean specified"); }
if (orig == null) { throw new IllegalArgumentException("No origin bean specified"); }
// simplified property copy without logging
// ... (code omitted for brevity)
}Spring's copyProperties implementation also improves performance by using assertions for null checks, eliminating logging, skipping the DynaBean type check, and explicitly setting method accessibility when needed.
private static void copyProperties(Object source, Object target, @Nullable Class
editable, @Nullable String... ignoreProperties) {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
// property descriptor handling without logging
// ... (code omitted for brevity)
}In conclusion, the article recommends avoiding Apache BeanUtils for object copying due to its heavy type checking and logging overhead, and suggests using faster alternatives such as Spring's BeanCopier or PropertyUtils.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.