package com.baidu.dsp.common.utils; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.beanutils.PropertyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.Assert; /** * 反射的Utils函数集合. * <p/> * 提供侵犯隐私的直接读取filed的能力. */ public class BeanUtils { protected static final Logger logger = LoggerFactory.getLogger(BeanUtils.class); private static final String ENTITY_CLASS_PACKAGE = "com.baidu.dsp"; /** * 直接读取对象属性值,无视private/protected修饰符,不经过getter函数. */ public static Object getFieldValue(Object object, String fieldName) throws NoSuchFieldException { Field field = getDeclaredField(object, fieldName); if (!field.isAccessible()) { field.setAccessible(true); } Object result = null; try { result = field.get(object); } catch (IllegalAccessException e) { logger.error("不可能抛出的异常{}", e.getMessage()); } return result; } /** * 直接设置对象属性值,无视private/protected修饰符,不经过setter函数. */ public static void setFieldValue(Object object, String fieldName, Object value) throws NoSuchFieldException { Field field = getDeclaredField(object, fieldName); if (!field.isAccessible()) { field.setAccessible(true); } try { field.set(object, value); } catch (IllegalAccessException e) { logger.error("不可能抛出的异常:{}", e.getMessage()); } } /** * 循环向上转型,获取对象的DeclaredField. */ private static Field getDeclaredField(Object object, String fieldName) throws NoSuchFieldException { Assert.notNull(object); return getDeclaredField(object.getClass(), fieldName); } /** * 循环向上转型,获取类的DeclaredField. */ @SuppressWarnings("rawtypes") private static Field getDeclaredField(Class clazz, String fieldName) throws NoSuchFieldException { Assert.notNull(clazz); Assert.hasText(fieldName); for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) { try { return superClass.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { // Field不在当前类定义,继续向上转型 } } throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + fieldName); } /** * 获得输入对象的两层镜象实例,要求参数类必需包含一个无参的public构造函数 * <p/> * 两层镜像:如果输入对象的某个属性是系统的实体或实体的集合则clone该实体或集合里面的每个实体,且只是两层clone不会再次嵌套 * 实体:com.baidu.dsp.*.*.java 实体集合:目前支持的集合为ArrayList HashSet * * @param source * * @return * * @author guojichun * @since 1.0.0 */ @SuppressWarnings({"rawtypes", "unchecked"}) public static Object getClone(Object source) { if (null == source) { return null; } Object target = BeanUtils.getOneLayerClone(source); try { // 此处使用了JAVA的内省机制(内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法) // 获得对像的BeanInfo 信息: BeanInfo bi = Introspector.getBeanInfo(source.getClass()); // 获得属性的描述器 PropertyDescriptor[] props = bi.getPropertyDescriptors(); for (int i = 0; i < props.length; ++i) { if (null != props[i].getReadMethod()) { Class propertyType = props[i].getPropertyType(); if (propertyType.equals(List.class)) { List newList = new ArrayList(); // 此处使用了JAVA的反射机制通过获得方法的引用去执行方法,其中source:为要执行的方法所属的对象, // 方法如果没有参数第二个参数则为null; List valueList = (List) props[i].getReadMethod().invoke(source); if (valueList == null) { valueList = new ArrayList(); } for (Object value : valueList) { Object cloneValue = null; if (value.getClass().getName().indexOf(ENTITY_CLASS_PACKAGE) >= 0) { cloneValue = BeanUtils.getOneLayerClone(value); } else { cloneValue = value; } newList.add(cloneValue); } props[i].getWriteMethod().invoke(target, newList); } if (propertyType.equals(Set.class)) { Set newSet = new HashSet(); Set valueSet = (Set) props[i].getReadMethod().invoke(source); if (valueSet == null) { valueSet = new HashSet(); } for (Object value : valueSet) { Object cloneValue = BeanUtils.getOneLayerClone(value); newSet.add(cloneValue); } props[i].getWriteMethod().invoke(target, newSet); } else { // 如果是array 跳过 //FIXME if (propertyType.equals(Arrays.class)) { continue; } if (propertyType.toString().startsWith(ENTITY_CLASS_PACKAGE)) { Object value = props[i].getReadMethod().invoke(source); Object cloneValue = BeanUtils.getOneLayerClone(value); props[i].getWriteMethod().invoke(target, cloneValue); } } } } } catch (Exception e) { logger.error("clone object exception object class:" + source.getClass(), e); } return target; } /** * 获得输入对象的简单一层镜象实例,要求参数类必需包含一个无参的public构造函数 * * @param source * * @return * * @author guojichun * @since 1.0.0 */ @SuppressWarnings("rawtypes") private static Object getOneLayerClone(Object source) { if (null == source) { return null; } Object target = null; try { Constructor con = source.getClass().getConstructor(); target = con.newInstance(); // 把一个集合类中的数据拷贝到另一集合类中 PropertyUtils.copyProperties(target, source); } catch (Exception e) { logger.error("clone object exception object class:" + source.getClass(), e); } return target; } /** * 获得输入对象列表的镜象实例列表,要求参数类必需包含一个无参的public构造函数 * * @param sourceList * * @return * * @author ying * @since 1.0.0 */ @SuppressWarnings({"rawtypes", "unchecked"}) public static List getCloneList(List sourceList) { if (null == sourceList) { return null; } List targetList = new ArrayList(); for (int i = 0; i < sourceList.size(); i++) { Object target = null; Object source = sourceList.get(i); try { Constructor con = source.getClass().getConstructor(); target = con.newInstance(); PropertyUtils.copyProperties(target, source); } catch (Exception e) { logger.error("clone object exception object class:" + source.getClass(), e); } targetList.add(target); } return targetList; } }