放心大膽的用,BeanUtils.copyProperties沒(méi)有想象中的那么差
不知道從什么時(shí)候開(kāi)始,大家對(duì)Spring的BeanUtils.copyProperties口誅筆伐,似乎用了這個(gè)方法拷貝bean屬性就低人一等,代碼分分鐘就是一堆bug一樣。但我相信,這個(gè)方法在大家的項(xiàng)目中出場(chǎng)率一定不低。
今天我們來(lái)分析一下,BeanUtils.copyProperties那些常被人吐槽的點(diǎn),是否真的有大家說(shuō)的那么不堪。
槽點(diǎn)1. 不聲明屬性的get、set方法,屬性將copy失敗
首先我們要明白,BeanUtils.copyProperties中sourceBean和targetBean的屬性的拷貝,是通過(guò)反射中的Method完成的,所以如果Bean不聲明屬性的set和get方法,就不能進(jìn)行屬性間的copy。
所以說(shuō)這不能說(shuō)人家框架有問(wèn)題,就像我們?nèi)绻涣私釹pringweb的原理,寫(xiě)出的接口出了問(wèn)題,卻說(shuō)Spring框架有問(wèn)題,豈不是欲加之罪?
槽點(diǎn)2. copy為淺拷貝(拷貝對(duì)象的引用)
BeanUtils.copyProperties的定位就是快速淺拷貝,對(duì)于大多數(shù)的場(chǎng)景而言,通過(guò)getset方式快速?gòu)?fù)制屬性,已經(jīng)基本能滿(mǎn)足我們的日常需求。如果有深拷貝的需求,那我們要做的應(yīng)該更換拷貝工具,而不是埋怨BeanUtils.copyProperties有bug。
槽點(diǎn)3. Spring不同版本對(duì)屬性泛型處理方式不同
從工具類(lèi)的角度看,兩個(gè)類(lèi)的屬性名相同,但是泛型類(lèi)型不同,所以未進(jìn)行屬性復(fù)制。
這個(gè)問(wèn)題從不同的角度看似乎都有其合理性。從用戶(hù)角度看,同一個(gè)名稱(chēng)的屬性未復(fù)制值,這是個(gè)bug。但是從工具類(lèi)角度看,不同的泛型就相當(dāng)于兩個(gè)屬性,不復(fù)制是合理的。
但是反過(guò)來(lái)想,如果工具類(lèi)直接把屬性名相同的值進(jìn)行復(fù)制,而不校驗(yàn)泛型,那么當(dāng)我們使用target的時(shí)候,發(fā)現(xiàn)獲取的值不是source中的類(lèi)型,是不是又該埋怨工具類(lèi)擅自做主了呢?
所以我覺(jué)得,這個(gè)問(wèn)題頂多算是寫(xiě)代碼不規(guī)范導(dǎo)致的。
性能
對(duì)于絕大部分場(chǎng)景來(lái)說(shuō),屬性復(fù)制不會(huì)對(duì)性能有特別大的影響,一般不會(huì)成為性能瓶頸。
總結(jié)
說(shuō)了這么多,其實(shí)也并不是要大家無(wú)腦的去使用BeanUtils.copyProperties,而是希望大家在合適的場(chǎng)景選用合適的工具做合適的事。
我們常說(shuō),透過(guò)現(xiàn)象看本質(zhì),能真正的理解其背后的復(fù)制原理,才能讓我們的編碼能力不斷提升,而不是人云亦云的說(shuō)某某工具類(lèi)不好用。
借用一位老哥的話(huà):有的人干5年有5年的經(jīng)驗(yàn),有的人一個(gè)經(jīng)驗(yàn)用5年。希望大家都能像前者一樣,在技術(shù)的道路不斷進(jìn)步。