程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 用Introspector提取BeanInfo

用Introspector提取BeanInfo

編輯:關於JAVA

當我們拖放一個Bean的調色板並將它放入到窗體中時,一個Bean的最關鍵的部分的規則發生了。應用程序構建工具必須可以創建Bean(如果它是默認的構建器的話,它就可以做)然後,在此范圍外訪問Bean的源代碼,提取所有的必要的信息以創立屬性表和事件處理器。
解決方案的一部分在11章結尾部分已經顯現出來:Java 1.1版的映象允許一個匿名類的所有方法被發現。這完美地解決了Bean的難題而無需我們使用一些特殊的語言關鍵字像在其它的可視化編程語言中所需要的那樣。事實上,一個主要的原因是映象增加到Java 1.1版中以支持Beans(盡管映象同樣支持對象串聯和遠程方法調用)。因為我們可能希望應用程序構建工具的開發者將不得不映象每個Bean並且通過它們的方法搜索以找到Bean的屬性和事件。
這當然是可能的,但是Java的研制者們希望為每個使用它的用戶提供一個標准的接口,而不僅僅是使Bean更為簡單易用,不過他們也同樣提供了一個創建更復雜的Bean的標准方法。這個接口就是Introspector類,在這個類中最重要的方法靜態的getBeanInfo()。我們通過一個類處理這個方法並且getBeanInfo()方法全面地對類進行查詢,返回一個我們可以進行詳細研究以發現其屬性、方法和事件的BeanInfo對象。
通常我們不會留意這樣的一些事物——我們可能會使用我們大多數的現成的Bean,並且我們不需要了解所有的在底層運行的技術細節。我們會簡單地拖放我們的Bean到我們窗體中,然後配置它們的屬性並且為事件編寫處理器。無論如何它都是一個有趣的並且是有教育意義的使用Introspector來顯示關於Bean信息的練習,好啦,閒話少說,這裡有一個工具請運行它(我們可以在forgbean子目錄中找到它):
 

//: BeanDumper.java
// A method to introspect a Bean
import java.beans.*;
import java.lang.reflect.*;

public class BeanDumper {
  public static void dump(Class bean){
    BeanInfo bi = null;
    try {
      bi = Introspector.getBeanInfo(
        bean, java.lang.Object.class);
    } catch(IntrospectionException ex) {
      System.out.println("Couldn't introspect " +
        bean.getName());
      System.exit(1);
    }
    PropertyDescriptor[] properties = 
      bi.getPropertyDescriptors();
    for(int i = 0; i < properties.length; i++) {
      Class p = properties[i].getPropertyType();
      System.out.println(
        "Property type:\n  " + p.getName());
      System.out.println(
        "Property name:\n  " + 
        properties[i].getName());
      Method readMethod = 
        properties[i].getReadMethod();
      if(readMethod != null)
        System.out.println(
          "Read method:\n  " + 
          readMethod.toString());
      Method writeMethod = 
        properties[i].getWriteMethod();
      if(writeMethod != null)
        System.out.println(
          "Write method:\n  " +
          writeMethod.toString());
      System.out.println("====================");
    }
    System.out.println("Public methods:");
    MethodDescriptor[] methods =
      bi.getMethodDescriptors();
    for(int i = 0; i < methods.length; i++)
      System.out.println(
        methods[i].getMethod().toString());
    System.out.println("======================");
    System.out.println("Event support:");
    EventSetDescriptor[] events = 
      bi.getEventSetDescriptors();
    for(int i = 0; i < events.length; i++) {
      System.out.println("Listener type:\n  " +
        events[i].getListenerType().getName());
      Method[] lm = 
        events[i].getListenerMethods();
      for(int j = 0; j < lm.length; j++)
        System.out.println(
          "Listener method:\n  " +
          lm[j].getName());
      MethodDescriptor[] lmd = 
        events[i].getListenerMethodDescriptors();
      for(int j = 0; j < lmd.length; j++)
        System.out.println(
          "Method descriptor:\n  " +
          lmd[j].getMethod().toString());
      Method addListener = 
        events[i].getAddListenerMethod();
      System.out.println(
          "Add Listener Method:\n  " +
        addListener.toString());
      Method removeListener =
        events[i].getRemoveListenerMethod();
      System.out.println(
        "Remove Listener Method:\n  " +
        removeListener.toString());
      System.out.println("====================");
    }
  }
  // Dump the class of your choice:
  public static void main(String[] args) {
    if(args.length < 1) {
      System.err.println("usage: \n" +
        "BeanDumper fully.qualified.class");
      System.exit(0);
    }
    Class c = null;
    try {
      c = Class.forName(args[0]);
    } catch(ClassNotFoundException ex) {
      System.err.println(
        "Couldn't find " + args[0]);
      System.exit(0);
    }
    dump(c);
  }
} ///:~


BeanDumper.dump()是一個可以做任何工作的方法。首先它試圖創建一個BeanInfo對象,如果成功地調用BeanInfo的方法,就產生關於屬性、方法和事件的信息。在Introspector.getBeanInfo()中,我們會注意到有一個另外的自變量。由它來通知Introspector訪問繼承體系的地點。在這種情況下,它在分析所有對象方法前停下,因為我們對看到那些並不感興趣。
因為屬性,getPropertyDescriptors()返回一組的屬性描述符號。對於每個描述符號我們可以調用getPropertyType()方法徹底的通過屬性方法發現類的對象。這時,我們可以用getName()方法得到每個屬性的假名(從方法名中提取),getname()方法用getReadMethod()和getWriteMethod()完成讀和寫的操作。最後的兩個方法返回一個可以真正地用來調用在對象上調用相應的方法方法對象(這是映象的一部分)。對於公共方法(包括屬性方法),getMethodDescriptors( )返回一組方法描述字符。每一個我們都可以得到相當的方法對象並可以顯示出它們的名字。
對於事件而言,getEventSetDescriptors()返回一組事件描述字符。它們中的每一個都可以被查詢以找出接收器的類,接收器類的方法以及增加和刪除接收器的方法。BeanDumper程序打印出所有的這些信息。
如果我們調用BeanDumper在Frog類中,就像這樣:
java BeanDumper frogbean.Frog
它的輸出結果如下(已刪除這兒不需要的額外細節):
 

class name: Frog
Property type:
  Color
Property name:
  color
Read method:
  public Color getColor()
Write method:
  public void setColor(Color)
====================
Property type:
  Spots
Property name:
  spots
Read method:
  public Spots getSpots()
Write method:
  public void setSpots(Spots)
====================
Property type:
  boolean
Property name:
  jumper
Read method:
  public boolean isJumper()
Write method:
  public void setJumper(boolean)
====================
Property type:
  int
Property name:
  jumps
Read method:
  public int getJumps()
Write method:
  public void setJumps(int)
====================
Public methods:
public void setJumps(int)
public void croak()
public void removeActionListener(ActionListener)
public void addActionListener(ActionListener)
public int getJumps()
public void setColor(Color)
public void setSpots(Spots)
public void setJumper(boolean)
public boolean isJumper()
public void addKeyListener(KeyListener)
public Color getColor()
public void removeKeyListener(KeyListener)
public Spots getSpots()
======================
Event support:
Listener type:
  KeyListener
Listener method:
  keyTyped
Listener method:
  keyPressed
Listener method:
  keyReleased
Method descriptor:
  public void keyTyped(KeyEvent)
Method descriptor:
  public void keyPressed(KeyEvent)
Method descriptor:
  public void keyReleased(KeyEvent)
Add Listener Method:
  public void addKeyListener(KeyListener)
Remove Listener Method:
  public void removeKeyListener(KeyListener)
====================
Listener type:
  ActionListener
Listener method:
  actionPerformed
Method descriptor:
  public void actionPerformed(ActionEvent)
Add Listener Method:
  public void addActionListener(ActionListener)
Remove Listener Method:
  public void removeActionListener(ActionListener)
====================


這個結果揭示出了Introspector在從我們的Bean產生一個BeanInfo對象時看到的大部分內容。我們可注意到屬性的類型和它們的名字是相互獨立的。請注意小寫的屬性名。(當屬性名開頭在一行中有超過不止的大寫字母,這一次程序就不會被執行。)並且請記住我們在這裡所見到的方法名(例如讀和與方法)真正地從一個可以被用來在對象中調用相關方法的方法對象中產生。
通用方法列表包含了不相關的事件或者屬性,例如croak()。列表中所有的方法都是我們可以有計劃的為Bean調用,並且應用程序構建工具可以選擇列出所有的方法,當我們調用方法時,減輕我們的任務。
最後,我們可以看到事件在接收器中完全地分析研究它的方法、增加和減少接收器的方法。基本上,一旦我們擁有BeanInfo,我們就可以找出對Bean來說任何重要的事物。我們同樣可以為Bean調用方法,即使我們除了對象外沒有任何其它的信息(此外,這也是映象的特點)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved