原创文章,转载请注明: 转载自工学1号馆
内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。
JavaBean简介
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
为什么要使用JavaBean
在实际的开发过程中,通常会出现重复的代码或者段落,此时就会大大降低程序的可重用性并且浪费时间。使用JavaBean就可以大大简化程序的设计过程并且方便了其它程序的重复使用。
JavaBean在服务器端的应用具有非常强大的优势,非可视化的JavaBean可以非常好地实现控制逻辑、业务逻辑、表示层之间的分离,从而大大降低了它们之间的耦合度。非可视化的JavaBean现在多用于后台处理,这样会使系统具有一定的灵活性。
JavaBean是Java程序的一种,所使用的语法和其它类似的Java程序一致。在程序中使用JavaBean具有以下优点:
(1)可以实现代码的重复利用。
(2)易编写、易维护、易使用。
(3)它可以压缩在jar文件中,以更小的体积在网络中应用
(4)完全是Java语言编写,可以在任何安装了Java运行环境的平台上的使用,而不需要重新编译。
JavaBean的形式和要素
编写JavaBean就是编写一个Java的类,这个类创建的一个对象称做一个Bean。为了能让使用这个bean的应用程序构建工具(比如JSP引擎)知道这个bean的属性和方法,只需在类的方法命名上遵守以下规则:
(1)如果类的成员变量的名字是xxx,那么为了更改或获取成员变量的值,即更改或获取属性,在类中可以使用两个方法:
- getXXX():用来获取属性xxx。
- setXXX():用来修改属性xxx.。
(2)对于boolean类型的成员变量,即布尔逻辑类型的属性,允许使用”is”代替上面的”get”和”set”。
(3)类中方法的访问属性都必须是public的。
(4)类中如果有构造方法,那么这个构造方法也是public的并且没有参数。
JavaBean示例:
import java.io.Serializable;
public class JavaBeanDemo implements Serializable{
private int id;
private String name;
JavaBeanDemo(){}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,如果方法名为getId,中文意思即为获取id。去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
按照这样的规则,可以得出下面的实例:
setId()的属性名–>id
isLast()的属性名–>last
setCPU的属性名是什么?–>CPU
getUPS的属性名是什么?–>UPS
总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean!好处如下:
在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作.
JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,有一定难度,用内省这套api操作JavaBean比用普通类的方式更方便。
java内省实战
1、实现用eclipse自动生成 ReflectPoint类的setter和getter方法。
public class ReflectPoint {
private int x;
private int y;
public ReflectPoint(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
获得属性x的值并且设置x的值:
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class ReflectTest2 {
public static void main(String[] args) throws Exception{
ReflectPoint pt1 = new ReflectPoint(1, 2);
String propertyName = "x";
//直接调用JavaBean API
PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);
System.out.println(retVal);
Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(pt1, 3);
System.out.println(pt1.getX());
}
}
小技巧:用eclipse将读取属性和设置属性的流水帐代码分别抽取成方法,选中代码,右键选择–Refactor–>ExtractMothod–>… 重构后的代码如下:
private static void setProperty(ReflectPoint pt1, String propertyName,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName, pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, value);
}
private static Object getProperty(Object pt1,
String propertyName) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);
System.out.println(retVal);
return pd;
}
2、修改上面的代码,采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性。
思路:在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法, 得到的BeanInfo对象封装了把这个类当作JavaBean看的结果信息。代码如下:
private static Object getProperty(Object pt1,
String propertyName) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object retVal = null;
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodGetX = pd.getReadMethod();
retVal = methodGetX.invoke(pt1);
break;
}
}
return retVal;
}

Comments