转载请注明出处:https://blog.csdn.net/jevonsCSDN/article/details/87824271 【Jevons’Blog】
依赖包:
commons-logging.jar
commons-beanutils-1.8.0-BETA.jar
cglib-nodep-3.2.10.jar
辅助包:
fastjson-1.1.39.jar
优化复制方法 2019-2-25 18:04:08
package dynamic;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import net.sf.cglib.beans.BeanGenerator;
import net.sf.cglib.beans.BeanMap;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import com.alibaba.fastjson.JSON;
public class DynaBeanHolder {
@SuppressWarnings("rawtypes")
private Map classMap = new HashMap<String, Class<?>>();
@SuppressWarnings("rawtypes")
private Map valueMap = new HashMap<String, Object>();
/** 创建标志 */
private boolean isCreate = false;
private BeanGenerator generator = null;
private static BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance();
private Object dynaBean = null;
private BeanMap beanMap = null;
public DynaBeanHolder() {
super();
}
/**
* 初始化属性 class、key、value
*
* @param key
* @param value
* @return
*/
@SuppressWarnings("unchecked")
private DynaBeanHolder initSet(String key, Object value) {
if (this.dynaBean == null || !this.classMap.containsKey(key)) {
this.classMap.put(key, value.getClass());
this.valueMap.put(key, value);
} else {
beanMap.put(key, value);
}
return this;
}
/**
* 初始化属性 class、key,同时值为null
*
* @param key
* @param value
* @return
*/
@SuppressWarnings("unchecked")
public DynaBeanHolder setToNull(String key, Class<?> clazz) {
if (this.dynaBean == null || !this.classMap.containsKey(key)) {
this.classMap.put(key, clazz);
this.valueMap.put(key, null);
} else {
beanMap.put(key, null);
}
return this;
}
/**
* 给指定的dynaBean赋值
*
* @param dynaBean
* @param key
* @param value
* @return
*/
public static Object set(Object dynaBean, String key, Object value) {
BeanMap.create(dynaBean).put(key, value);
return dynaBean;
}
/**
* set方法
*
* @param key
* 属性名
* @param value
* 值
*/
public DynaBeanHolder set(String key, Object value) {
return initSet(key, value);
}
/**
* get方法
*
* @param key
* 属性名
* @return 值
*/
public Object get(String key) {
return beanMap.get(key);
}
/**
* 获取bean(含有完整的属性 set/get方法)
*
* @return
*/
public Object getDynaBean() {
return this.dynaBean;
}
/**
* 结束属性初始化,创建并返回一个Object对象(内含相应属性的set/get方法)
*
* @return
*/
public DynaBeanHolder create() {
if (!isCreate) {
generator = new BeanGenerator();
BeanGenerator.addProperties(generator, this.classMap);
this.dynaBean = generator.create();
this.beanMap = BeanMap.create(this.dynaBean);
this.beanMap.putAll(this.valueMap);
this.isCreate = true;
}
return this;
}
/**
* 重建
*
* @return
*/
public DynaBeanHolder reCreate() {
this.isCreate = false;
return create();
}
/**
* 销毁
*/
public void destroy() {
this.classMap.clear();
this.valueMap.clear();
this.generator = null;
this.dynaBean = null;
this.beanMap = null;
this.isCreate = false;
}
/**
* 从dynaBean复制属性到target
*
* @param target
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public void copyTo(Object target) throws IllegalAccessException,
InvocationTargetException {
BeanUtils.copyProperties(target, this.dynaBean);
}
/**
* 特殊复制:从dynaBean复制属性到target
*
* @param target
* @param copyProperty
* @throws Exception
*/
public void copySpecialTo(Object target, Collection<String> copyProperty)
throws Exception {
boolean specialCopy = copyProperty == null ? false : true;
if (specialCopy) {
for (Iterator it = copyProperty.iterator(); it.hasNext();) {
String key = (String) it.next();
BeanUtils.copyProperty(target, key,
BeanUtils.getProperty(this.dynaBean, key));
}
} else {
copyTo(target);
}
}
/**
* 从target复制属性到dynaBean
*
* @param src
* @throws Exception
*/
public DynaBeanHolder copyFrom(Object src) throws Exception {
return copyFrom(src, false);
}
public DynaBeanHolder copyFrom(Object src, boolean asNew) throws Exception {
return copySpecialFrom(src, null, asNew);
}
/**
* 从target复制属性到dynaBean
*
* @param src
* @param asNew
* 是否复制为一个新的DynaBeanHolder
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public DynaBeanHolder copySpecialFrom(Object src,
Collection<String> copyProperty, boolean asNew) throws Exception {
boolean specialCopy = false;
int copySize = 0;
if (copyProperty != null) {
specialCopy = true;
copySize = copyProperty.size();
}
if (asNew) {
DynaBeanHolder newHolder = newInstance();
PropertyDescriptor[] descriptors = getPropertyDescriptor(src);
for (PropertyDescriptor descriptor : descriptors) {
if (!descriptor.getName().equals("class")
&& ((specialCopy && copyProperty.contains(descriptor
.getName())) || (!specialCopy))) {
Class<?> clazz = descriptor.getPropertyType();
String key = descriptor.getName();
newHolder.classMap.put(key, clazz);
newHolder.valueMap.put(key, descriptor.getReadMethod()
.invoke(src));
if (specialCopy && --copySize == 0)
break;// 阻断多余循环
}
}
return newHolder.create();
} else {
if (this.dynaBean != null) {
if (specialCopy) {
PropertyDescriptor[] descriptors = getPropertyDescriptor(src);
for (PropertyDescriptor descriptor : descriptors) {
if (!descriptor.getName().equals("class")
&& copyProperty.contains(descriptor.getName())) {
String key = descriptor.getName();
BeanUtils.copyProperty(this.dynaBean, key,
BeanUtils.getProperty(src, key));
if (--copySize == 0)
break;
}
}
} else {
BeanUtils.copyProperties(this.dynaBean, src);
}
return this;
} else {
throw new Exception(
"Please initialize the dynaBean before calling the copyFrom!");
}
}
}
/**
* 特殊复制属性 (只复制指定属性名的值) 静态
*
* @param src
* @param copyProperty
* @return
* @throws Exception
*/
public static DynaBeanHolder copysSpecFrom(Object src,
Collection<String> copyProperty) throws Exception {
return newInstance().copySpecialFrom(src, copyProperty, true);
}
/**
* 特殊复制属性 (只复制指定属性名的值) 静态
*
* @param src
* @param copyProperty
* @return
* @throws Exception
*/
public static DynaBeanHolder copysSpecFrom(Object src,
String... copyProperty) throws Exception {
List<String> propertyList = null;
if (copyProperty != null) {
propertyList = Arrays.asList(copyProperty);
} else {
propertyList = Collections.emptyList();
}
return newInstance().copySpecialFrom(src, propertyList, true);
}
/**
* 复制属性 (只复制指定属性名的值) 静态
*
* @param src
* @param copyProperty
* @return
* @throws Exception
*/
public static DynaBeanHolder copysFrom(Object src) throws Exception {
return newInstance().copyFrom(src, true);
}
/**
* 获取属性 <br>
* PropertyUtilsBean中已使用FastHashMap.setFast(true) <br>
* 针对PropertyDescriptor做了缓存处理,不需要担心重复获取影响效率问题(线程安全)
*
* @param bean
* @return
*/
public static PropertyDescriptor[] getPropertyDescriptor(Object bean) {
return beanUtilsBean.getPropertyUtils().getPropertyDescriptors(bean);
}
public static DynaBeanHolder newInstance() {
return new DynaBeanHolder();
}
/**
* 特殊复制属性 (只复制指定属性名的值)
*
* @param src
* @param copyProperty
* @return
* @throws Exception
*/
public DynaBeanHolder copySpecialFrom(Object src,
Collection<String> copyProperty) throws Exception {
return copySpecialFrom(src, copyProperty, false);
}
/**
* 获取BeanMap
*
* @return
*/
public BeanMap getBeanMap() {
if (this.beanMap == null && this.dynaBean != null) {
this.beanMap = BeanMap.create(this.dynaBean);
} else if (this.beanMap != null && this.dynaBean == null) {
this.beanMap = null;
}
return this.beanMap;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((beanMap == null) ? 0 : beanMap.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DynaBeanHolder other = (DynaBeanHolder) obj;
if (beanMap == null) {
if (other.beanMap != null)
return false;
} else if (!beanMap.equals(other.beanMap))
return false;
return true;
}
public static void main(String[] args) throws Exception {
//测试样例:动态bean赋值给 user对象
DynaBeanHolder bean = new DynaBeanHolder();
Object object = bean.set("name","来了").set("age", 24).create();
User user1 = new User();
BeanUtils.copyProperties(user1, object);
BeanUtils.copyProperties(user1, bean.getBeanMap());
System.out.println(JSON.toJSON(object));
System.out.println(JSON.toJSON(bean.set("fuck", "??").reCreate()));
//测试样例:user对象赋值给 动态bean
DynaBeanHolder bean2 = new DynaBeanHolder();
Object object2 = bean2.setToNull("name", String.class).setToNull("age", Integer.class).create();
User user2 = new User();
user2.setAge(12);
user2.setName("张三");
bean2.copyFrom(user2);//正确赋值
// BeanUtils.copyProperties(object2, user2);//正确赋值
// BeanUtils.copyProperties(bean2.getBeanMap(),user2);//错误赋值
// BeanUtils.copyProperties(bean2,user2);//错误赋值
//测试样例:动态bean3 与 动态bean4比较
DynaBeanHolder bean3 = new DynaBeanHolder();
Object object3 = bean3.initSet("name","来了").initSet("age", 24).create();
DynaBeanHolder bean4 = new DynaBeanHolder();
Object object4 = bean4.initSet("name","来了").initSet("age", 24).create();
System.out.println(object3.equals(object4));//false
System.out.println(object3==object4);//false
System.out.println(bean3.equals(bean4));//true
System.out.println(bean3==bean4);//false
System.out.println(bean3.getBeanMap().equals(bean4.getBeanMap()));//true
System.out.println(bean3.getBeanMap()==bean4.getBeanMap());//false
DynaBeanHolder bean5 = new DynaBeanHolder();
bean5.copyFrom(user2,true);
System.out.println(JSON.toJSON(bean5));
}
}
实体测试类:
package dynamic;
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}