内省的简单操作(Introspector)
1. JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则
2. 如果要在两个模板之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。去掉set或者get前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小写的。总之,一个类被当做javabean使用时,javabean的属性是根据方法名推断出来的,它根本看不到java类的内部成员变量。
3. 一个符合javabean特点的类可以当做一个普通类一样,但把它当做javabean用肯定需要带来一些额外的好处。如下:
在java EE开发中,经常要使用到javabean。很多环境就要求按javabean方式进行操作
JDK中提供了对javabean进行操作的一些api,这套api称为内省。如果要你自己去通过getX方法来方位私有的想,怎么做?有一定的难度,所以用用内省这套api操作javabean比用普通类的方式更为方便。
以下是采用的是顺序的写法
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
publicclassIntrospectorDemo1 {
publicstaticvoid main(String[] args)throws Exception {
ReflectPointrp = newReflectPoint(3, 5);
StringpropertyName = "x";
//内省的api,属性标记
PropertyDescriptorpd = newPropertyDescriptor(propertyName, rp.getClass());
//得到x的读方法,也就是get方法
MethodmethodGetX = pd.getReadMethod();
//不清楚返回值的类型,所以使用Object,执行invoke方法
ObjectretVal = methodGetX.invoke(rp);
System.out.println(retVal);
PropertyDescriptorpd2 = newPropertyDescriptor(propertyName, rp.getClass());
MethodmethodSetX = pd2.getWriteMethod();
methodSetX.invoke(rp,8);
//使用普通类的方法来打印数据,为了简便,以上是使用内省
System.out.println(rp.getX());
}
}
//将以上的代码抽取为方法
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
publicclassIntrospectorDemo1 {
publicstaticvoid main(String[] args)throws Exception {
ReflectPointrp = newReflectPoint(3, 5);
//此变量时表示需要获取的是哪个字段
/**
* 如果不采用内省,则会使用
* x -> X -> getX-> methodGetX->
*/
StringpropertyName = "x";
//内省的api,属性标记
ObjectretVal = getProperty(rp, propertyName);
System.out.println(retVal);
Objectvalue = 8;
setProperty(rp,propertyName, value);
//使用普通类的方法来打印数据,为了简便,以上是使用内省
System.out.println(rp.getX());
}
/**
*
* @param rp javabean的那个类
* @param propertyName javabean中需要操作的数据(x,y)
* @param value 需要更改的javabean中的数据
* @throws IntrospectionException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
privatestaticvoidsetProperty(ReflectPoint rp, String propertyName,
Objectvalue) throwsIntrospectionException,
IllegalAccessException,InvocationTargetException {
PropertyDescriptorpd2 = newPropertyDescriptor(propertyName, rp.getClass());
MethodmethodSetX = pd2.getWriteMethod();
methodSetX.invoke(rp,value);
}
/**
*
* @param rp javabean的那个类
* @param propertyName javabean中需要操作的数据(x,y)
* @return
* @throws IntrospectionException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
privatestatic ObjectgetProperty(Object rp, String propertyName)
throws IntrospectionException,IllegalAccessException,
InvocationTargetException{
PropertyDescriptorpd = newPropertyDescriptor(propertyName, rp.getClass());
//得到x的读方法,也就是get方法
MethodmethodGetX = pd.getReadMethod();
//不清楚返回值的类型,所以使用Object,执行invoke方法
ObjectretVal = methodGetX.invoke(rp);
return retVal;
}
}
内省的复杂操作
以上是较为简单的一种方法,还有一种更为复杂的方法,通过beaninfo来得到需要操作的对象
privatestatic ObjectgetProperty1(Objectrp, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
ObjectretVal = null;
//Introspector这个类中有一个方法getBeanInfo可以返回javabean类的一个beaninfo的
//数据,通过beaninfo来得到需要内省的属性描述,返回的是一个PropertyDescriptor的数组
//然后在找到需要内省的那个字段(x),进而在得到那个字段的getReadMethod(也就是get方法)
//最后在执行那个方法,得到所需要的数据
BeanInfobeanInfo = Introspector.getBeanInfo(rp.getClass());
PropertyDescriptor[]pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd:pds) {
if(pd.getName().equals(propertyName)){
MethodmethodGetX = pd.getReadMethod();
retVal= methodGetX.invoke(rp);
break;
}
}
return retVal;
}