javabean Introspector
javaBean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有字段,且方法名符合某种规则。
如果聊个模块之间传递多个信息,可以将这些信息封装到javaBean中,这种javaBean的实例对象称之为值得对象(Value Object 简称VO),这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。javaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId()中文意思是设置id的值,至于你把它存储到那个变量上,不用管。如果方法为getId()表示获取id,至于是从哪个变量上获取的,也不重要。去掉set和get就是属性名,如果剩余部分的第二个字母是小写的,把剩余部分的首字母改成小写。
总之,一个类被当做javaBean使用时,javaBean的属性是根据其方法名推断出来的,他根本看不到类内部的成员变量。
一个符合javaBean特点的类可以当做普通类一样使用,但是把他当做javaBean使用时可定会带来一些好处。
在java EE开发中经常熬使用到javaBean;很多环境就要求按JavaBean的方式进行操作。
JDK提供了对JavaBean进行操作的一些API。这套API就称为内省(IntroSpector).如果你要自己通过getxxx方法来访问私有的xxx属性有一定的难度。用内省这同API操作JavaBean比用普通类要边界得多。
例如:
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class IntroSpectorTest1 {
public static void main(String[] args)throws Exception {
MyPointmpt1 = new MyPoint(5,8);
String propertyName = "x";
/*同过PropertyDescriptor类来获取javaBean的setter和getter方法,在用获得的方法来存取相应的属性
构造方法PropertyDescriptor的第一个参数 String propertyName表示的是要处理的javaBean的属性,第
二个参数表示的是,对相应的类 */
PropertyDescriptor pd = newPropertyDescriptor(propertyName,mpt1.getClass());
//获得对 propertyName属性的读方法即getter方法
Method methodGetX =pd.getReadMethod();
//将获得的getter作用于MyPointlei的mpt1对象上
Object retval = methodGetX.invoke(mpt1, null);
System.out.println(retval);
//获得对 propertyName属性的读方法即setter方法
Method methodSetX = pd.getWriteMethod();
//通过的到的setter方法设置Mypoint的mpt1对象propertyName属性值
methodSetX.invoke(mpt1, 36);
System.out.println(mpt1);
}
}
运行结果:
5
36::8
这里我们可以将读取和设置值分别抽取成两个独立的方法,用Eclipse的功能很容易就尅办到
//、设置某个对象的属性值
private static void setProperty(MyPoint myPoint, String propertyName,
Object value) throwsIntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd = newPropertyDescriptor(propertyName,myPoint.getClass());
Method methodSetY = pd.getWriteMethod();
methodSetY.invoke(myPoint, value);
}
//获得某个对象的某个属性值
private static ObjectgetProperty(Object myPoint, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
PropertyDescriptor pd = newPropertyDescriptor(propertyName,myPoint.getClass());
Method methodGetY = pd.getReadMethod();
Object retval = methodGetY.invoke(myPoint,null);
return retval;
这样我们就可以对任何一个符合javaBean的类进行内省操作了。
我们还可以同过Introspector和BeanInfo来实现以上操作Introspector类的getBeanInfo(Class<?>)方法可以将类转换成javaBean类型,封装后称为BeanInfo类的实例对象,BeanInfo的getPropertyDescriptors可以获取类的所有属性,所以哟啊得到某一个特定的属性,就必须遍历对比
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class IntroSpectorTest3 {
public static void main(String[] args)throws Exception{
MyPoint mpt1 = new MyPoint(22,33);
String propertyName = "x";
/*Introspector类的getBeanInfo(Class<?>)方法可以将类转换成javaBean类型,
封装后称为BeanInfo类的实例对象,BeanInfo的getPropertyDescriptors可以获取
类的所有属性,所以哟啊得到某一个特定的属性,就必须遍历对比*/
BeanInfo beanInfo = Introspector.getBeanInfo(mpt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
if(pd.getName().equals(propertyName)){
Method methodGetX = pd.getReadMethod();
Object retval = methodGetX.invoke(mpt1, null);
System.out.println(retval);
Method methodSetX= pd.getWriteMethod();
methodSetX.invoke(mpt1, 11111);
System.out.println(mpt1);
}
}
}
}
}
我们还可以通过Appache提供的BeanUtils工具类和PropertyUtils工具类来操作javaBean,而且工能更强大。BeanUtils和PropertyUtils的区别在于出力的数据的形式,BeanUtils是以相应类型的对象字符串形式处理数据,PropertyUtils是以相应的类型的对象处理数据
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
public class IntroSpectorTest4 {
public static void main(String[] args)throws Exception {
//用BeanUtils包来操作javaBean
MyPoint mpt1 = new MyPoint(4,7);
System.out.println(BeanUtils.getProperty(mpt1,"x") + " " + BeanUtils.getProperty(mpt1,"y"));
BeanUtils.setProperty(mpt1, "x", "333");
BeanUtils.setProperty(mpt1, "y", "333");
System.out.println(BeanUtils.getProperty(mpt1,"x") + " " + BeanUtils.getProperty(mpt1,"y"));
System.out.println(BeanUtils.getProperty(mpt1,"birthday.time"));
//如果属性也是一个JavaBean类则可以对此属性进行内省操作
BeanUtils.setProperty(mpt1, "birthday.time","1222222222221");//此处传入的必须是相应的字符串形式的设置值
System.out.println(BeanUtils.getProperty(mpt1,"birthday.time"));
System.out.println(BeanUtils.getProperty(mpt1,"birthday"));
//用PropertyUtils包来操作javaBean
PropertyUtils.setProperty(mpt1, "x", 999);//次数传入的值必须是相应的类型的对象,
System.out.println(PropertyUtils.getProperty(mpt1,"x"));
//BeanUtils和PropertyUtils的区别在于出力的数据的形式,BeanUtils是以相应类型的对象字符串形式处理数据,PropertyUtils是以相应的类型的对象处理数据
}
}