设为首页 收藏本站
查看: 573|回复: 0

[经验分享] 开源工具 — Apache Commons BeanUtils

[复制链接]
发表于 2017-1-2 08:22:50 | 显示全部楼层 |阅读模式
开源工具系列文章:
      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都有各自的工具包,有众多的选择,但最终的目的只是为了方便我们程序的开发和维护,简化我们编写一些常用的逻辑,提升我们开发的效率,从而达到活在开源,善用开源

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-322603-1-1.html 上篇帖子: Apache common deamon的使用 下篇帖子: Windows下Apache的优化
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表