Java内省メカニズムIntroSpector

3099 ワード

内省(IntroSpector)は、Java言語によるJavaBeanクラスの属性、イベントの処理方法である.たとえばクラスAに属性名がある場合、getName、setNameで値を取得したり、新しい値を設定したりすることができます.getName/setNameでnameプロパティにアクセスするのがデフォルトのルールです.Javaには、ある属性にアクセスするためのgetter/setterメソッドが提供されています.これらのAPIにより、パッケージjavaに格納されているこのルールを理解する必要がありません.beansで.
 
一般的には、クラスIntrospectorのgetBeanInfoメソッドでオブジェクトのBeanInfo情報を取得し、BeanInfoでプロパティの記述器(PropertyDescriptor)を取得し、このプロパティ記述器でプロパティに対応するgetter/setterメソッドを取得し、反射メカニズムでこれらのメソッドを呼び出すことができます.
 
また、javabeanのインスタンスオブジェクトを値オブジェクト(Value Object)と呼ぶのが一般的です.これらのbeanには通常、いくつかの情報フィールドと格納方法しかなく、機能的な方法がないからです.
JavaBeanクラスは、JavaBeanではなく、通常のクラスとして使用できます.JavaBeanは、クラスがこの仕様を満たすと、他の特定のクラスに呼び出される仕様です.1つのクラスがjavaBeanとして使用される場合、JavaBeanのプロパティはメソッド名に基づいて推定され、javaクラス内部のメンバー変数はまったく見えません(プロパティがなくても大丈夫ですが、IntroSpectorは仮定的な操作です).set接頭辞を外し、残りの部分を取り、残りの部分の2番目のアルファベットが小文字であれば、残りの部分の頭文字を小さくします.
 
反射に用いるクラスを導入する必要があるほか、内省で導入する必要があるクラスは以下のようにjavaに属する.beansパッケージのクラスは、自分でプログラムを書くときにも、対応するパッケージやクラスを導入することを忘れてはいけません.次のコード・スライスは、JavaBeanクラスの属性を設定するキー・コードです.
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by wangpl on 1/16/15.
 */
public class Test {
    public static void main(String[] args) throws IntrospectionException, InvocationTargetException,
            IllegalAccessException {
        User user =new User("zhangsan", 21);
        String propertyName = "name";
        PropertyDescriptor pd=new PropertyDescriptor(propertyName, user.getClass());//           
        Method readMethod = pd.getReadMethod();//      
        Object invoke = readMethod.invoke(user, null);//       
        System.out.println("  :" + invoke);
        pd.getWriteMethod().invoke(user, "lisi");
        invoke = readMethod.invoke(user, null);
        System.out.println("  :" + invoke);

        //     Bean   
//        BeanInfo beanInfo= Introspector.getBeanInfo(user.getClass());
        BeanInfo beanInfo= Introspector.getBeanInfo(user.getClass(), Object.class);//  Object       ,             

        System.out.println("      :");
        PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();//          
        for (PropertyDescriptor propertyDescriptor: pds) {
            System.out.println(propertyDescriptor.getName());
        }
        System.out.println("      :");
        for (MethodDescriptor methodDescriptor: beanInfo.getMethodDescriptors()) {
            System.out.println(methodDescriptor.getName());
//            Method method = methodDescriptor.getMethod();
        }
    }
}
public class User {
    private String name;
    private int age;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

Apache BeanUtilsは、カスケード属性操作など、より高度なBean操作機能を備えています.