内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

JavaBeanInfo和Spring之間有什么關(guān)系

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

青白江網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),青白江網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為青白江近千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的青白江做網(wǎng)站的公司定做!

Java Beans

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

  • BeanInfoFactory

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

  • CachedIntrospectionResults

    public final class CachedIntrospectionResults {
    	private final BeanInfo beanInfo;
    }

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

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

public class Student {
   private String name;

   public String getName() {
      return name;
   }

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

現(xiàn)在我們用了一個名字叫做 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 相關(guān)的事件信息

  • 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[]參數(shù)名稱
paramsList<WeakReference<Class<?>>>參數(shù)信息
parameterDescriptorsParameterDescriptor參數(shù)描述

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

  • BeanInfo 測試用例

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

JavaBeanInfo 和 Spring 之間有什么關(guān)系

我們現(xiàn)在對 BeanInfo 有了一定的了解,接下來我們要通過 BeanInfo 來創(chuàng)建一個對象,并給該對象進行數(shù)據(jù)賦值,下面我們來寫代碼

@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();
   // 獲取所有的構(gòu)造函數(shù)
   Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
   // 確認構(gòu)造函數(shù): 直接取無參構(gòu)造
   Constructor constructor = confirmConstructor(declaredConstructors);
   // 通過構(gòu)造函數(shù)獲取對象
   Object bean = constructor.newInstance();
   // 為對象設(shè)置屬性
   // 提取屬性描述
   PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
   for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
      // 屬性名稱
      String name = propertyDescriptor.getName();
      if (prop.containsKey(name)) {

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

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

  1. 通過 Class 獲取 BeanInfo 接口

  2. 通過 BeanInfo 獲取 beanClass

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

  4. 獲取屬性描述對象進行屬性設(shè)置

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

@Test
void beanInfoCreateBean() throws Exception {

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

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

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

下面我們來談一談 Spring 和 BeanInfo 的一些關(guān)聯(lián)。

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

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

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

  1. 知道了 BeanClass 如何才能創(chuàng)建對象呢?

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

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

  1. 第一個問題的答案:創(chuàng)建對象其本質(zhì)是尋找構(gòu)造函數(shù)并調(diào)用

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

  • Spring 中無參構(gòu)造函數(shù)的調(diào)用

JavaBeanInfo 和 Spring 之間有什么關(guān)系

  • 有參構(gòu)造的推論過程

JavaBeanInfo 和 Spring 之間有什么關(guān)系

在這里做出了兩種構(gòu)造函數(shù)的推論,當(dāng)完成推論構(gòu)造函數(shù)后就可以進行對象創(chuàng)建及屬性賦值了。

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

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

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

  • 修改后的 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();
   // 獲取所有的構(gòu)造函數(shù)
   Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
   // 確認構(gòu)造函數(shù): 直接取無參構(gòu)造
   Constructor constructor = confirmConstructor(declaredConstructors);
   // 通過構(gòu)造函數(shù)獲取對象
   Object bean = constructor.newInstance();
   // 為對象設(shè)置屬性
   // 提取屬性描述
   PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
   for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
      // 屬性名稱
      String name = propertyDescriptor.getName();
      if (prop.containsKey(name)) {

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

以上就是JavaBeanInfo 和 Spring 之間有什么關(guān)系,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

當(dāng)前題目:JavaBeanInfo和Spring之間有什么關(guān)系
URL分享:http://m.rwnh.cn/article42/jejohc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設(shè)網(wǎng)站維護、App開發(fā)、Google、網(wǎng)站建設(shè)、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護公司
龙泉市| 长垣县| 铁力市| 漳平市| 涞水县| 凌云县| 和林格尔县| 威信县| 简阳市| 长兴县| 诸城市| 山阳县| 延庆县| 道真| 太保市| 枞阳县| 阿克| 湘潭市| 敖汉旗| 琼结县| 安平县| 浏阳市| 吴江市| 池州市| 肥城市| 鄂托克旗| 兴山县| 永城市| 普兰店市| 巨野县| 内黄县| 抚州市| 乐清市| 阳江市| 固安县| 五台县| 德庆县| 云南省| 利川市| 盐源县| 潢川县|