`
ray_yui
  • 浏览: 220189 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

开源工具 — Apache Commons BeanUtils

阅读更多

开源工具系列文章:
      Apache Commons Lang(1):http://ray-yui.iteye.com/blog/1953020
      Apache Commons Lang(2):http://ray-yui.iteye.com/blog/1958319
      Apache Commons BeanUtils:http://ray-yui.iteye.com/blog/1961451
      Apache Commons Collections:http://ray-yui.iteye.com/blog/2021484
      Apache Commons IO:http://ray-yui.iteye.com/blog/2023034


      在笔者之前的文章提到过,在BeanUtils中通过PropertyUtils取代了FieldUtils,PropertyUtils是一套很容易操作类属性的API工具类,使用非常简单而且保持了对类的封装,使用get和set进行存取

public class TestMain {
	public static void main(String[] args) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		// 初始化信息
		Test test = new Test();
		Integer[] testArray = new Integer[10];
		Map<String, String> testMap = new HashMap<String, String>();

		
		// 以下方法名为set开始的方法均有get方法与其对应

		
		// 设置username,testArray,testMap属性
		PropertyUtils.setProperty(test, "username", "Hello");
		PropertyUtils.setProperty(test, "testArray", testArray);
		PropertyUtils.setProperty(test, "testMap", testMap);

		
		// 设置testArray属性下标为0的值为10
		PropertyUtils.setIndexedProperty(test, "testArray[0]", 10);

		
		// 设置testMap属性的值为参数三,遗憾是 key参数只支持字符串
		PropertyUtils.setMappedProperty(test, "testMap", "Hello", "10");

		
		// 在类中有嵌套类的时候,就不能使用简单的setProperty来对引用类设置属性,
		// 要使用nested,address为test类中属性名引用
		PropertyUtils.setNestedProperty(test, "address.id", 1);

		
		// 判断属性是否有get方法或set方法
		PropertyUtils.isReadable(test, "username");
		PropertyUtils.isWriteable(test, "username");

		
		// 返回该实例全部属性,属性名为key,值为value
		Map<String, Object> map = PropertyUtils.describe(test);

		
		// 把test对象的所有属性复制到test2对象当中,
		// 通过反射字段名匹配进行复制,但要注意将会覆盖原值
		Test test2 = new Test();
		PropertyUtils.copyProperties(test2, test);


		// 获取属性的Class类型
		PropertyUtils.getPropertyType(test, "username");
	}
}


PropertyUtils和BeanUtils的方法非常相似,但有一些小细节上可以区别它们,例如都使用copyProperty,BeanUtils只要属性名一致就算类型不同都可以互相兼容赋值,但PropertyUtils则会报错

public class TestMain {
	public static void main(String[] args) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException,
			InstantiationException {
		Test test1 = new Test();
		Test test2 = new Test();

		
		// 复制单个属性
		BeanUtils.copyProperty(test1, "username", test2);

		
		// 克隆对象,注意是浅克隆
		Test test3 = (Test) BeanUtils.cloneBean(test1);

		
		/*
		 * 在设置时间时,读者需要注意一个小问题, 
		 * 用-->setProperty(test1, "date", new Date());
		 * 这种方式设置时间时没有问题的,但若然使用字符串的形式2013-10-3
		 * 就会出现问题,这是因为BeanUtils无法识别字符串类型和时间类型的关系,
		 * 所以我们需要使用ConvertUtils来辅助BeanUtils,
		 * 但使用如下方式进行转换后,PropertyUtils仍然是无能为力
		 */
		
		//用此种方式没任何问题
		BeanUtils.setProperty(test1, "date", new Date()); 
		//此种方式无法区别字符串还是日期
		BeanUtils.setProperty(test1, "date", "2013-10-01");

		
		// 自定义一个转换器
		ConvertUtils.register(new Converter() {

			@Override
			public Object convert(Class type, Object value) {
				if (value == null) {
					throw new RuntimeException("value is null");
				}
				if (value.getClass() == Date.class) {
					return value;
				}
				if (value.getClass() != String.class) {
					throw new RuntimeException("type not match");
				}
				String valueStr = (String) value;
				if (StringUtils.isBlank(valueStr)) {
					throw new RuntimeException("string is empty");
				}
				try {
					return new SimpleDateFormat("yyyy-MM-dd").parse(valueStr);
				} catch (ParseException e) {
					e.printStackTrace();
					return null;
				}
			}
		}, Date.class);

		// 此时使用字符串的日期形式都可以成功转换
		BeanUtils.setProperty(test1, "date", "2013-10-1");
	}
}


      从上面时间转换的例子就能看出,为什么同属性名不同类型PropertyUtils会转换失败,因为PropertyUtils并没有使用ConvertUtils来进行转换,导致类型不同时没发互相转换,由于Apache commons发展历史的原因,导致某些Utils功能大致相同,请读者自行选择


      在某些业务情况下,我们的Bean是不确定的,可能随某些地方触发而改变,可能需要某个属性,又可能不需要某个属性,这种动态的Bean是编译性语言的Java无法支持的,但BeanUtils中的自由Bean(动态Bean)将动态创建Bean成为了可能

public class TestMain {
	public static void main(String[] args) throws IllegalAccessException,
			InstantiationException {

		// 创建动态Bean所拥有的字段
		DynaProperty[] props = new DynaProperty[] {
				new DynaProperty("id", String.class),
				new DynaProperty("testMap", Map.class) };

		
		// 创建dynaClass的BasicDynaClass实现,传入定义的props
		DynaClass dynaClass = new BasicDynaClass("bean", null, props);

		
		// 通过dynaClass创建Bean
		DynaBean bean = dynaClass.newInstance();

		
		// 可以按普通bean的方式对其进行使用
		bean.set("id", "hello");
		bean.set("testMap", new HashMap());
		bean.set("testMap", "Hello", "World");

		bean.get("id");
		bean.get("testMap", "Hello");


		/*
		 * BasicDynaClass是DynaClass接口的实现类, 
		 * 其中还有LazyDynaClass的实现可以帮助我们更方便
		 * 的使用动态bean,lazy,懒嘛!方便
		 */

		// 不需要再定义dynaProperty,直接赋值时将会自动声明属性
		DynaClass dynaClass = new LazyDynaClass();

		DynaBean dynaBean = dynaClass.newInstance();

		dynaBean.set("username", "Hello");
		dynaBean.set("testArray", 0, "Hello");
		dynaBean.set("testMap", "Hello", "World");

		dynaBean.get("username");
		dynaBean.get("testArray", 0);
		dynaBean.get("testMap", "Hello");

	}
}


总结:
      commons工具包很多开源组织都有提供,例如google,spring,apache都有各自的工具包,有众多的选择,但最终的目的只是为了方便我们程序的开发和维护,简化我们编写一些常用的逻辑,提升我们开发的效率,从而达到活在开源,善用开源
15
3
分享到:
评论
4 楼 ray_yui 2013-10-22  
ping2010 写道
ping2010 写道
// 克隆对象,注意是深克隆,非常有用 
Test test3 = (Test) BeanUtils.cloneBean(test1); 

这句话不对,根本不是深度复制。
package org.runant.demo ;
import org.apache.commons.beanutils.BeanUtils;

/*
 * $Id:testClone.java 
 *
 * Copyright (C) 2000-2013 Runant Systems, Inc, see http://www.runant.org.
 * All rights reserved
 * 
 * Created by Runant on 2013-10-22
 */
public class testClone {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Address address = new Address("SZ", 101000);
        User user = new User("GoodBoy", "123456", address);

        User target = (User) BeanUtils.cloneBean(user);
        System.out.println(target.getPassword());
        Address targetAddress = target.getAddress();
        targetAddress.setDetail("BJ");

        System.out.println("oraginal address:" + address + ",clone address:" + targetAddress);
        System.out.println("oraginal address:" + address.getDetail() + "," + address.getNum());
        System.out.println("clone address:" + targetAddress.getDetail() + "," + targetAddress.getNum());
    }

    public static class User {
        public User() {
        }

        public User(String userName, String password, Address address) {
            this.userName = userName;
            this.password = password;
            this.address = address;
        }

        private String userName;
        private String password;
        private Address address;

        public Address getAddress() {
            return address;
        }

        public void setAddress(Address address) {
            this.address = address;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    public static class Address {
        public Address() {
        }

        public Address(String detail, Integer num) {
            this.detail = detail;
            this.num = num;
        }

        private String detail;
        private Integer num;

        public String getDetail() {
            return detail;
        }

        public void setDetail(String detail) {
            this.detail = detail;
        }

        public Integer getNum() {
            return num;
        }

        public void setNum(Integer num) {
            this.num = num;
        }
    }
}



执行的结果为:
123456
oraginal address:testClone$Address@16897b2,clone address:testClone$Address@16897b2
clone address:BJ,101000
oraginal address:BJ,101000


非常感谢你的提醒,已修改
3 楼 ping2010 2013-10-22  
ping2010 写道
// 克隆对象,注意是深克隆,非常有用 
Test test3 = (Test) BeanUtils.cloneBean(test1); 

这句话不对,根本不是深度复制。
package org.runant.demo ;
import org.apache.commons.beanutils.BeanUtils;

/*
 * $Id:testClone.java 
 *
 * Copyright (C) 2000-2013 Runant Systems, Inc, see http://www.runant.org.
 * All rights reserved
 * 
 * Created by Runant on 2013-10-22
 */
public class testClone {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Address address = new Address("SZ", 101000);
        User user = new User("GoodBoy", "123456", address);

        User target = (User) BeanUtils.cloneBean(user);
        System.out.println(target.getPassword());
        Address targetAddress = target.getAddress();
        targetAddress.setDetail("BJ");

        System.out.println("oraginal address:" + address + ",clone address:" + targetAddress);
        System.out.println("oraginal address:" + address.getDetail() + "," + address.getNum());
        System.out.println("clone address:" + targetAddress.getDetail() + "," + targetAddress.getNum());
    }

    public static class User {
        public User() {
        }

        public User(String userName, String password, Address address) {
            this.userName = userName;
            this.password = password;
            this.address = address;
        }

        private String userName;
        private String password;
        private Address address;

        public Address getAddress() {
            return address;
        }

        public void setAddress(Address address) {
            this.address = address;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    public static class Address {
        public Address() {
        }

        public Address(String detail, Integer num) {
            this.detail = detail;
            this.num = num;
        }

        private String detail;
        private Integer num;

        public String getDetail() {
            return detail;
        }

        public void setDetail(String detail) {
            this.detail = detail;
        }

        public Integer getNum() {
            return num;
        }

        public void setNum(Integer num) {
            this.num = num;
        }
    }
}



执行的结果为:
123456
oraginal address:testClone$Address@16897b2,clone address:testClone$Address@16897b2
clone address:BJ,101000
oraginal address:BJ,101000

2 楼 ping2010 2013-10-22  
// 克隆对象,注意是深克隆,非常有用 
Test test3 = (Test) BeanUtils.cloneBean(test1); 

这句话不对,根本不是深度复制。
package org.runant.demo ;
import org.apache.commons.beanutils.BeanUtils;

/*
 * $Id:testClone.java 
 *
 * Copyright (C) 2000-2013 Runant Systems, Inc, see http://www.runant.org.
 * All rights reserved
 * 
 * Created by Runant on 2013-10-22
 */
public class testClone {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Address address = new Address("SZ", 101000);
        User user = new User("GoodBoy", "123456", address);

        User target = (User) BeanUtils.cloneBean(user);
        System.out.println(target.getPassword());
        Address targetAddress = target.getAddress();
        targetAddress.setDetail("BJ");

        System.out.println("oraginal address:" + address + ",clone address:" + targetAddress);
        System.out.println("oraginal address:" + address.getDetail() + "," + address.getNum());
        System.out.println("clone address:" + targetAddress.getDetail() + "," + targetAddress.getNum());
    }

    public static class User {
        public User() {
        }

        public User(String userName, String password, Address address) {
            this.userName = userName;
            this.password = password;
            this.address = address;
        }

        private String userName;
        private String password;
        private Address address;

        public Address getAddress() {
            return address;
        }

        public void setAddress(Address address) {
            this.address = address;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    public static class Address {
        public Address() {
        }

        public Address(String detail, Integer num) {
            this.detail = detail;
            this.num = num;
        }

        private String detail;
        private Integer num;

        public String getDetail() {
            return detail;
        }

        public void setDetail(String detail) {
            this.detail = detail;
        }

        public Integer getNum() {
            return num;
        }

        public void setNum(Integer num) {
            this.num = num;
        }
    }
}

1 楼 liushicheng1 2013-10-21  
系列文章写的很不错

相关推荐

    org.apache.commons.beanutils.jar

    Apache Commons BeanUtils是Apache软件基金会的一个开源项目,它提供了一组实用工具类,用于简化JavaBean对象的操作。这个库的核心是`org.apache.commons.beanutils`包,其中包含了大量的辅助方法,使得开发者可以...

    commons-beanutils-1.9.2下载

    标题"commons-beanutils-1.9.2下载"指的是Apache Commons BeanUtils库的1.9.2版本,这是一个开源的、稳定且广泛使用的版本。下载这个库的目的是为了在项目中引入它的功能,以便于处理Java对象的属性操作。 Apache ...

    commons-beanutils-1.8.3和commons-beanutils-1.8.0

    Apache Commons BeanUtils是Java开发中的一个实用工具库,主要用于处理JavaBeans对象,简化对JavaBean属性的操作。这个库提供了一套方便的API,使得开发者可以通过简单的API调用来获取、设置JavaBean的属性,甚至...

    org.apache.commons工具包

    Apache Commons BeanUtils是Java开发中的一个非常重要的工具包,它属于Apache软件基金会的Commons项目。这个工具包提供了大量方便的API,极大地简化了JavaBean对象之间的属性操作,尤其是在处理复杂的对象模型和数据...

    commons-beanutils-1.9.2和commons.collections-3.2.1

    Apache Commons BeanUtils与Apache Commons Collections是两个非常重要的Java开源库,它们在开发过程中扮演着不可或缺的角色,尤其是在处理对象属性操作和集合操作时。 Apache Commons BeanUtils库是专门为简化...

    commons-beanutils-1.8.3-bin+logging.rar

    Apache Commons BeanUtils是Java开发中广泛使用的开源工具库,它简化了JavaBean对象的操作,提供了大量的便捷方法,使得开发者能够更加方便地处理属性的读取和设置,以及对象之间的复制。在这个标题为"commons-...

    commons-beanutils-1.8.1.jar.zip

    Apache Commons BeanUtils是Java开发中的一个著名工具库,它为处理JavaBeans提供了极大的便利。本篇将详细探讨`commons-beanutils-1.8.1.jar.zip`这个压缩包中的主要内容,以及其在实际开发中的应用。 首先,`...

    commons-beanutils-core-1.7.0.zip

    Apache Commons BeanUtils Core是一个用于简化JavaBeans操作的开源库。它提供了一系列静态方法,使得开发者可以方便地对Java对象进行属性的读取、设置、复制,甚至转换等操作。BeanUtils Core的主要目标是减少与...

    commons-beanutils和commons-collections-3.1的jar包

    Commons BeanUtils和Apache Commons Collections是Java开发中两个非常重要的库,它们为开发者提供了大量实用工具类,极大地简化了日常编程工作。这两个库都是Apache软件基金会的一部分,属于开源项目,广泛应用于...

    commons-beanutils-1.8.3-sources.jar

    Apache Commons BeanUtils是Java开发中广泛使用的开源工具库,主要用于简化JavaBean对象的操作。在这个特定的版本“commons-beanutils-1.8.3-sources.jar”中,包含了该库的源代码,为开发者提供了深入理解其内部...

    commons-beanutils-1.9.4.zip

    Apache Commons BeanUtils是Java开发中的一个实用工具库,它提供了对JavaBeans属性操作的强大支持,使得开发者能够方便地进行对象属性的读写操作。而Apache Commons Logging则是一个轻量级的日志框架,它允许开发者...

    commons-beanutils-1.8.0.rar

    Commons BeanUtils是Apache软件基金会开发的一个Java开源项目,它位于Apache Commons组件库中,主要用于简化JavaBean对象的操作。这个库提供了许多便利的方法,使得开发者能够更便捷地处理JavaBean属性,而无需直接...

    commons-beanutils-core-1.8.0.jar

    Apache Commons BeanUtils是Apache软件基金会开发的一个开源项目,它是Java编程中的一个实用工具库,主要提供了方便地操作JavaBeans属性的功能。本文将深入探讨其中的核心模块——Commons BeanUtils Core 1.8.0版本...

    apache commons 开源工具列举

    Apache Commons 是一个由Apache软件基金会维护的Java库集合,它为开发人员提供了大量实用的工具类和组件,极大地简化了常见的编程任务。这个库包含了众多模块,每个模块专注于特定的功能领域,例如字符串处理、数学...

    apache-commons所有jar包

    Apache Commons 是一个由 Apache 软件基金会维护的开源项目,它提供了大量的 Java 类库,这些类库包含了许多实用的功能,极大地丰富了 Java 核心库的功能,为开发者提供了更强大的工具集。在Web开发中,Apache ...

    Apache Commons 常用jar包(包含代码和doc)更新至2011/12

    Apache Commons 是一个由 Apache 软件基金会维护的开源项目,它提供了大量可重用的 Java 类库,极大地丰富了 Java 核心库的功能。在这个更新至2011年12月的压缩包中,包含了几个关键的 Commons 模块,如 Beanutils、...

    Apache Commons 官方最近所有的jar包

    Apache Commons 是一个由 Apache 软件基金会维护的开源项目集合,它提供了许多Java实用工具类,以增强Java标准库的功能。这些jar包是开发者在处理常见编程任务时的得力助手,涵盖范围广泛,包括数据结构、网络通信、...

    Apache Commons组件简介.ppt

    5. **BeanUtils**:Apache Commons BeanUtils 提供了对JavaBeans规范的支持,简化了Java对象属性的访问和操作,包括属性编辑和反射功能,使得对象操作更加便捷。 6. **DBUtils**:Apache Commons DBUtils 是一个...

    org.apache.commons jar

    Apache Commons 是一个由 Apache 软件基金会维护的开源项目,它提供了大量的 Java 类库,以帮助开发者解决常见的编程任务。这些类库弥补了 Java 核心库中的不足,为开发人员提供了更方便、功能更丰富的工具。"org....

    apache commons 文档

    Apache Commons是Apache软件基金会提供的一个开源Java工具包,它包含了许多独立的Java库,涉及的领域包括字符串操作、数学运算、数组操作、对象反射、XML处理等。本知识点将围绕Apache Commons文档中的关键组件展开...

Global site tag (gtag.js) - Google Analytics