MapStruct是一个对象属性拷贝工具,一般用于不同层级模型的对象属性拷贝。Icopiedtheperformancecomparisonofotherpeople'stestsfromtheInternet.PCconfiguration:i7,16Gmemory,variousBeancopytools,comparisontools,tenobjectscopiedonce,10,000objectscopiedonce,onemillionobjectscopiedonce,onemillionobjectscopiedonce复制5次mapStruct0ms3ms96ms281mshutools的BeanUtil23ms102ms1734ms8316msspring的BeanUtils2ms47ms726ms3676msapache的BeanUtils20ms156ms10658ms52355msapache的PropertyUtils5ms68ms6767ms30694ms来源:MapStruct使用及性能测试,秒杀BeanUtil基础使用依赖配置pom.xml配置以下内容,例子中使用了lombok,所以我把lombok的配置也加上了1.4.2.Final1.18.20org.projectlomboklombok${lombok.version}trueorg.mapstructmapstruct</artifactId><版本>${org.mapstruct.version}org.apache.maven.pluginsmaven-compiler-plugin<版本>3.8.1<配置><路径>org.projectlomboklombok<版本>${lombok.version}org.mapstructmapstruct-process或${org.mapstruct.version}官方示例@DatapublicclassCar{privateStringmake;私有intnumberOfSeats;私有CarType类型;}@DatapublicclassCarDto{privateStringmake;私人座位数;私有字符串类型;}@MapperpublicinterfaceCarMapper{CarMapperINSTANCE=Mappers.getMapper(CarMapper.class);//字符段名称不同时,可以使用@Mapping配置关系@Mapping(source="numberOfSeats",target="seatCount")CarDtocarToCarDto(Carcar);}@TestpublicvoidshouldMapCarToDto(){//givenCarcar=new汽车(“莫里斯”,5,CarType.SEDAN);//当CarDtocarDto=CarMapper.INSTANCE.carToCarDto(car);//然后assertThat(carDto).isNotNull();assertThat(carDto.getMake()).isEqualTo(“莫里斯”);assertThat(carDto.getSeatCount()).isEqualTo(5);assertThat(carDto.getType()).isEqualTo("SEDAN");}封装从上面的例子来看,每次使??用都需要调用一次Mapper.INSTANCE来获取Mapper,这样Mapper就会和业务代码耦合,不利于以后替换其他工具。我们可以将复制对象属性的功能抽象成一个接口Convert,所有的Bean都是Convert的子类,这样每个Bean都具有转换对象的能力。publicinterfaceConvertextendsSerializable{/***获取自动转换的JavaBean对象**@paramclazzclasstype*@paramtype*@returnobject*/@SuppressWarnings({"unchecked","rawtypes"})defaultTconvert(Classclazz){BeanConvertMapper映射器=BeanConvertMappers.getMapper(this.getClass(),clazz);返回(T)mapper.to(this);}}BeanConvertMapper定义了一个对象转换接口publicinterfaceBeanConvertMapper{/***sourcetotarget**@paramsourcesource*@returntarget*/TARGETto(SOURCEsource);}BeanConvertMappers是一个工具类,它提供源对象Class和目标对象Class获取Mapper方法。@SuppressWarnings({"rawtypes","unchecked"})publicclassBeanConvertMappers{publicstaticBeanConvertMappergetMapper(ClasssourceClass,ClasstargetClass){Stringkey=MapperDefinition.generateKey(sourceClass,targetClass);类mapperClass=MapperDefinition.getMappers().get(key);if(mapperClass==null){thrownewIllegalArgumentException(StrUtil.format("找不到{}到{}Mapper",sourceClass.getName(),targetClass.getName()));}返回(BeanConvertMapper)Mappers.getMapper(mapperClass);}}MapperDefinition维护着所有的Mappers,新的Mappers只需要注册到地图上即可。@SuppressWarnings("rawtypes")publicclassMapperDefinition{privatestaticMapMAPPERS=newHashMap<>(16);static{registerMapper(CarDto.class,Car.class,CarDtoToCarMapper.class);//新增加的Mapper在此注册MAPPERS=MapUtil.unmodifiable(MAPPERS);}/*Mapper定义*/@MapperpublicinterfaceCarDtoToCarMapperextendsBeanConvertMapper{}/*Mapper定义*/publicstaticMapgetMappers(){returnMAPPERS;}publicstaticStringgenerateKey(ClasssourceClass,ClasstargetClass){returnsourceClass.getName()+targetClass.getName();}privatestaticvoidregisterMapper(ClasssourceClass,ClasstargetClass,Class>mapperClass){MAPPERS.put(generateKey(sourceClass,targetClass),mapperClass);}}进一步优化上面的封装,解决了Mapper耦合的问题,但是在定义Mapper的时候,仍然存在大量的模板接口。有没有更好的方法来解决它?我想到的方案是:和mapstruct的原理一样,在mapstruct的注解处理器之前,通过注解生成BeanConvertMapper接口。注释大致如下。@Target(ElementType.TYPE)@Retention(RetentionPolicy.CLASS)public@interfaceMapperDefinition{/***源对象的类**@returnClass*/Class>source();/***目标对象的类**@returnClass*/Class>target();}有没有更好的方案,分享一下