原创文章,转载请注明: 转载自工学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