欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

BeanUtils.copyProperties復(fù)制不生效的解決

 更新時間:2021年09月01日 09:45:30   作者:藍(lán)風(fēng)9  
這篇文章主要介紹了BeanUtils.copyProperties復(fù)制不生效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

前言

呵呵 前端時間使用 BeanUtils.copyProperties 的時候碰到了一個這樣的問題

我有兩個實體, 有同樣的屬性, 一個有給定的屬性的 getter, 另外一個有 給定的屬性的 setter, 但是 我使用 BeanUtils.copyProperties 的時候 把來源對象的這個屬性 復(fù)制不到 目標(biāo)對象上面

然后 當(dāng)時也跟蹤了一下代碼, 然后 這里整理一下 改代碼片段吧

然后在調(diào)試的過程中 也發(fā)現(xiàn)了一些其他的問題, 呵呵 算是額外的了解吧

一下代碼基于 : jdk1.8.0_211 + commons-beanutils 1.9.4

問題的排查

首先來一段測試用例, 里面主要包含了三個類, 一個測試類, 兩個實體類

package com.hx.test03;  
import org.apache.commons.beanutils.BeanUtils; 
/**
 * Test24BeanUtilsCopy
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2020-02-25 16:55
 */
public class Test24BeanUtilsCopy {
 
  // Test24BeanUtilsCopy
  // 1. 取的 source 的 propertyDescriptor
  // 2. get, set 對應(yīng)的類型不匹配
  public static void main(String[] args) throws Exception {
 
    Test24ImmutableEntity fromImmutable = new Test24ImmutableEntity("fromImmutable");
    Test24MutableEntity fromMutable = new Test24MutableEntity("fromMutable");
    Test24MutableEntity targetEntity = new Test24MutableEntity("targetEntity");
 
    // does't work
    BeanUtils.copyProperties(targetEntity, fromImmutable);
    System.out.println(targetEntity.getAttr());
    // does't work
    BeanUtils.copyProperties(targetEntity, fromMutable);
    System.out.println(targetEntity.getAttr()); 
  }
}
 
package com.hx.test03; 
/**
 * ImmutablePayment
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2020-02-25 16:32
 */
public class Test24ImmutableEntity {
 
  // attr
  private final String attr;
 
  public Test24ImmutableEntity(String attr) {
    this.attr = attr;
  }
 
  public String getAttr() {
    return attr;
  } 
}
package com.hx.test03; 
import java.util.Optional; 
/**
 * ImmutablePayment
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2020-02-25 16:32
 */
public class Test24MutableEntity {
 
  // attr
  private String attr;
 
  public Test24MutableEntity(String attr) {
    this.attr = attr;
  }
 
  public Optional<String> getAttr() {
    return Optional.of(attr);
  }
 
//  public String getAttr() {
//    return attr;
//  }
 
  public void setAttr(String attr) {
    this.attr = attr;
  } 
}

以上測試代碼輸出結(jié)果為 :

從測試代碼中可以看到這里有兩個 BeanUtils.copyProperties 的使用, 并且兩個都沒有拷貝成功, 我們一個一個的來看

首先是第一個 BeanUtils.copyProperties, 來源對象 和 目標(biāo)對象分別為 ImmutableEntity 和 MutableEntity

ImmutableEntity 上面有 getAttr, MutableEntity 上面有 setAttr, 但是為什么沒有拷貝成功呢 ?

在下圖的地方打一個斷點 調(diào)試一下

調(diào)試發(fā)現(xiàn) 源對象是可讀的, 但是 目標(biāo)對象不可寫?, 為什么呢?, 我們的 MutableEntity 不是有 setAttr 么

在 processPropertyDescriptor 方法之后, 我們發(fā)現(xiàn) attr 屬性, 居然不可寫了 ?

具體到 processPropertyDescriptor 方法, 他主要干的事情是

// 1. 尋找 getter(存在多個merge) 
// First pass. Find the latest getter method. Merge properties
// of previous getter methods.
 
// 2. 尋找 setter(存在多個merge) 
// Second pass. Find the latest setter method which
// has the same type as the getter method.
 
// 3. merge getter & setter 
// At this stage we should have either PDs or IPDs for the
// representative getters and setters. The order at which the
// property descriptors are determined represent the
// precedence of the property ordering.

以上注釋來自于 Introspector.java, 1, 2, 3 的注釋來自于我

我們這里重點關(guān)注 step2, 需要找到 類型匹配 getter 類型的 setter 方法, 但是我們這里的情況是 getter 返回值是 Optional, setter 返回值是 String, 因此類型不匹配 所以我們上面看到的結(jié)果是 有 getter, 沒得 setter

實際的上下文信息如下圖

以上便是 第一個 BeanUtils.copyProperties 不生效的原因了

第二個 BeanUtils.copyProperties, 原因也是同上, 不過直觀的理解來說, attr 是有 getter 并且有 setter 的, 但是 由于規(guī)范的約定, 因此 propertyDescriptor 里面有 getter, 沒得 setter

問題的擴(kuò)展

package com.hx.test03;  
import org.apache.commons.beanutils.BeanUtils; 
/**
 * BeanUtilsCopy
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2020-02-24 12:49
 */
public class Test23BeanUtilsCopy {
 
  // Test23BeanUtilsCopy
  // 1. 取的 source 的 propertyDescriptor
  // 2. get, set 對應(yīng)的類型不匹配
  public static void main(String[] args) throws Exception { 
    ImmutableEntity fromImmutable = new ImmutableEntity("fromImmutable");
    MutableEntity fromMutable = new MutableEntity("fromMutable");
    MutableEntity targetEntity = new MutableEntity("targetEntity");
 
    // does't work
    BeanUtils.copyProperties(targetEntity, fromImmutable);
    System.out.println(targetEntity.getAttr());
    // does't work
    BeanUtils.copyProperties(targetEntity, fromMutable);
    System.out.println(targetEntity.getAttr()); 
  }
}
 
/**
 * ImmutablePayment
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2020-02-24 12:50
 */
class ImmutableEntity {
  // attr
  private final String attr;
 
  public ImmutableEntity(String attr) {
    this.attr = attr;
  }
 
  public String getAttr() {
    return attr;
  }
}
 
/**
 * MutablePayment
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2020-02-24 12:54
 */
class MutableEntity {
  // attr
  private String attr;
 
  public MutableEntity(String attr) {
    this.attr = attr;
  }
 
//  public Optional<String> getAttr() {
//    return Optional.of(attr);
//  }
  public String getAttr() {
    return attr;
  }
 
  public void setAttr(String attr) {
    this.attr = attr;
  }
}
 

我們吧如上代碼 整理到同一個文件中(這其實才是第一個 demo, 上文中的是第二個 demo), 并且調(diào)整了 MutableEntity.getter 使其和 setter 的類型能夠匹配

但是我們一跑, 發(fā)現(xiàn)結(jié)果還是有些出人意料

BeanUtilsBean 如下地方打一個斷點

我們發(fā)現(xiàn)這里有一個奇怪的現(xiàn)象, 源對象不可讀, 目標(biāo)對象不可寫??, 這是怎么回事 ?

以 ImmutableEntity. getAttr 為例, 我們在 MethodUtils.getAccessableMethod 里面如下地方打一個斷點

我們發(fā)現(xiàn) 尋找目標(biāo)的方法主要有圖中 三個地方

第一個是當(dāng)前類, 另外一個是當(dāng)前類實現(xiàn)的接口, 另外一個是 當(dāng)前類的基類(上圖還有未截取完的一部分, 限定 method 必須為 public, 否則不允許訪問)

  • 1. 在當(dāng)前類查詢 : 首先需要限定當(dāng)前類是 public(我們這里不滿足) public 允許訪問
  • 2. 當(dāng)前類實現(xiàn)的接口查詢 : 獲取接口以及父接口中 匹配方法名字, 參數(shù)列表 的方法
  • 3. 當(dāng)前類的基類查詢 : 獲取基類以及更上的基類中, 并且是 public 的基類, 匹配方法名字, 參數(shù)列表 的方法

因此, 我們這里的 第二個例子的 兩個 BeanUtils.copyProperties 也沒有生效

呵呵 不知道這個限定類為 public 的限定是否是 bug 呢?, 還是說 相關(guān)規(guī)范就是這么約定的呢 ?

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • JAVA讀取文件夾大小的幾種方法實例

    JAVA讀取文件夾大小的幾種方法實例

    這篇文章介紹了JAVA讀取文件夾大小的幾種方法實例,有需要的朋友可以參考一下
    2013-10-10
  • Java字符串轉(zhuǎn)成二進(jìn)制碼的方法

    Java字符串轉(zhuǎn)成二進(jìn)制碼的方法

    這篇文章主要為大家詳細(xì)介紹了Java字符串轉(zhuǎn)成二進(jìn)制碼的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一
    2017-05-05
  • springboot2中session超時,退到登錄頁面方式

    springboot2中session超時,退到登錄頁面方式

    這篇文章主要介紹了springboot2中session超時,退到登錄頁面方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • mybatis?plus實現(xiàn)分頁邏輯刪除

    mybatis?plus實現(xiàn)分頁邏輯刪除

    這篇文章主要為大家介紹了mybatis?plus實現(xiàn)分頁邏輯刪除的方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • java基礎(chǔ)的詳細(xì)了解第三天

    java基礎(chǔ)的詳細(xì)了解第三天

    這篇文章對Java編程語言的基礎(chǔ)知識作了一個較為全面的匯總,在這里給大家分享一下。需要的朋友可以參考,希望能給你帶來幫助
    2021-08-08
  • SpringBoot啟動器Starters使用及原理解析

    SpringBoot啟動器Starters使用及原理解析

    這篇文章主要介紹了SpringBoot啟動器Starters使用及原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • jar包運行一段時間后莫名其妙掛掉線上問題及處理方案

    jar包運行一段時間后莫名其妙掛掉線上問題及處理方案

    這篇文章主要介紹了jar包運行一段時間后莫名其妙掛掉線上問題及處理方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 詳解SpringBoot中如何使用Reactor模型

    詳解SpringBoot中如何使用Reactor模型

    Reactor模型主要提供了一種在Java虛擬機上構(gòu)建非阻塞應(yīng)用的方式,這種方式使用了響應(yīng)式編程原理,通過響應(yīng)式流標(biāo)準(zhǔn)來實現(xiàn),下面我們就來看看它在SpringBoot中是如何使用的吧
    2024-04-04
  • jtds1.1連接sqlserver2000測試示例

    jtds1.1連接sqlserver2000測試示例

    這篇文章主要介紹了jtds1.1連接sqlserver2000測試示例,需要的朋友可以參考下
    2014-02-02
  • Springboot項目刪除項目同步target文件問題解決方案

    Springboot項目刪除項目同步target文件問題解決方案

    這篇文章主要介紹了Springboot項目刪除項目同步target文件問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-12-12

最新評論