BeanCopier

使用Converter

當(dāng)源和目標(biāo)類的屬性類型不同時(shí),不能拷貝該屬性,此時(shí)我們可以通過實(shí)現(xiàn)Converter接口來自定義轉(zhuǎn)換器:

源類和目標(biāo)類:

    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

基于目標(biāo)對象的屬性出發(fā),如果源對象有相同名稱的屬性,則調(diào)一次convert方法:


    package net.sf.cglib.core;  
      
    public interface Converter {  
        // value 源對象屬性的值,target 目標(biāo)對象屬性的類,context 目標(biāo)對象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定義的規(guī)則去拷貝屬性,所以在convert方法中要考慮所有的屬性。

性能優(yōu)化

BeanCopier拷貝速度快,性能瓶頸出現(xiàn)在創(chuàng)建BeanCopier實(shí)例的過程中。所以,把創(chuàng)建過的BeanCopier實(shí)例放到緩存中,下次可以直接獲取,提升性能:

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();  
    }  
}  
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • 本文將簡要介紹CGLIB代碼包結(jié)構(gòu)以及核心類的基本功能,然后通過介紹BeanCopier的使用例子,將其作為引子對...
    9cc9閱讀 21,013評論 5 42
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,971評論 6 342
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,778評論 18 399
  • 慧女立志求至學(xué), 小雀成鳳出深山。 父女歡歌赴古都, 過洛陽奔娘子關(guān)。 憶往昔又謀遠(yuǎn)景, 廿時(shí)車程彈指間。 勤學(xué)苦...
    亮靚_27d5閱讀 335評論 4 14