Java高新技术 JavaBean内省



Java高新技术  JavaBean内省


知识概要:

                (1)了解JavaBean内省

                (2)JavaBean的简单内省操作

                (3)使用BeanUtils来操作JavaBean

               

了解JavaBean内省


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类内部的 成员变量。
一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定需要带来一些额外的好 处,我们才会去了解和应用JavaBean!好处如下:
在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,

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



内省综合案例


演示用eclipse自动生成 ReflectPoint类的setter和getter方法。

直接new一个PropertyDescriptor对象的方式来让大家了解JavaBean API的价值,

先用一段代码读取JavaBean的属性,然后再用一段代码设置JavaBean的属性。

演示用eclipse将读取属性和设置属性的流水帐代码分别抽取成方法

只要调用这个方法,并给这个方法传递了一个对象、属性名和设置值,它就能完成属性修改的功能。

得到BeanInfo最好采用“obj.getClass()”方式,而不要采用“类名.class”方式,这样程序更通用。

采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性。在程序中把一个类当作JavaBean来

看,就是调用IntroSpector.getBeanInfo方法, 得到的BeanInfo对象封装了把这个类当作JavaBean看的结果信息
package cn.itheima.day1;

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 {
	public static void main(String[] args) throws Exception{
		ReflectPoint pt1 = new ReflectPoint(3,5);;
		
		String propertyName = "x";
		
		Object retVal = getProperty(pt1, propertyName);
		System.out.println(retVal);
		
		Object value = 7;
		setProperties(pt1, propertyName, value);
		
		System.out.println(BeanUtils.getProperty(pt1,"x"));
		BeanUtils.setProperty(pt1,"x","9");
		System.out.println(BeanUtils.getProperty(pt1,"x"));
		//java7新特性。
		//Map map =(name:"cuizhaojin",age:18);
		//BeanUtils.setProperty(map, "name", "cuizhao");
		BeanUtils.setProperty(pt1,"birthday.time","2014"); 

		String birthday = BeanUtils.getProperty(pt1,"birthday.time"); 

		System.out.println(birthday); 
		
		PropertyUtils.setProperty(pt1,"x",9);
		
		System.out.println(PropertyUtils.getProperty(pt1, "x").getClass());
		
		
	}

	private static void setProperties(Object 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 Exception
		/*throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
		Method methodGetX =pd.getReadMethod();
		Object retVal = methodGetX.invoke(pt1);*/{
		
		
		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;
	}
}


图例:


PropertyUtils类也可以操作对象的属性,但是与BeanUtils不同的是它不能进行自动类型转换。

例如Person类中的age属性为int类型,但是设置属性值的时候传入的参数就不可以是String类型。




如果设置成了String类型,那么将会报错。










posted @ 2014-06-01 16:14  博客园杀手  阅读(166)  评论(0编辑  收藏  举报