当前位置:网站首页>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 !
边栏推荐
- Force buckle 204 Count prime
- Canvas drawing -- bingdd
- 2022 Jiangxi Provincial Safety Officer B certificate reexamination examination and Jiangxi Provincial Safety Officer B certificate simulation examination question bank
- Why can't the start method be called repeatedly? But the run method can?
- Leetcode 6103 - minimum fraction to delete an edge from the tree
- Type expansion of non ts/js file modules
- Mathematical knowledge: step Nim game game game theory
- 【C语言】指针与数组笔试题详解
- [自我管理]时间、精力与习惯管理
- Meituan dynamic thread pool practice ideas, open source
猜你喜欢

Meituan dynamic thread pool practice ideas, open source

【C语言】指针与数组笔试题详解
![[Androd] Gradle 使用技巧之模块依赖替换](/img/5f/968db696932f155a8c4a45f67135ac.png)
[Androd] Gradle 使用技巧之模块依赖替换

C application interface development foundation - form control (3) - file control
![[机缘参悟-36]:鬼谷子-飞箝篇 - 面对捧杀与诱饵的防范之道](/img/c6/9aee30cb935b203c7c62b12c822085.jpg)
[机缘参悟-36]:鬼谷子-飞箝篇 - 面对捧杀与诱饵的防范之道

给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。【剑指Offer】

【QT】自定义控件的封装

Arduino dy-sv17f automatic voice broadcast

Machine learning terminology
![[principles of multithreading and high concurrency: 2. Solutions to cache consistency]](/img/ce/5c41550ed649ee7cada17b0160f739.jpg)
[principles of multithreading and high concurrency: 2. Solutions to cache consistency]
随机推荐
MySQL foundation 06 DDL
软考信息系统项目管理师_历年真题_2019下半年错题集_上午综合知识题---软考高级之信息系统项目管理师053
Key wizard play strange learning - front desk and Intranet send background verification code
MySQL
leetcode刷题_两数之和 II - 输入有序数组
How is the mask effect achieved in the LPL ban/pick selection stage?
按鍵精靈打怪學習-多線程後臺坐標識別
Mathematical Knowledge: Steps - Nim Games - Game Theory
Force buckle 204 Count prime
Find a benchmark comrade in arms | a million level real-time data platform, which can be used for free for life
Asynchronous, email and scheduled tasks
[interview question] 1369 when can't I use arrow function?
The meaning of wildcard, patsubst and notdir in makefile
[Cao gongzatan] after working in goose factory for a year in 2021, some of my insights
Androd gradle's substitution of its use module dependency
Button wizard play strange learning - automatic return to the city route judgment
Esp32 simple speed message test of ros2 (limit frequency)
[FPGA tutorial case 6] design and implementation of dual port RAM based on vivado core
【FH-GFSK】FH-GFSK信号分析与盲解调研究
按键精灵打怪学习-前台和内网发送后台验证码