SpringBoot整合高性能BeanCopy-Orika工具
我们在业务中,经常需要转换对象,来解决各种 POJO,VO,DTO 之间的转换,在不使用工具类的情况下,需要写大量的 Get,Set 方法,代码看起来很臃肿.现在也有很多工具类可以让我们来使用,解决这个问题,常用的有 mapstruct、Spring BeanUtils、Apache BeanUtils、dozer 等,今天要介绍的是 orika.
Orika是一个简单、快速的JavaBean拷贝框架,它能够递归地将数据从一个JavaBean复制到另一个JavaBean,这在多层应用开发中是非常有用的。Orika 底层采用了javassist类库生成Bean映射的字节码,之后直接加载执行生成的字节码文件,因此在速度上比使用反射进行赋值会快很多.
- MapperFactoryBean
import ma.glasnost.orika.CustomConverter;
import ma.glasnost.orika.Mapper;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.ClassMapBuilder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class MapperFactoryBean implements FactoryBean<MapperFactory>, ApplicationContextAware {
ApplicationContext applicationContext;
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public MapperFactory getObject() throws Exception {
DefaultMapperFactory build = new DefaultMapperFactory.Builder().build();
for (CustomConverter converter : applicationContext.getBeansOfType(CustomConverter.class).values()) {
build.getConverterFactory().registerConverter(converter);
}
for (Mapper<?, ?> mapper : applicationContext.getBeansOfType(Mapper.class).values()) {
build.registerMapper(mapper);
}
for (ClassMapBuilder<?, ?> mapper : applicationContext.getBeansOfType(ClassMapBuilder.class).values()) {
build.registerClassMap(mapper);
}
return build;
}
@Override
public Class<?> getObjectType() {
return MapperFactory.class;
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
- OrikaConfig
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.converter.BidirectionalConverter;
import ma.glasnost.orika.metadata.Type;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
@Configuration
public class OrikaConfig {
@Bean
public MapperFactoryBean loadFactory(){
return new MapperFactoryBean();
}
@Bean
public MapperFacade loadMapperFacade(MapperFactory factory){
return factory.getMapperFacade();
}
@Autowired
private MapperFactory mapperFactory;
/**
* 解决orika映射LocalDateTime报错问题
*/
@PostConstruct
public void init() {
mapperFactory.getConverterFactory().registerConverter(new LocalDateTimeConverter());
mapperFactory.getConverterFactory().registerConverter(new LocalDateConverter());
mapperFactory.getConverterFactory().registerConverter(new LocalTimeConverter());
mapperFactory.getConverterFactory().registerConverter(new IntegerToBooleanConverter());
}
private static class LocalDateTimeConverter extends BidirectionalConverter<LocalDateTime, LocalDateTime> {
@Override
public LocalDateTime convertTo(LocalDateTime source, Type<LocalDateTime> destinationType) {
return LocalDateTime.from(source);
}
@Override
public LocalDateTime convertFrom(LocalDateTime source, Type<LocalDateTime> destinationType) {
return LocalDateTime.from(source);
}
}
private static class LocalDateConverter extends BidirectionalConverter<LocalDate, LocalDate> {
@Override
public LocalDate convertTo(LocalDate source, Type<LocalDate> destinationType) {
return LocalDate.from(source);
}
@Override
public LocalDate convertFrom(LocalDate source, Type<LocalDate> destinationType) {
return LocalDate.from(source);
}
}
private static class LocalTimeConverter extends BidirectionalConverter<LocalTime, LocalTime> {
@Override
public LocalTime convertTo(LocalTime source, Type<LocalTime> destinationType) {
return LocalTime.from(source);
}
@Override
public LocalTime convertFrom(LocalTime source, Type<LocalTime> destinationType) {
return LocalTime.from(source);
}
}
private static class IntegerToBooleanConverter extends BidirectionalConverter<Integer, Boolean> {
@Override
public Boolean convertTo(Integer source, Type<Boolean> destinationType) {
return source != null && source == 1;
}
@Override
public Integer convertFrom(Boolean source, Type<Integer> destinationType) {
return source ? 1 : 0;
}
}
}
- OrikaUtil
import ma.glasnost.orika.MapperFacade;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
@Component
public class OrikaUtil {
@Resource
private MapperFacade mapperFacade;
public static MapperFacade staticMapperFacade;
@PostConstruct
public void init() {
staticMapperFacade=mapperFacade;
}
public static MapperFacade getMapperFacade() {
return staticMapperFacade;
}
}