內省機制(操作javaBean的資訊)

一樂樂發表於2022-02-23

內省機制(操作javaBean的資訊)

----是不是聯想到了反射機制了哈,這兩者有什麼區別呢?


1、內省機制和反射機制的聯絡

■ 其實內省機制也是通過反射來實現的,而反射是對一切類都適合去動態獲取類的資訊,而內省機制是sun公司針對特殊的類---javaBean推出的技術。內省機制就是用來獲取javabean的資訊的。

2、什麼是javaBean?

■ 比較官方的描述:javaBean 是一種java 語言寫成的可重用的元件(類)。

■ 簡單理解:就是一種特殊類,遵循特定的規範,遵循的規範如下:

  • 必須使用 public 修飾(javabean)類

  • (javabean)類必須有公共無參構造器

  • 包含有屬性的操作手段(獲取屬性值或給屬性賦值---getter/setter)

■ javaBean 可以很複雜,也可以很簡單。

  • javabean 可以有的資訊(不是必備):方法Method、事件event、屬性property

  • 補充一下屬性property:表示狀態,不是欄位,是欄位的操作方法getter、setter方法決定的,判斷屬性看getter/setter

□ 複雜的javabean擁有了事件、屬性、方法,例如UI(button、panel、window類);

□ 簡單的javabean,最簡單最常用的有實體類domain-包含了屬性和操作屬性的getter、setter方法,還有dao、service元件,封裝資料,運算元據庫,邏輯運算等。


3、內省機制(自省機制)的作用:就是用來檢視和操作javaBean的資訊(屬性、方法、事件)

--------一般常用來操作簡單的javaBean(domain類)的屬性。

(1)獲取屬性名或屬性型別

(2)設定屬性值或獲取屬性值-通過反射呼叫setter或getter方法(setter/getter)


4、內省機制的核心類---Introspector

  • 注意核心類在哪個包,例如反射-Class在lang包裡,內省的Introspector在beans包裡

  • 抓住核心類Introspector(學習的突破口),順騰摸瓜,例如反射抓住核心類Class,然後順藤摸瓜,獲得構造器Constructor、方法Method;

  • 我們知道javaBean可以具有屬性、事件、方法,而操作javabean的內省機制,它的核心類Introspector就是操作javaBean的屬性、事件、方法。


5、Introspector(核心類、學習內省機制的突破口、學習操作javaBean的學習入口)---操作javaBean

  • 第一步就是先得到該javaBean:【在突破口中:得到javaBean的描述物件BeanInfo物件
    • 方法getBeanInfo的引數是該javaBean的位元組碼,結果是得到javaBean的資訊---BeanInfo物件(javaBean的描述物件)

image

  • 第二個突破口擁有javaBean的一切的BeanInfo:【在突破口中:得到javaBean的屬性描述器PropertyDescriptor
    • 方法getPropertyDescriptors(),結果是得到javaBean的屬性資訊---PropertyDescriptor屬性陣列物件(javaBean的屬性描述器物件)

image

  • 第三個突破口擁有javaBean的屬性的一切的PropertyDescriptor:【在突破口中:得到關於屬性的操作
    • 屬性描述器是陣列----遍歷

image


6、內省機制操作javaBean的屬性程式碼如下:

	@Test
	public void testIntrospector() throws Exception {
		//1、通過突破口(核心類Introspector)獲取javaBean描述物件BeanInfo
		BeanInfo beanInfo = Introspector.getBeanInfo(Person.class,Object.class);
		//2、獲取javaBean中的屬性描述器
		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
		
		//建立一個Person物件
		Person person = new Person();
		for (PropertyDescriptor pd : pds) {//遍歷陣列描述器陣列
			//3-1、獲取當前的屬性的屬性名
			System.out.println("當前屬性的屬性名是:" +pd.getName());
			System.out.println("當前屬性的getter方法是:" +pd.getReadMethod());
			System.out.println("當前屬性的setter方法是:" +pd.getWriteMethod());
			if("name".equals(pd.getName())) {//若當前屬性名是name【不能直接使用setName方法,因為反射的時候並不知道是哪個具體的方法】
				Method setter = pd.getWriteMethod();//3-2、獲取setter方法
				setter.invoke(person, "shan");//設定當前person物件的name值為shan
			}	
		}
	}

相關文章