Apache Commons Beanutils对象属性批量复制(pseudo-singleton)
Apache Commons Beanutils为开源软件,可在Apache官网http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi下载,使用它还需另一个Apache开源软件Apache
Commons Logging,可在Apache官网http://commons.apache.org/proper/commons-logging/download_logging.cgi下载,我使用的是commons-beanutils-1.9.1-bin.zip和commons-logging-1.1.3-bin.zip
public class User {
private String name;
private Integer age;
private boolean single;
private Map<Integer,Integer> map;
public User(){}
public User(String name,Integer age,boolean single,
Map<Integer,Integer> map){
this.name = name;
this.age = age;
this.single = single;
this.map = map;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSingle() {
return single;
}
public void setSingle(boolean single) {
this.single = single;
}
public Map<Integer, Integer> getMap() {
return map;
}
public void setMap(Map<Integer, Integer> map) {
this.map = map;
}
public String toString(){
String str = "name:"+name+" age:"+age+" single:"+single+" ";
if(null != map && map.size() > 0){
str += "map[";
Iterator<Integer> it = map.keySet().iterator();
while(it.hasNext()){
Integer key = it.next();
Integer value = map.get(key);
str += key+":"+value+" ";
}
str += "]";
}
return str;
}
}
package com.sean; import java.util.HashMap;
import java.util.Map; import org.apache.commons.beanutils.BeanUtils; public class Test {
public static void main(String[] args) throws Exception {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
map.put(1, 1);
User u1 = new User("tom",123,true,map);
User u2 = new User();
BeanUtils.copyProperties(u2, u1);
System.out.println(u1.toString());
System.out.println(u2.toString());
}
}
运行结果为(比较复杂的属性也可以被复制并且只有拥有get/set方法的属性才可以被复制):
name:tom age:123 single:true map[1:1 ]
name:tom age:null single:true map[1:1 ]
更详细的使用说明就不介绍了,接下来看看BeanUtils是如何实现的,好戏刚刚开始
BeanUtils:
.......
public static void copyProperties(Object dest, Object orig)
throws IllegalAccessException, InvocationTargetException {
BeanUtilsBean.getInstance().copyProperties(dest, orig);
}
......
/**
* Gets the instance which provides the functionality for {@link BeanUtils}.
* This is a pseudo-singleton - an single instance is provided per (thread) context classloader.
* This mechanism provides isolation for web apps deployed in the same container.
*
* @return The (pseudo-singleton) BeanUtils bean instance
*/
public static BeanUtilsBean getInstance() {
return BEANS_BY_CLASSLOADER.get();
}
......
这里特意带上了方法说明,getInstance()方法并不是一个简单的单例模式,而是一个“伪单例”模式
ContextClassLoaderLocal<T>:
......
private static final ContextClassLoaderLocal<BeanUtilsBean> BEANS_BY_CLASSLOADER
= new ContextClassLoaderLocal<BeanUtilsBean>() {
// Creates the default instance used when the context classloader is unavailable
@Override
protected BeanUtilsBean initialValue() {
return new BeanUtilsBean();
}
};
......
/**
* Gets the instance which provides the functionality for {@link BeanUtils}.
* This is a pseudo-singleton - an single instance is provided per (thread) context classloader.
* This mechanism provides isolation for web apps deployed in the same container.
* @return the object currently associated with the context-classloader of the current thread.
*/
public synchronized T get() {
// synchronizing the whole method is a bit slower
// but guarantees no subtle threading problems, and there's no
// need to synchronize valueByClassLoader // make sure that the map is given a change to purge itself
valueByClassLoader.isEmpty();
try {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if (contextClassLoader != null) { T value = valueByClassLoader.get(contextClassLoader);
if ((value == null) && !valueByClassLoader.containsKey(contextClassLoader)) {
value = initialValue();
valueByClassLoader.put(contextClassLoader, value);
}
return value;
}
} catch (SecurityException e) { /* SWALLOW - should we log this? */ }
// if none or exception, return the globalValue
if (!globalValueInitialized) {
globalValue = initialValue();
globalValueInitialized = true;
}//else already set
return globalValue;
}
.......
和ContextClassLoader配合实现了一个线程中单例的“伪单例”模式,真正的亮点
Apache Commons Beanutils对象属性批量复制(pseudo-singleton)的更多相关文章
- Apache Commons Beanutils 一 (使用PropertyUtils访问Bean属性)
BeanUtils简要描述 beanutils,顾名思义,是java bean的一个工具类,可以帮助我们方便的读取(get)和设置(set)bean属性值.动态定义和访问bean属性: 细心的话,会发 ...
- BeanUtils对象属性copy的性能对比以及源码分析
1. 对象属性拷贝的常见方式及其性能 在日常编码中,经常会遇到DO.DTO对象之间的转换,如果对象本身的属性比较少的时候,那么我们采用硬编码手工setter也还ok,但如果对象的属性比较多的情况下,手 ...
- org.springframework.beans.BeanUtils与org.apache.commons.beanutils.BeanUtils的copyProperties用法区别
知识点 org.springframework.beans.BeanUtils与org.apache.commons.beanutils.BeanUtils都提供了copyProperties方法,作 ...
- org.apache.commons.beanutils.BeanUtils的常见用法
import org.apache.commons.beanutils.BeanUtils BeanUtils1. public static void copyProperty(Object bea ...
- Apache Commons Beanutils 三 (BeanUtils、ConvertUtils、CollectionUtils...)
前言 前面已经学习了Apache Commons Beanutils包里的PropertyUtils和动态bean,接下来将学习剩下的几个工具类,个人觉得还是非常实用的,特别是CollectionUt ...
- Apache Commons Beanutils 二 (动态Bean - DynaBeans)
相关背景 上一篇介绍了PropertyUtils的用法,PropertyUtils主要是在不修改bean结构的前提下,动态访问bean的属性: 但是有时候,我们会经常希望能够在不定义一个Java类的前 ...
- org.apache.commons.beanutils.ConversionException: No value specified解决办法
转自:https://www.cnblogs.com/linjiqin/archive/2011/07/21/2112628.html 当用到了java.sql.Date时间等非内置对象时,如果对象为 ...
- org.apache.commons.beanutils.BeanMap简单使用例子
一.org.apache.commons.beanutils.BeanMap; 将一个java bean允许通过map的api进行调用, 几个支持的操作接口: Object get(Object ke ...
- 再续前缘-apache.commons.beanutils的补充
title: 再续前缘-apache.commons.beanutils的补充 toc: true date: 2016-05-32 02:29:32 categories: 实在技巧 tags: 插 ...
随机推荐
- 编译安装nginx并修改版本头信息—参考实例
今天做实验的时候,想起我那台yum安装的nginx+php-fpm+mysql服务器上的nginx版本有点低了,并且还要加两个第3方模块,就去nginx官网下载了最新稳定版nginx-1.0.6,好了 ...
- BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演
分析:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 然后对于求这样单个的gcd(x,y)=k的, ...
- 对apache和memcache进行压力测试
工作中经常使用的软件之二:apache和memcache 以前经常听说memcache的TPS能达到几万,但一直也不知道apache的性能到底如何,所以在闲暇之余,就自己做了一下压力测试. 环境:两台 ...
- 应用程序连接oracle rac
10g rac vip漂移的目的不是让client不加改变的连接过来而是让client尽快收到一个连接终止的包,然后由client去连接tnsnames中配置的下一个地址.和没有vip相比, 使用vi ...
- leetcode之Palindrome Partitioning
方法一:DFS递归,判断每一个是否为回文数 1,首先要有一个判断字符串是否是回文的函数.容易实现,字符串从两边同时往中间走,看字符是否相同; 2,深度优先搜索思想对字符串进行遍历.得到结果.例如,s ...
- cloudstack安装篇2-主机名配置
CloudStack要求正确配置主机名.在默认情况下,安装完操作系统后,主机名是localhost.localdomain.运行下面的命令来测试: hostname --fqdn 在此处将返回这样的结 ...
- PHP中的empty()和isset()的比较
- storm核心组件
Storm核心组件 了解 Storm 的核心组件对于理解 Storm 原理非常重要,下面介绍 Storm 的整体,然后介绍 Storm 的核心. Storm 集群由一个主节点和多个工作节点组成.主节点 ...
- java异常处理一
为什么需要异常处理? 郝斌解释:因为有些异常不能间接的利用if else来处理,比如说输入的时候,将键盘输入的内容转换为数字,此事如果用户输入非数字就会出现异常,而在用户输入之前是无法用程序判断用户所 ...
- easyui datagrid用formtater的问题
当value是一个字符串是直接使用value会提示value没有定义,这时需要转换下value,用""+value来替换就可以了.