JavaBean操作の詳細


一、beanの紹介
Javaの反射では、すべてのクラスがクラス、すなわちClassクラスを抽象化され、プログラムの実行中にプロファイルを介してクラスを動的にロードできます.しかし、反射を使用する場合、パラメータ付きconstructorを呼び出すときに、コンストラクション関数が伝達するパラメータがどのようなタイプなのかを知らなければならないという前提があります.Methodを呼び出すときは、メンバー関数が入力するパラメータのタイプを知っておく必要があります.fieldを呼び出すときは、メンバー変数のタイプを知っておく必要があります.しかし、場合によっては、クラス内のメンバー属性の名前が外部に表示されない場合があります.この場合、メンバータイプの配列field[]しか得られません.正確な変数名が分からない場合は、正確な変数にナビゲートできません.彼はこの属性に公開された読み取り(get)、書き込みを提供した.(set)メソッドは、メソッド名とメソッド操作のオブジェクトに大きな関係がある場合がありますが、この関係が必ず成立するとは保証できません.また、get、setメソッドのみを提供し、変数名を提供しない場合もよくありますので、javaはこのような抽象をjavabeanクラスとし、javabeanクラスの操作はget、set関数の後ろの名前で「擬」します.変数の名前が出ます.この名前により,ある変数の値を正確に求めることができる.javabeanの操作は内省(introspector)によって行われる.
二、内省がJavaBean属性にアクセスする二つの方法:
BeanのプロパティをP r ettyDescriptorクラスで操作してIntrospectorクラスでBeanオブジェクトのBeanInfoを取得し、BeanInfoでプロパティの記述器(P r epertyDescriptor)を取得し、このプロパティ記述器でプロパティに対応するgetter/setterメソッドを取得し、反射メカニズムでこれらのメソッドを呼び出すことができます.
次に例を示します.
package reflect;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class TestBean {

    public static void main(String[] args) throws Exception {
        testProDes();
        testBeanInfo();
        testBeanInfo1();
        
    }
    
    static void testBeanInfo() throws Exception{
        Dog d = (Dog) Class.forName("reflect.Dog").newInstance();
        S  beanuitls    bean   tring myname = "name";    
        BeanInfo beanInfo = Introspector.getBeanInfo(Dog.class);//beaninfo   bean     
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for(PropertyDescriptor pd : propertyDescriptors){
            if(pd.getName().equals(myname)){
                Method m1 = pd.getWriteMethod();
                m1.invoke(d,"zhangsan");
                Method m2 = pd.getReadMethod();
                m2.invoke(d);
                System.out.println(d);
                break;
            }
        }
    }
    
    static void testProDes() throws Exception{
        Dog d = (Dog) Class.forName("reflect.Dog").newInstance();
        String myname = "name" ;//           string    ,             。
        PropertyDescriptor pd = new PropertyDescriptor(myname, Dog.class);//propertyDescriptor         
        
        Method m1 = pd.getWriteMethod();
        m1.invoke(d,"zhangsan");
        Method m2 = pd.getReadMethod();
        m2.invoke(d);
        System.out.println(d);
    }
    static void testBeanInfo1() throws Exception{
        Dog d = (Dog) Class.forName("reflect.Dog").newInstance();
        String myname = "name";    
        BeanInfo beanInfo = Introspector.getBeanInfo(Dog.class);//beaninfo   bean     
        MethodDescriptor[] mds = beanInfo.getMethodDescriptors();
        for(MethodDescriptor md : mds){
            String str = md.getName();
            if (str.matches("[gs]et.*")) {
                System.out.println(str);//  set/get     
            }  beanuitls    bean   
        }
    }

}

class Dog {
    private String n ;
    private int a ;
    
    public Dog(){
    }
    public Dog(String name,int age){
        this.n = name;
        this.a = age;
    }
    
    public String getName() {
        return n;
    }
    public void setName(String name) {
        this.n = name;
    }
    public int getAge() {
        return a;
    }
    public void setAge(int age) {
        this.a = age;
    }
    @Override
    public String toString(){
        return n + " : "+a;
    }
    
}

ここではわざとDogクラスのget/setメソッドと属性名定義を違います.しかし、内省を通じて、正確な内部属性の名前を知る必要はありません.get/setの名前を通じて、属性の設定と読み取りを実現することができます.
最初の関数は直接propertyDescriptorで属性記述子を導出し,read法でget対応methodを求め,write法でset対応methodを求め,methodの反射invoke関数で属性に対する操作を実現する.
2番目の関数は1番目の関数と同じ機能を実現するが,経路が異なり,まずintrospector静的手法でbeaninfoを導出し,beaninfoにはクラスに関するすべての情報が含まれ,beaninfoの手法でpropertyDescriptorを導出し,1番目の実装手法で属性に対する操作を実現する.
3番目の関数はmethoddescriporをテストし、このjavabeanクラスのすべてのget/setの方法を印刷します.
三、beanutilsツールパッケージ操作bean
Sun社の内省APIは煩雑すぎるため、Apache組織は多くの実際の開発中の応用シーンと結びつけて、簡単で使いやすいAPI操作Beanの属性--BeanUtils Beanutilsツールパッケージの常用類:BeanUtils PropertyUtils ConvertUtilsを開発した.regsiter(Converter convert,Class clazz)カスタムコンバータ
四、beanuitlsフレームワークを使用してbeanの属性を操作する
1.Studioクラスを作成するには:
package cn.itcast.beanutils;
import java.util.Date;
//javabean (  )
public class Student {
<span style="white-space:pre">	</span> private String name; //   get set        ,      ,     
<span style="white-space:pre">	</span> private int age;
<span style="white-space:pre">	</span> private Date birthday;
<span style="white-space:pre">	</span> 
<span style="white-space:pre">	</span> public String getName() {
<span style="white-space:pre">		</span> return name;
<span style="white-space:pre">	</span> }
<span style="white-space:pre">	</span> public void setName(String name) {
<span style="white-space:pre">		</span> this.name = name;
<span style="white-space:pre">	</span> }
<span style="white-space:pre">	</span> public int getAge() {
<span style="white-space:pre">		</span> return age;
<span style="white-space:pre">	</span> }
<span style="white-space:pre">	</span> public void setAge(int age) {
<span style="white-space:pre">		</span> this.age = age;
<span style="white-space:pre">	</span> }
<span style="white-space:pre">	</span> public Date getBirthday() {
<span style="white-space:pre">		</span> return birthday;
<span style="white-space:pre">	</span> }
<span style="white-space:pre">	</span> public void setBirthday(Date birthday) {
<span style="white-space:pre">		</span> this.birthday = birthday;
<span style="white-space:pre">	</span> }
<span style="white-space:pre">	</span> public String getX(){        //X    ,   get  set    
<span style="white-space:pre">		</span> return "X";
<span style="white-space:pre">	</span> }
 //           getClass,     5   
}
2、beanuitlsフレームワークを使用してbeanを操作するプロパティ
Personクラス:
package cn.itcast.beanutils;

import java.util.Date;

public class Person {
	private String name;
	private String password;
	private int age;
	private Date birthday;
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public String getName() {
		return name;
	}
	public String getPassword() {
		return password;
	}
	public int getAge() {
		return age;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public void setAge(int age) {
		this.age = age;
	}

}

操作Personコード:
package cn.itcast.beanutils;

import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Test;

//  beanUtils  bean    (    )
public class Demo1 {
	@Test
	public void test1() throws Exception{
		Person p=new Person();
		BeanUtils.setProperty(p, "age", 456);
		System.out.println(p.getAge());//456
	}
	@Test
	public void test2() throws Exception{
		String name="aaaa";
		String age="123";
		String password="pw";
				
		Person p=new Person();
		//  8         
		BeanUtils.setProperty(p, "name", name);
		BeanUtils.setProperty(p, "age", age);
		BeanUtils.setProperty(p, "password", password);
		
		System.out.println(p.getName());//aaaa
		System.out.println(p.getAge());//123
		System.out.println(p.getPassword());//pw

	}
	@Test
	public void test3() throws Exception{

		String birthday="1983-12-1";
		
		//        bean birthday   , beanUtils         
		//ConvertUtils.register(converter, clazz);
		ConvertUtils.register(new Converter(){
			
			public Object convert(Class type, Object value) {
				if(value==null) return null;
				if(!(value instanceof String)){
					throw new ConversionException("   String     ");
				}
				String str=(String)value;
				if(str.trim().equals("")) return null;
				SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd",Locale.US);
				try {
					return df.parse(str);
				} catch (ParseException e) {
					throw new RuntimeException(e);					
				}
			}
		}, Date.class);
		Person p=new Person();
		BeanUtils.setProperty(p, "birthday", birthday);
		System.out.println(p.getBirthday());//pw
		System.out.println("___"+BeanUtils.getProperty(p, "birthday"));
	}
	public void test5() throws Exception {
		Map map=new HashMap();
		map.put("name", "aaa");
		map.put("password", "123");
		map.put("brithday", "1980-09-09");
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		Person p=new Person();
		// map    bean  ,map    bean     
		BeanUtils.populate(p, map);
	}
}