zoukankan      html  css  js  c++  java
  • 基础加强____【内省JavaBean】【BeanUtils框架】



    "内省"(IntroSpector)--> 了解"JavaBean"
    	"*"JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类的方法主要用于访问私有字段
    		且其方法符合一定的命名规则: getXxx() setXxx(),可以通过方法名推断其功能
    	"*"如果在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象
    	(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,
    	则需要通过一些相应的方法来访问,JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。
    	"*"可以吧javaBean 当做普通的类来使用,但JavaBean能够带来一些额外的好处
    		首先,JavaBean是Java EE开发中的应用规范
    		JDK提供了一些对JavaBean进行操作的API"内省",比按照普通的类操作更方便
    	eclipse可以通过右键菜单source生成setter & getter方法	
    	用内省的方式来读取JavaBean的属性
    
    内省综合案例
    	演示用eclipse自动生成ReflectPoint类 的setter & getter方法
    	创建一个 PropertyDescriptor 对象来获取该属性的描述,对setter & getter进行重构
    	用eclipse将读取属性和设置属性方法分别抽取成方法
    		只要调用这个方法,并对这个方法传递一个 对象&属性名&设置值,就能完成属性修改的功能
    		得到BeanInfo的方式 obj.getClass() 比 类名.class 更通用
    	
    相比较为复杂的方法(内省类)
    	采用遍历BeanInfo的所有属性来查找和设置某个ReflectPoint对象的x属性,在程序中把一个类当做JavaBean来看待。
    	调用 Introspector.getBeanInfo方法,得到BeanInfo对象,该对象封装了把这个类当做JavaBean的信息
    	
    
    "BeanUtils 框架"
    	使用BeanUtils开源框架来操作JavaBean,BeanUtils框架非常有用
    	首先将该框架的jar包导入到eclipse工程中
    	下载BeanUtil包,将beanutils.jar文件copy到工程的lib目录下,将该目录添加路径buildpath-->addpath
    	下载Logging包,添加jar
    使用BeanUtils框架的好处: 
    	(1)框架中集成了对对象进行操作的方法,可以直接使用不用再自己定义,接受的参数类型为String,避免了转数据类型的麻烦
    	(2)可以接收"属性面",对复合属性逐级向下查找
    		如birthday是Person的成员属性,Person中提供了相应的set & getBirthday方法
    		同时birthday是一个Date类的实例对象,date类提供了setTim方法,就可以将Date类也当做JavaBean来看待
    		通过修改time的属性来修改birthday,如果自己定义的话是比较繁琐的,而BeanUtil框架可以一步到位
    			将要修改的参数设置为 birthday.time,就能直接对该属性进行设置
    		BeanUtils.setProperty(pt1, "birthday.time", 6783);
    	BeanUtils 比普通工具类强在对参数的处理上
    	PropertyUtils.setProperty(pt1, "x", 88);//如 88 就不能改成字符串"88",而 BeanUtils 可以
    
    附: 对象作为一个类中的成员存在时,如果不进行初始化,在调用该属性时会抛出空指针异常
    	
    java 7 的新特性, Map 定义方式
    /*		Map[] map = {name:"asd" , age:22};
    		BeanUtils.setProperty(map, name, age);
    */

    代码实现

    package itheima.enhance;
    
    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 IntroSpector {
    	/**
    	 * @param args
    	 * @throws Exception 
    	 */
    	public static void main(String[] args) throws Exception {
    		// TODO Auto-generated method stub
    		
    		ReflectPoint pt1 = new ReflectPoint(3, 5);
    //用内省的方式来读取JavaBean的属性
    		String propertyName = "x";	//属性名
    	//普通方式:"x"-->"X"-->"getX"-->MethodGetX-->...
    		
    		//重构get方法
    		Object retVal = getProperty(pt1, propertyName);
    		System.out.println(retVal);
    		//重构set
    		Object value = 8;
    		setProperty(pt1, propertyName, value);	
    		System.out.println(pt1.getX());
    		
    //使用BeanUtil开源框架提供的set & get
    		System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName());
    	//(1)set.可以接收字符串,又可接收int
    		BeanUtils.setProperty(pt1, "x", "22");	
    		System.out.println(pt1.getX());
    		
    	//(2)使用BeanUtils的另一个好处,可以接收属性面,对复合属性进行操作
    		// 如birthday是Person的成员属性,Person中提供了相应的setBirthday & getBirthday方法
    		//同时是一个Date类的实例对象,date类提供了setTim方法,就可以将Date类也当做JavaBean来看待
    		//通过修改time的属性来修改birthday
    		BeanUtils.setProperty(pt1, "birthday.time", 6783);
    		System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
    		
    		//Java 7 新特性
    /*		Map[] map = {name:"asd" , age:22};
    		BeanUtils.setProperty(map, name, age);
    */		
    		//如 88 就不能改成字符串"88",而 BeanUtils 可以
    		PropertyUtils.setProperty(pt1, "x", 88);
    		System.out.println(PropertyUtils.getProperty(pt1, "x"));
    		
    	}
    
    	private static void setProperty(ReflectPoint pt1, String propertyName,
    			Object value) throws IntrospectionException,
    			IllegalAccessException, InvocationTargetException {
    		PropertyDescriptor pd2 = new PropertyDescriptor(propertyName, pt1.getClass());
    		//获得该属性的描述中写入(set)属性值的方法
    		Method methodSetX = pd2.getWriteMethod();
    		methodSetX.invoke(pt1,value);
    	}
    
    	private static Object getProperty(ReflectPoint pt1, String propertyName)
    			throws IntrospectionException, IllegalAccessException,
    			InvocationTargetException {
    /*		//获取该JavaBean "x"属性方法的描述
    		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
    		//获得应该用于(get)读取属性值的方法
    		Method methodGetX = pd.getReadMethod();
    		//通过获取的方法创建getX()方法的当前对象所对应的值
    		Object retVal = methodGetX.invoke(pt1);
    */		
    	//较为复杂的一种方法:调用 Introspector (内省)类的方法获取该类的 BeanInfo
    		BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
    		//通过BeanInfo的方法获取该类所有属性的描述
    		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;
    	}
    
    }
    




  • 相关阅读:
    canvas---HTML5新特性
    flex布局之兼容
    前端Blob对二进制流数据的处理方式
    execCommand的复制
    express快速入门
    react+redux+webpack+git技术栈
    react开发
    gulp工程化工具
    python---django安装
    vue+webpack+element-ui+git
  • 原文地址:https://www.cnblogs.com/Joure/p/4337190.html
Copyright © 2011-2022 走看看