当前位置:网站首页>Why is it not recommended to use BeanUtils in production?
Why is it not recommended to use BeanUtils in production?
2022-07-03 01:28:00 【Morning Xi light】
The main reason for not recommending is :
Some attribute copying tools have poor performance
Some attribute copying tools have “BUG” send
There are some hidden dangers when using attribute copying tools ( Later examples will talk about )
Example
First of all, the company has encountered commons Bag BeanUtils A real case of poor property copy performance , Then the colleague changed to Spring Of BeanUtils The performance is much better , If you are interested, you can use the performance test framework or benchmark framework to compare , There is no comparison here .
Now let's see Spring Of BeanUtils What are the problems with copying the properties of :
import lombok.Data;
import java.util.List;
@Data
public class A {
private String name;
private List<Integer> ids;
}
@Data
public class B {
private String name;
private List<String> ids;
}
import org.springframework.beans.BeanUtils;
import java.util.Arrays;
public class BeanUtilDemo {
public static void main(String[] args) {
A first = new A();
first.setName("demo");
first.setIds(Arrays.asList(1, 2, 3));
B second = new B();
BeanUtils.copyProperties(first, second);
for (String each : second.getIds()) {// Type conversion exception
System.out.println(each);
}
}
}
When you run the above example , A type conversion exception occurs .
At the break point, you can see , After the attribute is copied B Type of second In the object ids Still for Integer type :

If not converted to a string , Print directly , No errors are reported .
Use CGlib Not defined in Converter Similar problems will be encountered in the case of :
import org.easymock.cglib.beans.BeanCopier;
import java.util.Arrays;
public class BeanUtilDemo {
public static void main(String[] args) {
A first = new A();
first.setName("demo");
first.setIds(Arrays.asList(1, 2, 3));
B second = new B();
final BeanCopier beanCopier = BeanCopier.create(A.class, B.class, false);
beanCopier.copy(first,second,null);
for (String each : second.getIds()) {// Type conversion exception
System.out.println(each);
}
}
}
Again , The problem is exposed at runtime .
Let's take a look mapstruct:
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface Converter {
Converter INSTANCE = Mappers.getMapper(Converter.class);
B aToB(A car);
}
import java.util.Arrays;
public class BeanUtilDemo {
public static void main(String[] args) {
A first = new A();
first.setName("demo");
first.setIds(Arrays.asList(1, 2, 3));
B second = Converter.INSTANCE.aToB(first);
for (String each : second.getIds()) {// normal
System.out.println(each);
}
}
}
Can succeed in A in List<Integer> To B Medium List<String> type .
Let's look at the compiled Converter Implementation class :
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_202 (Oracle Corporation)"
)
@Component
public class ConverterImpl implements Converter {
@Override
public B aToB(A car) {
if ( car == null ) {
return null;
}
B b = new B();
b.setName( car.getName() );
b.setIds( integerListToStringList( car.getIds() ) );
return b;
}
protected List<String> integerListToStringList(List<Integer> list) {
if ( list == null ) {
return null;
}
List<String> list1 = new ArrayList<String>( list.size() );
for ( Integer integer : list ) {
list1.add( String.valueOf( integer ) );
}
return list1;
}
}
Automatically helped us with the conversion , We may not realize that the types are inconsistent .
If we were A Add one to the class String number attribute , stay B Add one to the class Long number attribute , Use mapstruect When number When it is set to non numeric type, it will report .NumberFormatException.
@Override
public B aToB(A car) {
if ( car == null ) {
return null;
}
B b = new B();
b.setName( car.getName() );
if ( car.getNumber() != null ) { // Here's the problem
b.setNumber( Long.parseLong( car.getNumber() ) );
}
b.setIds( integerListToStringList( car.getIds() ) );
return b;
}
Use cglib By default, there is no mapping number attribute ,B Medium number by null.
If you define the converter manually , Use IDEA plug-in unit ( Such as generateO2O) Automatic conversion :
public final class A2BConverter {
public static B from(A first) {
B b = new B();
b.setName(first.getName());
b.setIds(first.getIds());
return b;
}
}
This problem can be found very clearly in the coding phase :

Conclusion
because Java Generics are actually compile time checks , Post compilation generic erasure , Causes the runtime to List<Integer> and List<String> All are List type , It can be assigned normally . This leads to when using many attribute mapping tools , It is not easy to make obvious errors at compile time .
mapstruct Custom annotation processor , The generic types on both sides of the map can be read at compile time , Then map . But this mapping is also terrible , Sometimes we define the wrong type due to carelessness and other reasons , Automatically helped us with the conversion , It will bring a lot of side effects .
The performance of various attribute mapping tools has been briefly compared before , give the result as follows :

Therefore, use attribute conversion tools with caution , If possible, it is recommended to customize the conversion class , Use IDEA Plug in auto fill , Very efficient , A or B Any property type in does not match , Even delete an attribute , Errors can be reported at the compilation stage , And directly call get set The efficiency is also very high , I hope I can help you !
边栏推荐
- The difference between tail -f, tail -f and tail
- MySQL - database query - basic query
- 數學知識:臺階-Nim遊戲—博弈論
- Mathematical knowledge: Nim game game theory
- Swiftui component Encyclopedia: using scenekit and swiftui to build interactive 3D pie charts (tutorial with source code)
- Makefile中wildcard、patsubst、notdir的含义
- 按键精灵打怪学习-自动寻路回打怪点
- 给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。【剑指Offer】
- 【C语言】指针与数组笔试题详解
- leetcode:701. Insertion in binary search tree [BST insertion]
猜你喜欢

C application interface development foundation - form control (3) - file control

Give you an array numbers that may have duplicate element values. It was originally an array arranged in ascending order, and it was rotated once according to the above situation. Please return the sm
![[interview question] 1369 when can't I use arrow function?](/img/7f/84bba39965b4116f20b1cf8211f70a.png)
[interview question] 1369 when can't I use arrow function?

【C语言】指针与数组笔试题详解

MySQL

Database SQL language 02 connection query

C#应用程序界面开发基础——窗体控制(1)——Form窗体

Work experience of a hard pressed programmer

MySQL foundation 05 DML language

Draw love with go+ to express love to her beloved
随机推荐
leetcode:701. Insertion in binary search tree [BST insertion]
[day 29] given an integer, please find its factor number
Using tensorboard to visualize the model, data and training process
What operations need attention in the spot gold investment market?
1696C. Fishingprince plays with array [thinking questions + intermediate state + optimized storage]
The difference between tail -f, tail -f and tail
Excel if formula determines whether the two columns are the same
机器学习术语
对非ts/js文件模块进行类型扩充
Key wizard hit strange learning - automatic path finding back to hit strange points
基本远程连接工具Xshell
2022 coal mine gas drainage examination question bank and coal mine gas drainage examination questions and analysis
Thinkphp+redis realizes simple lottery
【系统分析师之路】第五章 复盘软件工程(开发模型开发方法)
Androd Gradle 对其使用模块依赖的替换
[principles of multithreading and high concurrency: 2. Solutions to cache consistency]
Machine learning terminology
Mathematical Knowledge: Steps - Nim Games - Game Theory
leetcode 6103 — 从树中删除边的最小分数
Key wizard play strange learning - front desk and Intranet send background verification code