Among the 12 vo2dto methods, the pressure measurement data of BeanUtil.copyProperties are the most stretched!

Posted by rotwyla98 on Tue, 09 Nov 2021 09:34:37 +0100

Continue to adhere to the original output, click the blue word to pay attention to me

Author: Xiao Fu Ge
Blog: https://bugstack.cn

‚ĚĚ

Precipitate, share and grow, so that you and others can gain something! ūüėú

‚Ěě

catalogue


  • 1, Foreword

  • 2, Performance test comparison

  • 3, 12 conversion cases

    • 1. get\set

    • 2. json2Json

    • 3. Apache copyProperties

    • 4. Spring copyProperties

    • 5. Bean Mapping

    • 6. Bean Mapping ASM

    • 7. BeanCopier

    • 8. Orika

    • 9. Dozer

    • 10. ModelMapper

    • 11. JMapper

    • 12. MapStruct

  • 4, Summary

  • 5, Series recommendation


1, Foreword

Why, your code is just usable?

How to write code without technical depth, lack of knowledge reserve and lack of experience accumulation? Baidu, if you encounter problems, search a little and check a piece. No matter what principle it is or what kind of scene it is suitable for, paste it into your own project first. Look, if you can run, you can run. Such code is only delivered to the extent of availability, and there is no certain quality assurance at all, not to mention the data structure, algorithm logic and design mode. The LeetCode brushed in the programming materials is all over.

When you feel that you can't use after reading a lot of materials, you will say what you really want to say. You have learned this. But in fact, I don't feel that the in-depth excavation of technology and the combing of a full set of knowledge system, a little work and a little harvest are rolling. Instead, it's as easy to watch technical videos as watching movies. Without writing cases, you think the book will be cool. It's meaningless to lack mental thinking. Mechanical physical repetition is volume, or even very volume.

It's like asking you to use an attribute copying tool to convert vo into dto. What do you use, Apache or Spring, or something else? Which is the most efficient? Next, let's verify it with data and provide the use comparison of various cases

2, Performance test comparison

In the process of Java system engineering development, there will be object conversion between various layers, such as   VO, DTO, PO, VO, etc. if they are all manual get and set, it is too time-consuming and may operate incorrectly. Therefore, it is more convenient to choose an automatic tool.

At present, I have sorted out 12 kinds of object attribute conversion, including: ordinary getset, json2Json, Apache attribute copy, Spring attribute copy, bean mapping, bean mapping ASM, BeanCopier, Orika, Dozer, ModelMapper, JMapper and MapStruct. Next, we test these 11 kinds of attribute conversion operations 100 times, 1000 times, 10000 times and 100000 times respectively Performance time comparison at a million times.

  • BeanUtils.copyProperties is the most common tool class in your code, but as long as you don't use it wrong Under the Apache package, but provided by Spring, it will not have much impact on performance.
  • But if the performance is better, it can replace manual get, set, or MapStruct works better because it is generated at compile time get, set code, and we write get and set are the same.
  • Other component packages are mainly based on AOP, ASM, CGlib is implemented by the technical means of, so there will be corresponding performance loss.

3, 12 conversion cases

Source code: https://github.com/fuzhengwei/guide-vo2dto

Description: create the interfaces.assembly package under the case project, define the iassembler < source, target > #sourcetotarget (source var) interface, and provide different methods of object conversion operation class implementation. During the learning process, you can directly download, run and debug.

1. get\set

@Component
public class GetSetAssembler implements IAssembler<UserVO, UserDTO> {

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        userDTO.setUserId(var.getUserId());
        userDTO.setUserNickName(var.getUserNickName());
        userDTO.setCreateTime(var.getCreateTime());
        return userDTO;
    }

}
  • Recommendation: ‚ėÖ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÖ
  • Means: handwriting
  • Comments: in fact, this method is also the most commonly used. The performance must be lever, but it is a little troublesome to operate. Especially when VO objects with a lot of attributes are converted into DTO objects. But there are also some quick operation methods. For example, you can select all attributes through Shift+Alt, merge Shift+Tab into one column, and then select this column with ALT to paste in batch userDTO.set and the shortcut key capitalize the first letter of the attribute. Finally, switch to the end, add parentheses and semicolons, and finally format it.

2. json2Json

@Component
public class Json2JsonAssembler implements IAssembler<UserVO, UserDTO> {

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        String strJson = JSON.toJSONString(var);
        return JSON.parseObject(strJson, UserDTO.class);
    }

}
  • Recommendation: ‚ėÜ‚ėÜ‚ėÜ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÜ‚ėÜ‚ėÜ
  • Means: convert the object to JSON string, and then convert JSON to another object
  • Comments: it's probably a little burning!

3. Apache copyProperties

@Component
public class ApacheCopyPropertiesAssembler implements IAssembler<UserVO, UserDTO> {

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        try {
            BeanUtils.copyProperties(userDTO, var);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return userDTO;
    }

}
  • Recommendation: ‚ėÜ‚ėÜ‚ėÜ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÜ‚ėÜ‚ėÜ
  • Means: the Introspector mechanism obtains the attributes of the class for assignment
  • Comments: pit, poor compatibility, not recommended

4. Spring copyProperties

@Component
public class SpringCopyPropertiesAssembler implements IAssembler<UserVO, UserDTO> {

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(var, userDTO);
        return userDTO;
    }

}
  • Recommendation: ‚ėÖ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÖ‚ėÖ
  • Means: the Introspector mechanism obtains the attributes of the class for assignment
  • Comments: it is also a reflection property copy. The copyProperties provided by Spring are much easier to use than Apache. As long as you don't make mistakes, there will be no problem.

5. Bean Mapping

@Component
public class BeanMappingAssembler implements IAssembler<UserVO, UserDTO> {

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        BeanUtil.copyProperties(var, userDTO);
        return userDTO;
    }

}
  • Recommendation: ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Method: attribute copy
  • Comments: average performance

6. Bean Mapping ASM

@Component
public class BeanMappingAssembler implements IAssembler<UserVO, UserDTO> {

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        BeanUtil.copyProperties(var, userDTO);
        return userDTO;
    }

}
  • Recommendation: ‚ėÖ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÖ‚ėÖ
  • Means: Based on ASM bytecode framework
  • Comments: compared with ordinary Bean Mapping, the performance is improved and can be used.

7. BeanCopier

@Component
public class BeanCopierAssembler implements IAssembler<UserVO, UserDTO> {

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        BeanCopier beanCopier = BeanCopier.create(var.getClass(), userDTO.getClass(), false);
        beanCopier.copy(var, userDTO, null);
        return userDTO;
    }

}
  • Recommendation: ‚ėÖ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÖ‚ėÖ
  • Means: generate get and set methods based on CGlib bytecode operation
  • Comments: the overall performance is very good and the use is not complicated. It can be used

8. Orika

@Component
public class OrikaAssembler implements IAssembler<UserVO, UserDTO> {

    /**
     * Construct a MapperFactory
     */

    private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

    static {
        mapperFactory.classMap(UserDTO.class, UserVO.class)
¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†.field("userId",¬†"userId")¬†¬†//  You can specify when the fields are inconsistent
                .byDefault()
                .register()
;
    }

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        return mapperFactory.getMapperFacade().map(var, UserDTO.class);
    }

}
  • Official website: https://orika-mapper.github.io/orika-docs/
  • Recommendation: ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Method: generate mapping object based on bytecode
  • Comments: the test performance is not too outstanding. If it is used, the construction of MapperFactory needs to be optimized into Bean objects

9. Dozer

@Component
public class DozerAssembler implements IAssembler<UserVO, UserDTO> {

    private static DozerBeanMapper mapper = new DozerBeanMapper();

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        return mapper.map(var, UserDTO.class);
    }

}
  • Official website: http://dozer.sourceforge.net/documentation/gettingstarted.html
  • Recommendation: ‚ėÖ‚ėÜ‚ėÜ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Means: attribute mapping framework, copy objects recursively
  • Comments: the performance is a little poor, not recommended

10. ModelMapper

@Component
public class ModelMapperAssembler implements IAssembler<UserVO, UserDTO> {

    private static ModelMapper modelMapper = new ModelMapper();

    static {
        modelMapper.addMappings(new PropertyMap<UserVO, UserDTO>() {
            @Override
            protected void configure() {
¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†//  The attribute values are different and can be operated by yourself
                map().setUserId(source.getUserId());
            }
        });
    }

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        return modelMapper.map(var, UserDTO.class);
    }

}
  • Official website: http://modelmapper.org
  • Recommendation: ‚ėÖ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÜ‚ėÜ
  • Means: Based on ASM bytecode
  • Comments: the performance is good when the number of conversion objects is small. If you convert objects in large quantities at the same time, the performance will decline

11. JMapper

JMapper<UserDTO, UserVO> jMapper = new JMapper<>(UserDTO.class, UserVO.class, new JMapperAPI()
        .add(JMapperAPI.mappedClass(UserDTO.class)
                .add(JMapperAPI.attribute("userId")
                        .value("userId"))
                .add(JMapperAPI.attribute("userNickName")
                        .value("userNickName"))
                .add(JMapperAPI.attribute("createTime")
                        .value("createTime"))
        ))
;
  • Official website: https://github.com/jmapper-framework/jmapper-core/wiki
  • Recommendation: ‚ėÖ‚ėÖ‚ėÖ‚ėÖ‚ėÖ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÖ
  • Means: element, high performance and robustness all in one java bean mapper
  • Comments: the speed is really OK, but it's a little troublesome combined with SpringBoot. Maybe the posture is wrong

12. MapStruct

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface UserDTOMapping extends IMapping<UserVO, UserDTO> {

¬†¬†¬†¬†/**¬†Single example for testing  */
    IMapping<UserVO, UserDTO> INSTANCE = Mappers.getMapper(UserDTOMapping.class);

    @Mapping(target = "userId", source = "userId")
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Override
    UserDTO sourceToTarget(UserVO var1);

    @Mapping(target = "userId", source = "userId")
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Override
    UserVO targetToSource(UserDTO var1);

}
  • Official website: https://github.com/mapstruct/mapstruct
  • Recommendation: ‚ėÖ‚ėÖ‚ėÖ‚ėÖ‚ėÖ
  • Performance: ‚ėÖ‚ėÖ‚ėÖ‚ėÖ
  • Means: directly generate the corresponding get and set during compilation, just like handwritten code
  • Comments: the speed is very fast. It does not need to be processed in the operation period. It is easy to use when combined into the framework

4, Summary

  • In fact, the operation of object attribute conversion is nothing more than based on reflection, AOP, CGlib, ASM and Javassist. Another good idea is to generate the corresponding get and set before compilation, just like handwritten.
  • Therefore, I prefer MapStruct, which is comfortable to use. One is from the expansibility, ease of use and compatibility of functions.
  • No matter what kind of use, you should do a complete test and verification. Don't copy and paste it when you come up, otherwise you may dig the pit early. Of course, it's not necessarily a brother to fill the pit.

5, Series recommendation

- END -

Scan the code below, pay attention to the bugstack wormhole stack, learn, grow and make common progress with brother Fu, and be the most expensive Coder in a code field!

  • Reply to [design pattern] and obtain "re learning Java design pattern", which is a practical book of real cases of the Internet. It is extracted from the actual business to learn code design in many scenarios such as transaction, marketing, second kill, middleware and source code.
  • Reply to [Spring column], Get "hand rolling Spring", which is a technical material to understand the core principles, design and implementation of Spring IOC, AOP, circular dependency and so on by taking the reader to write a simplified Spring framework.
  • Reply to the [Manual of facial Sutra] to obtain the manual of facial Sutra  •  Take Dachang Offer ", which is a deep core content of Java. It continues to explain in depth from data structure, algorithm, concurrent programming and JVM system 8. If you understand it, you really understand it.

Hello, I'm little brother Fu. First line Internet java Engineer and architect, developed transaction & marketing, wrote operation & activities, designed middleware, and tossed repeaters and IO boards. He has not only written the Java language, but also engaged in C#, PHP. He is a tosser with active technology.
Wrote a PDF in 2020 Revisiting Java design patterns , the download volume of the whole network is 500000 +, which has helped many students grow up and has published books. Two projects of github in the same year, CodeGuide , itstack-demo-design , continue to dominate the list trend and become a global hot project.
A small volume will be on the shelves in 2021 SpringBoot middleware design and development , 16 Internet middleware scenarios and 30 projects are the only time in the whole network to teach you how to build wheels and write middleware, because such technology is closest to P7, architects and high salaries!

This article is shared with WeChat official account bugstack wormhole stack (bugstack).
In case of infringement, please contact support@oschina.cn Delete.
Article participation“ OSC source creation program ”, you who are reading are welcome to join us and share with us.

Topics: Java Apache github Spring Spring Boot