JavaBean:
JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设 计模式的公共方法将内部域暴露成员属性。众所周知,属性名称符合这种模式,其他Java 类可以通过自身机制发现和操作这些JavaBean 属性。编写javabean就是编写一个java的类,所以你只要会写类就能编写一个bean,这个类创建的一个对象称做一个bean。为了能让使用这个bean的应用程序构 建工具(比如JSP引擎)知道这个bean的属性和方法,只需在类的方法命名上遵守以下规则:1. 如果类的成员变量的名字是xxx,那么为了更改或获取成员变量的值,即更改或获取属性,在类中可以使用两个方法:getXxx(),用来获取属性xxx。setXxx(),用来修改属性xxx.。3. 类中访问属性的方法都必须是public的,一般属性是private的。4. 类中如果有构造方法,那么这个构造方法也是public的并且是无参数的。换句话说,javabean就是一个java的类,只不过这个类你要按上面提到的一些规则来写,按这些规则写了之后,这个javabean可以在程序里被方便的重用, 使开发效率提高。
我们又通常把javabean的实例对象称之为值对象(Value Object),因为这些bean中通常只有一些信息字段和存储方法,没有功能性方法。
一个JavaBean类可以不当JavaBean用,而当成普通类用。JavaBean实际就是一种规范,当一个类满足这个规范,这个类就能被其它特定的类调用。一个类 被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。去掉get前缀,然后取剩余部分,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的,比如getName() 去掉get后,剩余Name,第二个字母是小写的,因此首字母改成小写的,即name
内省:
通过反射的方式操作JavaBean的属性,jdk提供了PropertyDescription类来操作访问JavaBean的属性。
反射和内省的联系和区别:
反射可以操作不同的java类,内省只能通过反射来操作JavaBean,JavaBean类里面操作的都是成员变量,都是通过setXXX和getXXX方法来获取成员变量, 这样的类用内省来操作会更简单。
反射和内省就好比是军队和军队里的尖刀连。内省属于反射,是一种特殊的反射,专门用来操作JavaBean类的,是一种较为特殊的反射方法,更为快捷的 获相应的东西。
假设给你一个未知的JavaBean类,
1、通过普通反射查看该类自身方法,并打印出所有方法,根据查看判断后再次使用获取对应get、set方法
2、通过内省机制获取setter(),getter()方法来操作成员属性。
通过比较可以知道内省存在的意义在于更快捷的操作了JavaBean类对象的成员属性。内省和反射各有各的应用场景。
如何使用内省:
属性和有返回值的getter有关,有几个有返回值的getter就有几个属性。注意继承与Object类的getClass()方法
①通过类Introspector的getBeanInfo方法获取某个对象的BeanInfo信息。
②通过BeanInfo来获取属性的描述器(PropertyDescriptor)。
③通过这个属性描述器就可以获取某个属性对应的getter/setter方法。
④通过反射机制来调用这些方法。
Introspector类:
将JavaBean中的属性封装起来进行操作。在程序把一个类当做JavaBean来看,就是调用Introspector.getBeanInfo()方法,得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息,即属性的信息。
主要方法(都是静态方法):
public static BeanInfo getBeanInfo(Class<?> beanClass) 在 JavaBean 上进行内省,了解其所有属性、公开的方法和事件。
beanClass
- 将要分析的 bean 类BeanInfo类:
封装了JavaBean属性的信息。
主要方法:
PropertyDescriptor[] getPropertyDescriptors() 获得所有属性的描述,可以采用遍历BeanInfo的方法,来查找、设置类的属性。
PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:
1. getPropertyType(),获得属性的Class对象;
2. getReadMethod(),获得用于读取属性值的方法;//等同于getxxx()方法getWriteMethod(),获得用于写入属性值的方法;//等同于setxxx()方法 3. hashCode(),获取对象的哈希值;6.getName();//返回属性的名字
4. setReadMethod(Method readMethod),设置用于读取属性值的方法;
5. setWriteMethod(Method writeMethod),设置用于写入属性值的方法。示例代码:
<span style="white-space:pre"> </span>@Test public void test1() throws Exception { Class<?> c = Class.forName("com.qq.java.introspector.Student"); Constructor<?> con = c.getConstructor(); Student stu = (Student) con.newInstance(); //获取封装的属性信息 BeanInfo bf = Introspector.getBeanInfo(c); //获取PropertyDescriptor PropertyDescriptor[] pds = bf.getPropertyDescriptors(); //遍历属性 String property = null; for (PropertyDescriptor pd : pds) { if (!(property = pd.getName()).equals("class")) //注意会有Class对象 { //m等同于setName(String name),setAge(int age) Method m = pd.getWriteMethod(); if(property.equals("name")) { m.invoke(stu, "Jack"); } if(property.equals("age")) { m.invoke(stu, 10); } //m2等同于getName(),getAge(); Method m2 = pd.getReadMethod(); //因为getName(),getAge()没有参数,所以invoke方法只有调用者 System.out.println(m2.invoke(stu)); } } }
可以看出,内省操作比较繁琐的,所以Apache开发了一套简单、易用的API来操作Bean的属性——BeanUtils工具包。BeanUtils工具包:
下载:http://commons.apache.org/beanutils/
注意:应用的时候还需要一个logging包 http://commons.apache.org/logging/
关于BeanUtils工具包的使用留到下一篇再细细研究一下。