BeanCopier

使用Converter

当源和目标类的属性类型不同时,不能拷贝该属性,此时我们可以通过实现Converter接口来自定义转换器:

源类和目标类:

    public class AccountEntity {  
        private int id;  
        private Timestamp createTime;  
        private BigDecimal balance;  
        // Getters and setters are omitted  
    }  

    public class AccountDto {  
        private int id;  
        private String name;  
        private String createTime;  
        private String balance;  
        // Getters and setters are omitted  
    }  
  1. 不使用Converter

    public class BeanCopierConverterTest {  
      
        @Test  
        public void noConverterTest() {  
            AccountEntity po = new AccountEntity();  
            po.setId(1);  
            po.setCreateTime(new Timestamp(10043143243L));  
            po.setBalance(BigDecimal.valueOf(4000L));  
            BeanCopier copier = BeanCopier.create(AccountEntity.class, AccountDto.class, false);  
            AccountDto dto = new AccountDto();  
            copier.copy(po, dto, null);  
            Assert.assertNull(dto.getCreateTime()); // 类型不同,未拷贝  
            Assert.assertNull(dto.getBalance()); // 类型不同,未拷贝  
        }  
    }  

  1. 使用Converter

基于目标对象的属性出发,如果源对象有相同名称的属性,则调一次convert方法:


    package net.sf.cglib.core;  
      
    public interface Converter {  
        // value 源对象属性的值,target 目标对象属性的类,context 目标对象setter方法名  
        Object convert(Object value, Class target, Object context);  
    }  
    @Test  
    public void converterTest() {  
        AccountEntity po = new AccountEntity();  
        po.setId(1);  
        po.setCreateTime(Timestamp.valueOf("2014-04-12 16:16:15"));  
        po.setBalance(BigDecimal.valueOf(4000L));  
        BeanCopier copier = BeanCopier.create(AccountEntity.class, AccountDto.class, true);  
        AccountConverter converter = new AccountConverter();  
        AccountDto dto = new AccountDto();  
        copier.copy(po, dto, converter);  
        Assert.assertEquals("2014-04-12 16:16:15", dto.getCreateTime());  
        Assert.assertEquals("4000", dto.getBalance());  
    }  
      
    static class AccountConverter implements Converter {  
      
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
      
        @SuppressWarnings("rawtypes")  
        @Override  
        public Object convert(Object value, Class target, Object context) {  
            if (value instanceof Integer) {  
                return (Integer) value;  
            } else if (value instanceof Timestamp) {  
                Timestamp date = (Timestamp) value;  
                return sdf.format(date);  
            } else if (value instanceof BigDecimal) {  
                BigDecimal bd = (BigDecimal) value;  
                return bd.toPlainString();  
            }  
            return null;  
        }  
    }  

注:一旦使用Converter,BeanCopier只使用Converter定义的规则去拷贝属性,所以在convert方法中要考虑所有的属性。

性能优化

BeanCopier拷贝速度快,性能瓶颈出现在创建BeanCopier实例的过程中。所以,把创建过的BeanCopier实例放到缓存中,下次可以直接获取,提升性能:

public class CachedBeanCopier {  
  
    static final Map<String, BeanCopier> BEAN_COPIERS = new HashMap<String, BeanCopier>();  
  
    public static void copy(Object srcObj, Object destObj) {  
        String key = genKey(srcObj.getClass(), destObj.getClass());  
        BeanCopier copier = null;  
        if (!BEAN_COPIERS.containsKey(key)) {  
            copier = BeanCopier.create(srcObj.getClass(), destObj.getClass(), false);  
            BEAN_COPIERS.put(key, copier);  
        } else {  
            copier = BEAN_COPIERS.get(key);  
        }  
        copier.copy(srcObj, destObj, null);  
    }  
  
    private static String genKey(Class<?> srcClazz, Class<?> destClazz) {  
        return srcClazz.getName() + destClazz.getName();  
    }  
}  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,923评论 18 139
  • 本文将简要介绍CGLIB代码包结构以及核心类的基本功能,然后通过介绍BeanCopier的使用例子,将其作为引子对...
    9cc9阅读 21,001评论 5 42
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,953评论 6 342
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,765评论 18 399
  • 慧女立志求至学, 小雀成凤出深山。 父女欢歌赴古都, 过洛阳奔娘子关。 忆往昔又谋远景, 廿时车程弹指间。 勤学苦...
    亮靓_27d5阅读 334评论 4 14