亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaBeanInfo 和 Spring 之間有什么關系

發布時間:2021-06-30 18:00:46 來源:億速云 閱讀:148 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關JavaBeanInfo 和 Spring 之間有什么關系,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

Java Beans

在 Spring 中我們可以看到 BeanInfoFactory 該接口可以用來獲取 Class 對應的 BeanInfo 對象,在 CachedIntrospectionResults 中也有相關的成員變量作為信息存儲,其他地方還有筆者就不再這里都去搜索了,各位可以自行查閱。

  • BeanInfoFactory

    public interface BeanInfoFactory {
    @Nullable
       BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException;
    
    }


  • CachedIntrospectionResults

    public final class CachedIntrospectionResults {
    	private final BeanInfo beanInfo;
    }


對于 Spring 來說操作 Bean 本身的內容其實是操作各類屬性及其提供的方法。從筆者的角度來看 Bean 這個對象我覺得可以分成這三種,第一種是關于 Bean 屬性的,第二種是關于屬性操作的方法,第三種是提供外部操作的方法。就比如說現在有一個 People 對象,存在多個屬性,我們在對這個 Bean 對象定義的時候正常情況下我們會放入 private 修飾的屬性名,然后在提供 getset 方法,如果有需要我們可以在通過非屬性操作相關的方法。本章就暫時是對前兩者的一個討論。

首先我們來定義一個基本的 Java Bean

public class Student {
   private String name;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

現在我們用了一個名字叫做 Student 的 Java 對象,我們來看這個對象的解釋

  1. Student 對象中具有屬性 name

  2. Student 對象中存在字段 name

我們通常情況下會有這兩種對象的定義解釋,那么這個定義解釋在 Java 中是如何對其進行定義的呢。在 Java 中有一個接口叫做 java.beans.BeanInfo 這個接口是用來描述 Java Bean 的接口,下面我們來看這個接口中存在的方法

  • BeanInfo 方法信息

public interface BeanInfo {

    BeanDescriptor getBeanDescriptor();

    EventSetDescriptor[] getEventSetDescriptors();

    int getDefaultEventIndex();

    PropertyDescriptor[] getPropertyDescriptors();

    int getDefaultPropertyIndex();

    MethodDescriptor[] getMethodDescriptors();

    BeanInfo[] getAdditionalBeanInfo();
}
  • getBeanDescriptor :返回 Bean 的描述信息

  • getEventSetDescriptors:返回 Bean 相關的事件信息

  • getDefaultEventIndex:返回 Bean 默認事件索引

  • getPropertyDescriptors:返回 Bean 屬性描述

  • getDefaultPropertyIndex:返回 Bean 默認的屬性索引

  • getMethodDescriptors:返回 Bean 方法描述

  • getAdditionalBeanInfo :返回其他的 Bean Info 信息

下面我們先來對接口中的返回值做一些介紹

  • BeanDescriptor 成員變量表

變量名稱變量類型變量說明
beanClassRefReference<? extends Class<?>>bean 的類
customizerClassRefReference<? extends Class<?>>自定義的類
  • PropertyDescriptor 成員變量表

變量名稱變量類型變量說明
propertyTypeRefReference<? extends Class<?>>屬性類型
readMethodRefMethodRef讀方法
writeMethodRefMethodRef寫方法
propertyEditorClassRefReference<? extends Class<?>>屬性編輯類型
boundboolean
constrainedboolean
baseNameString
writeMethodNameString寫方法名稱
readMethodNameString讀方法名稱
  • MethodDescriptor 成員變量表

變量名稱變量類型變量說明
methodRefMethodRef方法
paramNamesString[]參數名稱
paramsList<WeakReference<Class<?>>>參數信息
parameterDescriptorsParameterDescriptor參數描述

在了解了上述三個對象后我們來編寫一個測試用例,該測試用例主要用來獲取 BeanInfo 接口數據

  • BeanInfo 測試用例

@Test
void classTest() throws IntrospectionException {
   Class clazz  = Student.class;
   BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
   System.out.println();
}
  • BeanInfo 信息

JavaBeanInfo 和 Spring 之間有什么關系

我們現在對 BeanInfo 有了一定的了解,接下來我們要通過 BeanInfo 來創建一個對象,并給該對象進行數據賦值,下面我們來寫代碼

@NotNull
private <T> T getObject(Class<T> clazz, Map<String, Object> prop) throws Exception {
   // 獲取 BeanInfo 接口
   BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
   // 獲取 Bean Class
   Class<?> beanClass = beanInfo.getBeanDescriptor().getBeanClass();
   // 獲取所有的構造函數
   Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
   // 確認構造函數: 直接取無參構造
   Constructor constructor = confirmConstructor(declaredConstructors);
   // 通過構造函數獲取對象
   Object bean = constructor.newInstance();
   // 為對象設置屬性
   // 提取屬性描述
   PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
   for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
      // 屬性名稱
      String name = propertyDescriptor.getName();
      if (prop.containsKey(name)) {

         // 寫函數
         Method writeMethod = propertyDescriptor.getWriteMethod();
         // 從屬性表中獲取屬性名稱對應的屬性值
         Object proValue = prop.get(name);
         writeMethod.invoke(bean, proValue);
      }
   }
   return (T) bean;
}

編寫這段代碼的主要邏輯如下

  1. 通過 Class 獲取 BeanInfo 接口

  2. 通過 BeanInfo 獲取 beanClass

  3. 通過 beanClass 提取構造函數列表,從構造函數列表中選擇一個具體的構造函數(這里采用無參構造的方式)

  4. 獲取屬性描述對象進行屬性設置

編寫完成后我們來寫測試用例

@Test
void beanInfoCreateBean() throws Exception {

   Class<Student> clazz = Student.class;
   // 設置屬性表
   Map<String, Object> prop = new HashMap<>(8);
   prop.put("name", "student_name");

   Student bean = getObject(clazz, prop);
   assert bean.getName().equals("student_name");
}

這樣我們就完成了數據賦值,在上述過程中我們對于 beanClass 的獲取可以直接使用參數傳遞的 clazz 直接使用,可以不需要通過 BeanInfo 接口進行二次調度。

下面我們來談一談 Spring 和 BeanInfo 的一些關聯。

相信各位在使用 Spring XML 模式的時候會編寫下面這樣的內容。

<bean id="people" class="com.source.hot.ioc.book.pojo.PeopleBean">
    <property name="name" value="zhangsan"/>
</bean>

這里我們拋開 Spring 中 Bean 生命周期相關的一些接口、占位符解析等內容,我們就簡單的來看這個 <bean> 標簽,這個標簽定義了一個 class 屬性 和子標簽 property ,我們可以通過一些 XML 解析工具得到這兩個對象,Spring 在這會將 class 屬性通過 ClassLoader 轉換成 Class 會將 property 轉換成對象 PropertyValue ,然后通過反射將對象創建出來。那么這段說明和我們所編寫的通過 BeanInfo 創建 Bean 有什么關系呢?我們可以思考下面幾個問題

  1. 知道了 BeanClass 如何才能創建對象呢?

  2. 知道屬性名稱和屬性值如何給對象賦值呢?

這兩個問題的答案很簡單就是通過 Java 反射機制來進行處理,那么具體怎么做呢?這個問題的答案其實就是我們前面所編寫的那段創建對象的代碼。回過頭我們來看這兩個問題

  1. 第一個問題的答案:創建對象其本質是尋找構造函數并調用

  2. 第二個問題的答案:通過找到寫方法將數據寫入

  • Spring 中無參構造函數的調用

JavaBeanInfo 和 Spring 之間有什么關系

  • 有參構造的推論過程

JavaBeanInfo 和 Spring 之間有什么關系

在這里做出了兩種構造函數的推論,當完成推論構造函數后就可以進行對象創建及屬性賦值了。

屬性賦值相關的代碼就不在截圖了各位可以自行查找。

當我們有了 getObject 這樣一個方法后,我們再來看一些生命周期,Spring 當中的各類生命周期其實就是圍繞者這段代碼的前后來做各種補充操作,

比如 InitializingBean 這個接口的調用時在 Bean 創建完成后,那么我們可以在具體的位置上補充這樣一段

  • 修改后的 getObject

@NotNull
private <T> T getObject(Class<T> clazz, Map<String, Object> prop) throws Exception {
   // 獲取 BeanInfo 接口
   BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
   // 獲取 Bean Class
   Class<?> beanClass = beanInfo.getBeanDescriptor().getBeanClass();
   // 獲取所有的構造函數
   Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
   // 確認構造函數: 直接取無參構造
   Constructor constructor = confirmConstructor(declaredConstructors);
   // 通過構造函數獲取對象
   Object bean = constructor.newInstance();
   // 為對象設置屬性
   // 提取屬性描述
   PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
   for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
      // 屬性名稱
      String name = propertyDescriptor.getName();
      if (prop.containsKey(name)) {

         // 寫函數
         Method writeMethod = propertyDescriptor.getWriteMethod();
         // 從屬性表中獲取屬性名稱對應的屬性值
         Object proValue = prop.get(name);
         writeMethod.invoke(bean, proValue);
      }
   }
   if (bean instanceof InitializingBean) {
      ((InitializingBean) bean).afterPropertiesSet();
   }
   return (T) bean;
}

以上就是JavaBeanInfo 和 Spring 之間有什么關系,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

秀山| 临桂县| 华阴市| 新竹市| 塔城市| 襄垣县| 长阳| 元江| 英山县| 姜堰市| 涞源县| 天柱县| 江都市| 同仁县| 晋江市| 蓝田县| 土默特左旗| 永川市| 山东省| 泽库县| 顺义区| 太仓市| 理塘县| 永登县| 博罗县| 洛南县| 五大连池市| 都安| 行唐县| 凉山| 堆龙德庆县| 噶尔县| 开远市| 龙川县| 漯河市| 双辽市| 西盟| 云南省| 正阳县| 安图县| 大埔区|