您的位置:首页 > 编程语言 > Java开发

Java高新技术之JavaBean(内省 IntroSpector)

2012-01-12 09:51 531 查看
一、Javabean
1.JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。

如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,大家觉得这些方法的名称叫什么好呢?JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,至于你把它存到哪个变量上,用管吗?如果方法名为getId,中文意思即为获取id,至于你从哪个变量上取,用管吗?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。

setId()的属性名---->id
isLast()的属性名---->last
setCPU的属性名是什么?---->CPU
getUPS的属性名是什么?---->UPS

总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。

2.一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean!好处如下:

在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地!
JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,怎么做,有一定难度吧?用内省这套api操作JavaBean比用普通类的方式更方便。

二、PropertyDescriptor BeanInfo BeanUtils PropertyUtils操作javabean 见代码所示:
import java.util.Date;

public class Person
{
private String name;
private int age;
private Date birthday=new Date();//这里要创建对象!

public Date getBirthday()
{
return birthday;
}
public void setBirthday(Date birthday)
{
this.birthday = birthday;
}
public Person(String name, int age)
{
super();
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;
}

@Override
public String toString()
{
return this.name+" "+this.age+" "+this.birthday;
}

}
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

public class IntrospectorTest
{

/**
* 各种类操作javabean
*/
public static void main(String[] args)throws Exception
{
Person p=new Person("张三",23);
String propertyName="name";
//1.以下使用PropertyDescriptor操作javabean
getProperty(p, propertyName);

Object val="张凯";
setProperty(p, propertyName, val);

//2.以下使用BeanInfo操作javabean
getPropertyByBeanInfo(p, propertyName);

//3.以下使用BeanUtils操作javabean。
BeanUtils.setProperty(p, propertyName,"李四" );
//这是属性链,birthday是Date类型的,Date中有setTime(long time)方法
BeanUtils.setProperty(p, "birthday.time","11111");
System.out.println(BeanUtils.getProperty(p, "birthday.time"));
//BeanUtils操作中参数是String类型的 返回结果也是String类型
System.out.println(BeanUtils.getProperty(p, "birthday.time").getClass().getName());

//4.PropertyUtils操作javabean
PropertyUtils.setProperty(p, "name", "lily");
PropertyUtils.setProperty(p, "age", 30);//传入是是int
System.out.println(PropertyUtils.getProperty(p, "age").getClass().getName());//返回是Integer
PropertyUtils.setProperty(p, "birthday.time", 10000);
System.out.println(p);

}
public static void getPropertyByBeanInfo(Person p, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException
{
BeanInfo beanInfo=Introspector.getBeanInfo(p.getClass());
PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
//遍历数组找到指定属性
for(PropertyDescriptor pd:pds)
{
if(pd.getName().equals(propertyName))
{
System.out.println(pd.getReadMethod().invoke(p));
break;
}
}
}
//设置属性方法
public static void setProperty(Person p, String propertyName, Object val)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException
{
PropertyDescriptor pd1=new PropertyDescriptor(propertyName,p.getClass());
Method methodSet=pd1.getWriteMethod();
methodSet.invoke(p, val);//调用set方法把name值设置为“张凯”
System.out.println(p);
}

//得到属性方法
private static void getProperty(Person p, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException
{
//获取javaBean的属性描述
PropertyDescriptor pd=new PropertyDescriptor(propertyName,p.getClass());
//得到方法
Method methodGet=pd.getReadMethod();
System.out.println(methodGet.invoke(p));//调用方法
}

}


三、其他

用struts的迭代标签不能迭代出枚举元素的属性,而用jstl的迭代标签则可以。采用BeanUtils去获取带有抽象方法的枚举类的成员对象的属性时,会出现错误,要自己用内省加暴力反射方式才可以获取。主要原因是枚举类的抽象子类不是public类型的。
public static void main(String[] args) {
// TODO Auto-generated method stub
/*System.out.println(
PropertyUtils.getProperty(Sex.NONE, "title"));*/

Object bean = Sex.NONE;
BeanInfo beanInfo = null;
try {
beanInfo = Introspector.getBeanInfo(bean.getClass());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor property:properties)
{
if(property.getName().equals("title"))
{
Method method = property.getReadMethod();
method.setAccessible(true);
Object retVal;
try {
retVal = method.invoke(bean, null);
System.out.println(retVal);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: