本篇文章給大家分享的是有關(guān)JavaBeanInfo 和 Spring 之間有什么關(guān)系,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
青白江網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),青白江網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為青白江近千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的青白江做網(wǎng)站的公司定做!
在 Spring 中我們可以看到 BeanInfoFactory
該接口可以用來獲取 Class
對(duì)應(yīng)的 BeanInfo
對(duì)象,在 CachedIntrospectionResults
中也有相關(guān)的成員變量作為信息存儲(chǔ),其他地方還有筆者就不再這里都去搜索了,各位可以自行查閱。
BeanInfoFactory
public interface BeanInfoFactory { @Nullable BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException; }
CachedIntrospectionResults
public final class CachedIntrospectionResults { private final BeanInfo beanInfo; }
對(duì)于 Spring 來說操作 Bean 本身的內(nèi)容其實(shí)是操作各類屬性及其提供的方法。從筆者的角度來看 Bean 這個(gè)對(duì)象我覺得可以分成這三種,第一種是關(guān)于 Bean 屬性的,第二種是關(guān)于屬性操作的方法,第三種是提供外部操作的方法。就比如說現(xiàn)在有一個(gè) People
對(duì)象,存在多個(gè)屬性,我們?cè)趯?duì)這個(gè) Bean 對(duì)象定義的時(shí)候正常情況下我們會(huì)放入 private
修飾的屬性名,然后在提供 get
和 set
方法,如果有需要我們可以在通過非屬性操作相關(guān)的方法。本章就暫時(shí)是對(duì)前兩者的一個(gè)討論。
首先我們來定義一個(gè)基本的 Java Bean
public class Student { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
現(xiàn)在我們用了一個(gè)名字叫做 Student
的 Java 對(duì)象,我們來看這個(gè)對(duì)象的解釋
在 Student
對(duì)象中具有屬性 name
在 Student
對(duì)象中存在字段 name
我們通常情況下會(huì)有這兩種對(duì)象的定義解釋,那么這個(gè)定義解釋在 Java 中是如何對(duì)其進(jìn)行定義的呢。在 Java 中有一個(gè)接口叫做 java.beans.BeanInfo
這個(gè)接口是用來描述 Java Bean 的接口,下面我們來看這個(gè)接口中存在的方法
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 默認(rèn)事件索引
getPropertyDescriptors
:返回 Bean 屬性描述
getDefaultPropertyIndex
:返回 Bean 默認(rèn)的屬性索引
getMethodDescriptors
:返回 Bean 方法描述
getAdditionalBeanInfo
:返回其他的 Bean Info 信息
下面我們先來對(duì)接口中的返回值做一些介紹
BeanDescriptor
成員變量表
變量名稱 | 變量類型 | 變量說明 |
---|---|---|
beanClassRef | Reference<? extends Class<?>> | bean 的類 |
customizerClassRef | Reference<? extends Class<?>> | 自定義的類 |
PropertyDescriptor
成員變量表
變量名稱 | 變量類型 | 變量說明 |
---|---|---|
propertyTypeRef | Reference<? extends Class<?>> | 屬性類型 |
readMethodRef | MethodRef | 讀方法 |
writeMethodRef | MethodRef | 寫方法 |
propertyEditorClassRef | Reference<? extends Class<?>> | 屬性編輯類型 |
bound | boolean | |
constrained | boolean | |
baseName | String | |
writeMethodName | String | 寫方法名稱 |
readMethodName | String | 讀方法名稱 |
MethodDescriptor
成員變量表
變量名稱 | 變量類型 | 變量說明 |
---|---|---|
methodRef | MethodRef | 方法 |
paramNames | String[] | 參數(shù)名稱 |
params | List<WeakReference<Class<?>>> | 參數(shù)信息 |
parameterDescriptors | ParameterDescriptor | 參數(shù)描述 |
在了解了上述三個(gè)對(duì)象后我們來編寫一個(gè)測(cè)試用例,該測(cè)試用例主要用來獲取 BeanInfo
接口數(shù)據(jù)
BeanInfo
測(cè)試用例
@Test void classTest() throws IntrospectionException { Class clazz = Student.class; BeanInfo beanInfo = Introspector.getBeanInfo(clazz); System.out.println(); }
BeanInfo
信息
我們現(xiàn)在對(duì) BeanInfo
有了一定的了解,接下來我們要通過 BeanInfo
來創(chuàng)建一個(gè)對(duì)象,并給該對(duì)象進(jìn)行數(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(); // 確認(rèn)構(gòu)造函數(shù): 直接取無參構(gòu)造 Constructor constructor = confirmConstructor(declaredConstructors); // 通過構(gòu)造函數(shù)獲取對(duì)象 Object bean = constructor.newInstance(); // 為對(duì)象設(shè)置屬性 // 提取屬性描述 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { // 屬性名稱 String name = propertyDescriptor.getName(); if (prop.containsKey(name)) { // 寫函數(shù) Method writeMethod = propertyDescriptor.getWriteMethod(); // 從屬性表中獲取屬性名稱對(duì)應(yīng)的屬性值 Object proValue = prop.get(name); writeMethod.invoke(bean, proValue); } } return (T) bean; }
編寫這段代碼的主要邏輯如下
通過 Class
獲取 BeanInfo
接口
通過 BeanInfo
獲取 beanClass
通過 beanClass
提取構(gòu)造函數(shù)列表,從構(gòu)造函數(shù)列表中選擇一個(gè)具體的構(gòu)造函數(shù)(這里采用無參構(gòu)造的方式)
獲取屬性描述對(duì)象進(jìn)行屬性設(shè)置
編寫完成后我們來寫測(cè)試用例
@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ù)賦值,在上述過程中我們對(duì)于 beanClass
的獲取可以直接使用參數(shù)傳遞的 clazz
直接使用,可以不需要通過 BeanInfo
接口進(jìn)行二次調(diào)度。
下面我們來談一談 Spring 和 BeanInfo
的一些關(guān)聯(lián)。
相信各位在使用 Spring XML 模式的時(shí)候會(huì)編寫下面這樣的內(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)容,我們就簡(jiǎn)單的來看這個(gè) <bean>
標(biāo)簽,這個(gè)標(biāo)簽定義了一個(gè) class
屬性 和子標(biāo)簽 property
,我們可以通過一些 XML 解析工具得到這兩個(gè)對(duì)象,Spring 在這會(huì)將 class
屬性通過 ClassLoader
轉(zhuǎn)換成 Class
會(huì)將 property
轉(zhuǎn)換成對(duì)象 PropertyValue
,然后通過反射將對(duì)象創(chuàng)建出來。那么這段說明和我們所編寫的通過 BeanInfo
創(chuàng)建 Bean 有什么關(guān)系呢?我們可以思考下面幾個(gè)問題
知道了 BeanClass
如何才能創(chuàng)建對(duì)象呢?
知道屬性名稱和屬性值如何給對(duì)象賦值呢?
這兩個(gè)問題的答案很簡(jiǎn)單就是通過 Java 反射機(jī)制來進(jìn)行處理,那么具體怎么做呢?這個(gè)問題的答案其實(shí)就是我們前面所編寫的那段創(chuàng)建對(duì)象的代碼?;剡^頭我們來看這兩個(gè)問題
第一個(gè)問題的答案:創(chuàng)建對(duì)象其本質(zhì)是尋找構(gòu)造函數(shù)并調(diào)用
第二個(gè)問題的答案:通過找到寫方法將數(shù)據(jù)寫入
Spring 中無參構(gòu)造函數(shù)的調(diào)用
有參構(gòu)造的推論過程
在這里做出了兩種構(gòu)造函數(shù)的推論,當(dāng)完成推論構(gòu)造函數(shù)后就可以進(jìn)行對(duì)象創(chuàng)建及屬性賦值了。
屬性賦值相關(guān)的代碼就不在截圖了各位可以自行查找。
當(dāng)我們有了 getObject
這樣一個(gè)方法后,我們?cè)賮砜匆恍┥芷?,Spring 當(dāng)中的各類生命周期其實(shí)就是圍繞者這段代碼的前后來做各種補(bǔ)充操作,
比如 InitializingBean
這個(gè)接口的調(diào)用時(shí)在 Bean 創(chuàng)建完成后,那么我們可以在具體的位置上補(bǔ)充這樣一段
修改后的 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(); // 確認(rèn)構(gòu)造函數(shù): 直接取無參構(gòu)造 Constructor constructor = confirmConstructor(declaredConstructors); // 通過構(gòu)造函數(shù)獲取對(duì)象 Object bean = constructor.newInstance(); // 為對(duì)象設(shè)置屬性 // 提取屬性描述 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { // 屬性名稱 String name = propertyDescriptor.getName(); if (prop.containsKey(name)) { // 寫函數(shù) Method writeMethod = propertyDescriptor.getWriteMethod(); // 從屬性表中獲取屬性名稱對(duì)應(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)系,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
當(dāng)前題目:JavaBeanInfo和Spring之間有什么關(guān)系
URL分享:http://aaarwkj.com/article42/jejohc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、App開發(fā)、Google、網(wǎng)站建設(shè)、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)