background
As we all know, the Spring framework provides a well-known class copying tool, BeanUtils, which is simple and convenient to use.
However, the internal implementation of the same name property copy based on runtime reflection is not adequate for the field mapping and high performance runtime scenarios required, so the open source community has derived the following class copy framework
- MapStruct (build time Mapper implementation)
- Selma (Mapper implementation generated at compile time)
- Yangtu222 – BeanUtils (generates copy implementation bytecode for the first time)
- Mica (first generation of copy implementation bytecode)
- Hutool (Reflection)
use
At present, the second-generation password management platform adopts the BeanUtil class copy method rewritten by MICA. Overall, the performance can meet the requirements. However, in order to further improve the performance of class conversion during query, the application itself contains Swagger dependency, and Mapstruct dependency package is introduced in swagger. There is no need to introduce new dependencies.
Therefore,, the final consideration is to copy the class in the business scenario into a Mapstruct implementation, thus starting the Mapstruct pit climb road.
Software Package Version
SpringBoot: 2.4.2
SpringCloud: 2020.0.1
Lombok: 1.18.16
Mapstruct: 1.3.1. The Final
New rely on
Because mapstruct needs to automatically generate class transformation implementation according to the defined interface, mapstruct interface processing package needs to be introduced in two ways, one is in the form of Maven plug-in, and the other is in the form of Maven dependency
Maven plugin form (official recommendation)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1 track of</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Copy the code
Maven dependency form
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
Copy the code
Considering the large number of Maven modules on the platform and the complex inter-dependency relationship, the missing plug-in dependency can easily lead to bugs that are difficult to be checked, so the second method is finally adopted to reduce the amount of coding.
New mapping class
/ * * *@authorJia Yang * F@date2021/2/18 12:06 * /
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface OssEntityMapper {
OssVO ossToOssVO(Oss oss);
OssDTO ossToOssDto(Oss oss);
/** * bladeFile to Oss **@param bladeFile
* @return* /
@Mapping(target = "fileName", source = "name")
Oss bladeFileToOss(BladeFile bladeFile);
}
Copy the code
Adding unit tests
Because mapstruct is used for the first time, unit tests are written to check if the code succeeds
/ * * *@authorJia Yang * F@date2021/2/18 in * /
@Slf4j
@ExtendWith(BladeSpringExtension.class)
@SpringBootTest(classes = ResourceApplication.class)
@BladeBootTest(appName = AppConstant.APPLICATION_RESOURCE_NAME, profile = "test", enableLoader = true)
class OssEntityMapperTest {
@Autowired
private OssEntityMapper mapper;
@Test
void ossToOssVO(a) {
Oss oss = new Oss();
oss.setFileName("filename");
oss.setLink("link");
oss.setOriginalName("origin");
oss.setOssType(OssType.QI_NIU_OSS);
oss.setIsDeleted(BladeConstant.DB_NOT_DELETED);
OssVO ossVO = mapper.ossToOssVO(oss);
assertEquals("filename", ossVO.getFileName());
assertEquals("link", ossVO.getLink());
assertEquals("origin", ossVO.getOriginalName());
}
@Test
void ossToOssDto(a) {
Oss oss = new Oss();
oss.setFileName("filename");
oss.setLink("link");
oss.setOriginalName("origin");
oss.setOssType(OssType.QI_NIU_OSS);
oss.setIsDeleted(BladeConstant.DB_NOT_DELETED);
OssDTO ossDTO = mapper.ossToOssDto(oss);
assertEquals("filename", ossDTO.getFileName());
assertEquals("link", ossDTO.getLink());
assertEquals("origin", ossDTO.getOriginalName());
}
@Test
void bladeFileToOss(a) {
BladeFile file = new BladeFile();
file.setName("file");
file.setLink("link");
file.setOriginalName("origin");
Oss oss = mapper.bladeFileToOss(file);
assertEquals("file", oss.getFileName());
assertEquals("link", oss.getLink());
assertEquals("origin", oss.getOriginalName()); }}Copy the code
Compile the results
Compiling result, error reported
This is very strange, this is according to the official website of the simplest way to write, and IDEA also installed mapstruct plug-in, also did not report error, can correctly identify attributes, how to compile failed
Looking at the generated code, there is indeed no property mapping
Climb the pit
Because compiling error, consider the following solution
-
Remove spring container dependencies and write them as class references. – invalid
-
Remove attribute mapping, try to compile, can compile, but the generated code does not have the same attribute mapping, will only return null value. – invalid
@Override public Oss bladeFileToOss(BladeFile bladeFile) { if ( bladeFile == null ) { return null; } Oss oss = new Oss(); return oss; } Copy the code
-
After changing the class name, the test passes, but the test still fails several times. Could it be related to the compilation environment?
-
The same code is tested in a separate project (non-Maven multi-module). — Could it be related to Maven multi-module dependencies?
-
According to the online search results, the lombok version is too low. After checking, the current Lombok version should meet the minimum version requirements. – invalid
-
Considering whether there is any conflict with some spring components, a separate maven multi-module engineering test was opened, but the test still failed. — Is it really about Maven?
The solution
Finally, the answer was obtained by submitting an issue consultation to the official warehouse
Lombok s version is too high.
The final issue of lowering lombok versions is resolved.