• 工具类--BeanUtils----Bean转换工具


      1 package com.zhouyy.netBank.util;
      2 
      3 import java.beans.PropertyDescriptor;
      4 import java.lang.reflect.Field;
      5 import java.lang.reflect.Method;
      6 import java.lang.reflect.Modifier;
      7 import java.util.ArrayList;
      8 import java.util.Arrays;
      9 import java.util.HashMap;
     10 import java.util.List;
     11 import java.util.Map;
     12 import java.util.concurrent.ConcurrentHashMap;
     13 
     14 import org.springframework.beans.BeansException;
     15 import org.springframework.beans.FatalBeanException;
     16 import org.springframework.util.Assert;
     17 import org.springframework.util.ClassUtils;
     18 import org.springframework.util.CollectionUtils;
     19 
     20 import com.zhouyy.netBank.framework.cglib.beans.BeanCopier;
     21 import com.zhouyy.netBank.framework.cglib.beans.BeanMap;
     22 
     23 /**
     24  * Bean转换工具
     25  *
     26  * @author zhouyy
     27  * @version 0.0.5
     28  */
     29 public abstract class BeanUtils extends org.springframework.beans.BeanUtils {
     30 
     31     private static final Map<String, BeanCopier> BEAN_COPIER_MAP = new ConcurrentHashMap<>();
     32     private static final Map<String, BeanCopier> NONE_NULL_BEAN_COPIER_MAP = new ConcurrentHashMap<>();
     33 
     34     /**
     35      * MAP集合转成bean对象集合
     36      *
     37      * @param listResult 需要拷贝的集合
     38      * @param clazz      需要将map转换成的Class
     39      * @param <B>        泛型
     40      * @return 集合泛型
     41      * @author zhouyy
     42      */
     43     public static <B> List<B> copyMapListProperties(List listResult, Class<B> clazz) {
     44         List<B> sourceList = new ArrayList<>();
     45         Map<String, Object> cacheMap = new HashMap<>();
     46         //遍历MAP结果集
     47         for (Object obj : listResult) {
     48             Map map = (Map) obj;
     49             B source = copyMapProperties(map, clazz, cacheMap);
     50 //            if (null != clazz) {
     51 //                source = copyMapProperties(map, clazz, cacheMap);
     52 //            } else {
     53 //                Map<String, Object> newMap = new HashMap<>();
     54 //                Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
     55 //                while (entries.hasNext()) {
     56 //                    Map.Entry<String, Object> entry = entries.next();
     57 //                    newMap.put(entry.getKey().toLowerCase(), entry.getValue());
     58 //                }
     59 //                source = (B) newMap;
     60 //            }
     61             sourceList.add(source);
     62         }
     63         return sourceList;
     64     }
     65 
     66     /**
     67      * MAP转成bean对象集合
     68      *
     69      * @param map
     70      * @param clazz
     71      * @param <B>
     72      * @return
     73      * @author zhouyy
     74      */
     75     public static <B> B copyMapProperties(Map map, Class<B> clazz) {
     76         Map<String, Object> cacheMap = new HashMap<>();
     77         return copyMapProperties(map, clazz, cacheMap);
     78     }
     79 
     80     /**
     81      * 递归获取当前class的所有父类中的属性
     82      *
     83      * @param clazz     需要获取的类
     84      * @param fieldList 字段集合
     85      */
     86     public static void getAllFields(Class<?> clazz, List<Field> fieldList) {
     87         Class superClass = clazz.getSuperclass();
     88         if (superClass != Object.class) {
     89             getAllFields(superClass, fieldList);
     90         }
     91         Field[] fields = clazz.getDeclaredFields();
     92         fieldList.addAll(Arrays.asList(fields));
     93     }
     94 
     95     /**
     96      * MAP转成bean对象集合
     97      *
     98      * @param map
     99      * @param clazz
    100      * @param cacheMap
    101      * @param <B>
    102      * @return
    103      * @author zhouyy
    104      */
    105     @SuppressWarnings("unchecked")
    106     private static <B> B copyMapProperties(Map map, Class<B> clazz, Map<String, Object> cacheMap) {
    107         Assert.notNull(map, "map must not be null");
    108         Assert.notNull(clazz, "clazz must not be null");
    109 
    110         B instantiate = instantiate(clazz);
    111         BeanMap beanMap = BeanMap.create(instantiate, true);
    112         beanMap.putAll(map);
    113         return instantiate;
    114 
    115 //        List<Field> fieldList = (List<Field>) cacheMap.get(clazz);
    116 //        if (fieldList == null) {
    117 //            fieldList = new ArrayList<>();
    118 //            getAllFields(clazz, fieldList);
    119 //        }
    120 //
    121 //        B source = null;
    122 //        try {
    123 //            source = clazz.newInstance();
    124 //        } catch (InstantiationException | IllegalAccessException e) {
    125 //            e.printStackTrace();
    126 //        }
    127 //        //遍历结果MAP
    128 //        Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
    129 //        while (it.hasNext()) {
    130 //            Map.Entry<String, Object> entry = it.next();
    131 //            //遍历映射实体属性
    132 //            for (Field field : fieldList) {
    133 //                String key = entry.getKey();
    134 //                Boolean flag = (Boolean) cacheMap.get(key + field.getName());
    135 //                if (flag == null) {
    136 //                    flag = !key.replace("_", "").equalsIgnoreCase(field.getName());
    137 //                    cacheMap.put(key + field.getName(), flag);
    138 //                }
    139 //                if (flag) {
    140 //                    continue;
    141 //                }
    142 //
    143 //                Object value = entry.getValue();
    144 //                Class typeClass = field.getType();
    145 //                Object valueType = setFieldValueByFieldType(value, typeClass);
    146 //                ReflectionUtils.makeAccessible(field);
    147 //                ReflectionUtils.setField(field, source, valueType);
    148 //            }
    149 //        }
    150 //        return source;
    151     }
    152 
    153     //    private static Object setFieldValueByFieldType(Object value, Class typeClass) {
    154 //        //这里去掉typeClass == double.class是为了代码规范,保证bean中的属性使用包装类
    155 //        if ((value instanceof Character) && typeClass == String.class) {
    156 //            Character character = (Character) value;
    157 //            value = character.toString();
    158 //        }else if(value instanceof Number){
    159 //            Number number = (Number) value;
    160 //            if (typeClass == BigDecimal.class) {
    161 //                value = BigDecimal.valueOf(number.doubleValue());
    162 //            } else if (typeClass == BigInteger.class) {
    163 //                value = BigInteger.valueOf(number.longValue());
    164 //            } else if (typeClass == Long.class) {
    165 //                value = number.longValue();
    166 //            } else if (typeClass == Integer.class) {
    167 //                value = number.intValue();
    168 //            } else if (typeClass == Double.class) {
    169 //                value = number.doubleValue();
    170 //            } else if (typeClass == Float.class) {
    171 //                value = number.floatValue();
    172 //            } else if (typeClass == Short.class) {
    173 //                value = number.shortValue();
    174 //            } else if (typeClass == Byte.class) {
    175 //                value = number.byteValue();
    176 //            } else {
    177 //                value = number;
    178 //            }
    179 //        }
    180 //        return value;
    181 //    }
    182     private static String getBeanCopierCacheKey(Class source, Class target) {
    183         return source.getName() + "|" + target.getName();
    184     }
    185 
    186     private static BeanCopier getBeanCopier(Class source, Class target) {
    187         String beanCopierCacheKey = getBeanCopierCacheKey(source, target);
    188         BeanCopier beanCopier = BEAN_COPIER_MAP.get(beanCopierCacheKey);
    189         if (beanCopier == null) {
    190             beanCopier = BeanCopier.create(source, target, false);
    191             BEAN_COPIER_MAP.put(beanCopierCacheKey, beanCopier);
    192         }
    193         return beanCopier;
    194     }
    195 
    196     private static BeanCopier getNoneNullBeanCopier(Class source, Class target) {
    197         String beanCopierCacheKey = getBeanCopierCacheKey(source, target);
    198         BeanCopier beanCopier = NONE_NULL_BEAN_COPIER_MAP.get(getBeanCopierCacheKey(source, target));
    199         if (beanCopier == null) {
    200             beanCopier = BeanCopier.create(source, target, false, true);
    201             NONE_NULL_BEAN_COPIER_MAP.put(beanCopierCacheKey, beanCopier);
    202         }
    203         return beanCopier;
    204     }
    205 
    206     /**
    207      * 作者:zhouyy
    208      * 批量转换List<Bean>
    209      *
    210      * @param source list集合
    211      * @param t      所成对象的class
    212      * @param <B>
    213      * @return List<T>
    214      * @throws BeansException
    215      */
    216     public static <S, B> List<B> copyListProperties(List<S> source, Class<B> t) throws BeansException {
    217         List<B> list = new ArrayList<>();
    218         if (CollectionUtils.isEmpty(source)) {
    219             return list;
    220         }
    221 
    222         BeanCopier beanCopier = getBeanCopier(source.get(0).getClass(), t);
    223         for (Object o : source) {
    224             B instantiate = instantiate(t);
    225             beanCopier.copy(o, instantiate, null);
    226 //            copyProperties(o, instantiate);
    227             list.add(instantiate);
    228         }
    229         return list;
    230 //        List<B> list = new ArrayList<>();
    231 //        if (source == null) {
    232 //            return list;
    233 //        }
    234 //        try {
    235 //            for (Object o : source) {
    236 //                B tObj = t.newInstance();
    237 //                copyProperties(o, tObj);
    238 //                list.add(tObj);
    239 //            }
    240 //        } catch (InstantiationException | IllegalAccessException e) {
    241 //            e.printStackTrace();
    242 //        }
    243 //        return list;
    244     }
    245 
    246 
    247     public static Map<String, Object> beanToMap(Object obj) {
    248         BeanMap beanMap = BeanMap.create(obj);
    249         HashMap<String, Object> copy = new HashMap<>();
    250         for (Object key : beanMap.keySet()) {
    251             copy.put((String) key, beanMap.get(key));
    252         }
    253         return copy;
    254 //        if (obj == null) {
    255 //            return null;
    256 //        }
    257 //        Map<String, Object> map = new HashMap<>();
    258 //        try {
    259 //            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
    260 //            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    261 //            for (PropertyDescriptor property : propertyDescriptors) {
    262 //                String key = property.getName();
    263 //                // 过滤class属性
    264 //                if (!key.equals("class")) {
    265 //                    // 得到property对应的getter方法
    266 //                    Method getter = property.getReadMethod();
    267 //                    Object value = getter.invoke(obj);
    268 //
    269 //                    map.put(key, value);
    270 //                }
    271 //            }
    272 //        } catch (Exception e) {
    273 //            logger.error("transBean2Map Error {}", e);
    274 //        }
    275 //        return map;
    276     }
    277 
    278     /**
    279      * 将两个对象集合合并,并且转换为Map集合
    280      *
    281      * @param listA 对象集合A
    282      * @param listB 对象集合B
    283      * @param key   根据对象中的哪个值进行合并
    284      * @return 合并后的Map集合
    285      */
    286     public static List<Map<String, Object>> mergeListBeanToMap(List<?> listA, List<?> listB, String key) {
    287         List<Map<String, Object>> list = new ArrayList<>();
    288         for (Object objA : listA) {
    289             //将对象转换为Map
    290             Map<String, Object> mapA = beanToMap(objA);
    291             for (Object objB : listB) {
    292                 //将对象转换为Map
    293                 Map<String, Object> mapB = beanToMap(objB);
    294                 //如果对象A和对象B的值一直,则合并两个对象Map
    295                 if (mapA.get(key).equals(mapB.get(key))) {
    296                     mapA.putAll(mapB);
    297                 }
    298             }
    299             //如果集合中不存在Map,则往List中追加合并后的Map
    300             if (!list.contains(mapA)) {
    301                 list.add(mapA);
    302             }
    303         }
    304         return list;
    305     }
    306 
    307     /**
    308      * 将两个对象转换为map并做合并操作
    309      *
    310      * @param objA 对象A
    311      * @param objB 对象B
    312      * @param key  根据什么属性合并,属性名
    313      * @return 合并后的Map
    314      */
    315     public static Map<String, Object> mergeBeanToMap(Object objA, Object objB, String key) {
    316         if (objA == null) {
    317             return null;
    318         }
    319         Map<String, Object> mapA = beanToMap(objA);
    320         if (objB == null) {
    321             return mapA;
    322         }
    323         Map<String, Object> mapB = beanToMap(objB);
    324         if (mapA.get(key).equals(mapB.get(key))) {
    325             mapA.putAll(mapB);
    326         }
    327         return mapA;
    328     }
    329 
    330     /**
    331      * 把source和target相同属性的value复制到target中
    332      *
    333      * @param source 准备赋值对象
    334      * @param target 被赋值对象
    335      * @throws BeansException
    336      */
    337     public static void copyNotNullProperties(Object source, Object target) throws BeansException {
    338         BeanCopier noneNullBeanCopier = getNoneNullBeanCopier(source.getClass(), target.getClass());
    339         noneNullBeanCopier.copy(source, target, null);
    340 //        copyProperties(source, target, null, null);
    341     }
    342 
    343     public static void copyNotNullProperties(Object source, Object target, String... ignoreProperties) throws BeansException {
    344         copyProperties(source, target, null, ignoreProperties);
    345     }
    346 
    347     public static <B> B copyNewInstanceProperties(Object source, Class<B> t) throws BeansException {
    348         BeanCopier beanCopier = getBeanCopier(source.getClass(), t);
    349         B instantiate = instantiate(t);
    350         beanCopier.copy(source, instantiate, null);
    351         return instantiate;
    352 //        B tObj = null;
    353 //        try {
    354 //            tObj = t.newInstance();
    355 //        } catch (InstantiationException | IllegalAccessException e) {
    356 //            logger.error("copyNewInstanceProperties Error {}", e);
    357 //        }
    358 //        copyProperties(source, tObj);
    359 //        return tObj;
    360     }
    361 
    362     private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties) throws BeansException {
    363 
    364         Assert.notNull(source, "Source must not be null");
    365         Assert.notNull(target, "Target must not be null");
    366 
    367         Class<?> actualEditable = target.getClass();
    368         if (editable != null) {
    369             if (!editable.isInstance(target)) {
    370                 throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
    371                         "] not assignable to Editable class [" + editable.getName() + "]");
    372             }
    373             actualEditable = editable;
    374         }
    375         PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
    376         List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
    377 
    378         for (PropertyDescriptor targetPd : targetPds) {
    379             Method writeMethod = targetPd.getWriteMethod();
    380             if (writeMethod != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
    381                 PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
    382                 if (sourcePd != null) {
    383                     Method readMethod = sourcePd.getReadMethod();
    384                     if (readMethod != null &&
    385                             ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
    386                         try {
    387                             if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
    388                                 readMethod.setAccessible(true);
    389                             }
    390                             Object value = readMethod.invoke(source);
    391                             if (value != null) {  //只拷贝不为null的属性
    392                                 if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
    393                                     writeMethod.setAccessible(true);
    394                                 }
    395                                 writeMethod.invoke(target, value);
    396                             }
    397                         } catch (Throwable ex) {
    398                             throw new FatalBeanException(
    399                                     "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
    400                         }
    401                     }
    402                 }
    403             }
    404         }
    405     }
    406 }
      1 //
      2 // Source code recreated from a .class file by IntelliJ IDEA
      3 // (powered by Fernflower decompiler)
      4 //
      5 
      6 package com.zhouyy.netBank.framework.cglib.beans;
      7 
      8 import org.springframework.asm.ClassVisitor;
      9 import org.springframework.asm.Label;
     10 import org.springframework.asm.Type;
     11 import org.springframework.cglib.core.*;
     12 
     13 import java.beans.PropertyDescriptor;
     14 import java.lang.reflect.Modifier;
     15 import java.security.ProtectionDomain;
     16 import java.util.HashMap;
     17 import java.util.Map;
     18 
     19 public abstract class BeanCopier {
     20     private static final BeanCopier.BeanCopierKey KEY_FACTORY = (BeanCopier.BeanCopierKey) KeyFactory.create(BeanCopier.BeanCopierKey.class);
     21     private static final Type CONVERTER = TypeUtils.parseType("org.springframework.cglib.core.Converter");
     22     private static final Type BEAN_COPIER = TypeUtils.parseType(BeanCopier.class.getName());
     23     private static final Signature COPY;
     24     private static final Signature CONVERT;
     25 
     26     public BeanCopier() {
     27     }
     28 
     29     public static BeanCopier create(Class source, Class target, boolean useConverter) {
     30         BeanCopier.Generator gen = new BeanCopier.Generator();
     31         gen.setSource(source);
     32         gen.setTarget(target);
     33         gen.setUseConverter(useConverter);
     34         return gen.create();
     35     }
     36 
     37     public static BeanCopier create(Class source, Class target, boolean useConverter, boolean useNoneNull) {
     38         BeanCopier.Generator gen = new BeanCopier.Generator();
     39         gen.setSource(source);
     40         gen.setTarget(target);
     41         gen.setUseConverter(useConverter);
     42         gen.setUseNoneNull(useNoneNull);
     43         return gen.create();
     44     }
     45 
     46     public abstract void copy(Object var1, Object var2, Converter var3);
     47 
     48     static {
     49         COPY = new Signature("copy", Type.VOID_TYPE, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER});
     50         CONVERT = TypeUtils.parseSignature("Object convert(Object, Class, Object)");
     51     }
     52 
     53     public static class Generator extends AbstractClassGenerator {
     54         private static final Source SOURCE = new Source(BeanCopier.class.getName());
     55         private Class source;
     56         private Class target;
     57         //使用转换器
     58         private boolean useConverter;
     59         //使用非空判断
     60         private boolean useNoneNull;
     61 
     62         public Generator() {
     63             super(SOURCE);
     64         }
     65 
     66         public void setSource(Class source) {
     67             if (!Modifier.isPublic(source.getModifiers())) {
     68                 this.setNamePrefix(source.getName());
     69             }
     70 
     71             this.source = source;
     72         }
     73 
     74         public void setTarget(Class target) {
     75             if (!Modifier.isPublic(target.getModifiers())) {
     76                 this.setNamePrefix(target.getName());
     77             }
     78 
     79             this.target = target;
     80         }
     81 
     82 
     83         public void setUseNoneNull(boolean useNoneNull) {
     84             this.useNoneNull = useNoneNull;
     85         }
     86 
     87         public void setUseConverter(boolean useConverter) {
     88             this.useConverter = useConverter;
     89         }
     90 
     91         protected ClassLoader getDefaultClassLoader() {
     92             return this.source.getClassLoader();
     93         }
     94 
     95         protected ProtectionDomain getProtectionDomain() {
     96             return ReflectUtils.getProtectionDomain(this.source);
     97         }
     98 
     99         public BeanCopier create() {
    100             Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter,this.useNoneNull);
    101             return (BeanCopier)super.create(key);
    102         }
    103 
    104         public void generateClass(ClassVisitor v) {
    105             Type sourceType = Type.getType(source);
    106             Type targetType = Type.getType(target);
    107             ClassEmitter ce = new ClassEmitter(v);
    108             ce.begin_class(Constants.V1_7, Constants.ACC_PUBLIC, getClassName(), BEAN_COPIER, null, Constants.SOURCE_FILE);
    109 
    110             EmitUtils.null_constructor(ce);
    111             CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, COPY, null);
    112             PropertyDescriptor[] getters = ReflectUtils.getBeanGetters(source);
    113             PropertyDescriptor[] setters = ReflectUtils.getBeanSetters(target);
    114             Map<Object, Object> names = new HashMap<>();
    115 
    116             for (int i = 0; i < getters.length; ++i) {
    117                 names.put(getters[i].getName(), getters[i]);
    118             }
    119 
    120             Local targetLocal = e.make_local();
    121             Local sourceLocal = e.make_local();
    122             if (this.useConverter) {
    123                 e.load_arg(1);
    124                 e.checkcast(targetType);
    125                 e.store_local(targetLocal);
    126                 e.load_arg(0);
    127                 e.checkcast(sourceType);
    128                 e.store_local(sourceLocal);
    129             } else {
    130                 e.load_arg(1);
    131                 e.checkcast(targetType);
    132                 e.load_arg(0);
    133                 e.checkcast(sourceType);
    134             }
    135 
    136             for (int i = 0; i < setters.length; ++i) {
    137                 PropertyDescriptor setter = setters[i];
    138                 PropertyDescriptor getter = (PropertyDescriptor) names.get(setter.getName());
    139                 if (getter != null) {
    140                     Class<?> returnType = getter.getReadMethod().getReturnType();
    141                     //是否为基本数据类型 true是,false否
    142                     boolean isPrimitive = returnType.isPrimitive();
    143                     MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod());
    144                     MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod());
    145                     Type setterType = write.getSignature().getArgumentTypes()[0];
    146                     if (this.useConverter) {
    147                         Label start = null;
    148                         if (this.useNoneNull && !isPrimitive) {
    149                             //将sourceLocal压入栈顶,以便在if处能获取到source对象的变量
    150                             e.load_local(sourceLocal);
    151                             //创建标签
    152                             start = e.make_label();
    153                             //调用getter方法,获取值
    154                             e.invoke(read);
    155                             //进行非空判断
    156                             e.ifnull(start);
    157                         }
    158                         e.load_local(targetLocal);
    159                         e.load_arg(2);
    160                         e.load_local(sourceLocal);
    161                         e.invoke(read);
    162                         e.box(read.getSignature().getReturnType());
    163                         EmitUtils.load_class(e, setterType);
    164                         e.push(write.getSignature().getName());
    165                         e.invoke_interface(BeanCopier.CONVERTER, BeanCopier.CONVERT);
    166                         e.unbox_or_zero(setterType);
    167                         e.invoke(write);
    168 
    169                         if (start != null) {
    170                             //结束
    171                             e.mark(start);
    172                         }
    173                     } else if (compatible(getter, setter)) {
    174                         //如果是非空复制
    175                         Label start = null;
    176                         if (this.useNoneNull && !isPrimitive) {
    177                             //复制栈顶并进行压栈
    178                             e.dup();
    179                             //创建标签
    180                             start = e.make_label();
    181                             //调用getter方法,获取值
    182                             e.invoke(read);
    183                             //进行非空判断
    184                             e.ifnull(start);
    185                         }
    186                         e.dup2();
    187                         e.invoke(read);
    188                         e.invoke(write);
    189                         if (start != null) {
    190                             //结束
    191                             e.mark(start);
    192                         }
    193                     }
    194                 }
    195             }
    196             e.return_value();
    197             e.end_method();
    198             ce.end_class();
    199         }
    200 
    201         private static boolean compatible(PropertyDescriptor getter, PropertyDescriptor setter) {
    202             return setter.getPropertyType().isAssignableFrom(getter.getPropertyType());
    203         }
    204 
    205         protected Object firstInstance(Class type) {
    206             return ReflectUtils.newInstance(type);
    207         }
    208 
    209         protected Object nextInstance(Object instance) {
    210             return instance;
    211         }
    212     }
    213 
    214     interface BeanCopierKey {
    215         Object newInstance(String var1, String var2, boolean var3, boolean useNoneNull);
    216     }
    217 }
     1 package com.zhouyy.netBank.framework.cglib.beans;
     2 
     3 import java.math.BigDecimal;
     4 import java.math.BigInteger;
     5 
     6 /**
     7  * 基础数据类型转换,在BeanMapEmitter使用cglib生成的代码中使用该类
     8  *
     9  * @author zhoul
    10  * create time 2019-06-20
    11  */
    12 public abstract class BasicDataCast {
    13 
    14     public static Object cast(Object source, Class target) {
    15         if(source == null){
    16             return null;
    17         }
    18         // 如果类型一致,则直接返回
    19         if (source.getClass() == target) {
    20             return source;
    21         }
    22         if (source instanceof Character) {
    23             Character character = (Character) source;
    24             if (target == String.class) {
    25                 return character.toString();
    26             }
    27         } else if (source instanceof CharSequence) {
    28             CharSequence character = (CharSequence) source;
    29             if (target == String.class) {
    30                 return character.toString();
    31             }
    32         } else if (source instanceof Number) {
    33             Number number = (Number) source;
    34             if (target == BigDecimal.class) {
    35                 return BigDecimal.valueOf(number.doubleValue());
    36             } else if (target == BigInteger.class) {
    37                 return BigInteger.valueOf(number.longValue());
    38             } else if (target == Long.class) {
    39                 return number.longValue();
    40             } else if (target == Integer.class) {
    41                 return number.intValue();
    42             } else if (target == Double.class) {
    43                 return number.doubleValue();
    44             } else if (target == Float.class) {
    45                 return number.floatValue();
    46             } else if (target == Short.class) {
    47                 return number.shortValue();
    48             } else if (target == Byte.class) {
    49                 return number.byteValue();
    50             }else if (target == String.class) {
    51                 return number.toString();
    52             }
    53         }
    54         return source;
    55     }
    56 }
      1 package com.zhouyy.netBank.framework.cglib.beans;
      2 
      3 import org.springframework.asm.ClassVisitor;
      4 import org.springframework.cglib.core.AbstractClassGenerator;
      5 import org.springframework.cglib.core.KeyFactory;
      6 import org.springframework.cglib.core.ReflectUtils;
      7 
      8 import java.security.ProtectionDomain;
      9 import java.util.*;
     10 
     11 /**
     12  * A <code>Map</code>-based view of a JavaBean.  The default set of keys is the
     13  * union of all property names (getters or setters). An attempt to set
     14  * a read-only property will be ignored, and write-only properties will
     15  * be returned as <code>null</code>. Removal of objects is not a
     16  * supported (the key set is fixed).
     17  *
     18  * @author Chris Nokleberg
     19  * @author zhoul
     20  */
     21 abstract public class BeanMap implements Map {
     22     /**
     23      * Limit the properties reflected in the key set of the map
     24      * to readable properties.
     25      *
     26      * @see BeanMap.Generator#setRequire
     27      */
     28     public static final int REQUIRE_GETTER = 1;
     29 
     30     /**
     31      * Limit the properties reflected in the key set of the map
     32      * to writable properties.
     33      *
     34      * @see BeanMap.Generator#setRequire
     35      */
     36     public static final int REQUIRE_SETTER = 2;
     37 
     38     /**
     39      * Helper method to create a new <code>BeanMap</code>.  For finer
     40      * control over the generated instance, use a new instance of
     41      * <code>BeanMap.Generator</code> instead of this static method.
     42      *
     43      * @param bean the JavaBean underlying the map
     44      * @return a new <code>BeanMap</code> instance
     45      */
     46     public static BeanMap create(Object bean) {
     47         Generator gen = new Generator();
     48         gen.setBean(bean);
     49         return gen.create();
     50     }
     51 
     52     /**
     53      * 创建对象
     54      *
     55      * @param bean
     56      * @param ignoreKeyCase 是否忽略KEY的大小写,要与putAllIgnoreKeyCase配合使用
     57      * @return
     58      */
     59     public static BeanMap create(Object bean, boolean ignoreKeyCase) {
     60         Generator gen = new Generator();
     61         gen.setBean(bean);
     62         gen.setIgnoreKeyCase(ignoreKeyCase);
     63         return gen.create();
     64     }
     65 
     66     public static class Generator extends AbstractClassGenerator {
     67         private static final Source SOURCE = new Source(BeanMap.class.getName());
     68 
     69         private static final BeanMapKey KEY_FACTORY =
     70                 (BeanMapKey) KeyFactory.create(BeanMapKey.class, KeyFactory.CLASS_BY_NAME);
     71 
     72         interface BeanMapKey {
     73             public Object newInstance(Class type, int require, boolean ignoreKeyCase);
     74         }
     75 
     76         private Object bean;
     77         private Class beanClass;
     78         private int require;
     79         private boolean ignoreKeyCase;
     80 
     81         public Generator() {
     82             super(SOURCE);
     83         }
     84 
     85         public void setIgnoreKeyCase(boolean ignoreKeyCase) {
     86             this.ignoreKeyCase = ignoreKeyCase;
     87         }
     88 
     89         /**
     90          * Set the bean that the generated map should reflect. The bean may be swapped
     91          * out for another bean of the same type using {@link #setBean}.
     92          * Calling this method overrides any value previously set using {@link #setBeanClass}.
     93          * You must call either this method or {@link #setBeanClass} before {@link #create}.
     94          *
     95          * @param bean the initial bean
     96          */
     97         public void setBean(Object bean) {
     98             this.bean = bean;
     99             if (bean != null)
    100                 beanClass = bean.getClass();
    101         }
    102 
    103         /**
    104          * Set the class of the bean that the generated map should support.
    105          * You must call either this method or {@link #setBeanClass} before {@link #create}.
    106          *
    107          * @param beanClass the class of the bean
    108          */
    109         public void setBeanClass(Class beanClass) {
    110             this.beanClass = beanClass;
    111         }
    112 
    113         /**
    114          * Limit the properties reflected by the generated map.
    115          *
    116          * @param require any combination of {@link #REQUIRE_GETTER} and
    117          *                {@link #REQUIRE_SETTER}; default is zero (any property allowed)
    118          */
    119         public void setRequire(int require) {
    120             this.require = require;
    121         }
    122 
    123         protected ClassLoader getDefaultClassLoader() {
    124             return beanClass.getClassLoader();
    125         }
    126 
    127         protected ProtectionDomain getProtectionDomain() {
    128             return ReflectUtils.getProtectionDomain(beanClass);
    129         }
    130 
    131         /**
    132          * Create a new instance of the <code>BeanMap</code>. An existing
    133          * generated class will be reused if possible.
    134          */
    135         public BeanMap create() {
    136             if (beanClass == null) {
    137                 throw new IllegalArgumentException("Class of bean unknown");
    138             }
    139             setNamePrefix(beanClass.getName());
    140             return (BeanMap) super.create(KEY_FACTORY.newInstance(beanClass, require, ignoreKeyCase));
    141         }
    142 
    143         public void generateClass(ClassVisitor v) throws Exception {
    144             new BeanMapEmitter(v, getClassName(), beanClass, require, ignoreKeyCase);
    145         }
    146 
    147         protected Object firstInstance(Class type) {
    148             return ((BeanMap) ReflectUtils.newInstance(type)).newInstance(bean);
    149         }
    150 
    151         protected Object nextInstance(Object instance) {
    152             return ((BeanMap) instance).newInstance(bean);
    153         }
    154     }
    155 
    156     /**
    157      * Create a new <code>BeanMap</code> instance using the specified bean.
    158      * This is faster than using the {@link #create} static method.
    159      *
    160      * @param bean the JavaBean underlying the map
    161      * @return a new <code>BeanMap</code> instance
    162      */
    163     abstract public BeanMap newInstance(Object bean);
    164 
    165     /**
    166      * Get the type of a property.
    167      *
    168      * @param name the name of the JavaBean property
    169      * @return the type of the property, or null if the property does not exist
    170      */
    171     abstract public Class getPropertyType(String name);
    172 
    173     protected Object bean;
    174 
    175     protected BeanMap() {
    176     }
    177 
    178     protected BeanMap(Object bean) {
    179         setBean(bean);
    180     }
    181 
    182     public Object get(Object key) {
    183         return get(bean, key);
    184     }
    185 
    186     public Object put(Object key, Object value) {
    187         return put(bean, key, value);
    188     }
    189 
    190     /**
    191      * Get the property of a bean. This allows a <code>BeanMap</code>
    192      * to be used statically for multiple beans--the bean instance tied to the
    193      * map is ignored and the bean passed to this method is used instead.
    194      *
    195      * @param bean the bean to query; must be compatible with the type of
    196      *             this <code>BeanMap</code>
    197      * @param key  must be a String
    198      * @return the current value, or null if there is no matching property
    199      */
    200     abstract public Object get(Object bean, Object key);
    201 
    202     /**
    203      * Set the property of a bean. This allows a <code>BeanMap</code>
    204      * to be used statically for multiple beans--the bean instance tied to the
    205      * map is ignored and the bean passed to this method is used instead.
    206      *
    207      * @param key must be a String
    208      * @return the old value, if there was one, or null
    209      */
    210     abstract public Object put(Object bean, Object key, Object value);
    211 
    212     /**
    213      * Change the underlying bean this map should use.
    214      *
    215      * @param bean the new JavaBean
    216      * @see #getBean
    217      */
    218     public void setBean(Object bean) {
    219         this.bean = bean;
    220     }
    221 
    222     /**
    223      * Return the bean currently in use by this map.
    224      *
    225      * @return the current JavaBean
    226      * @see #setBean
    227      */
    228     public Object getBean() {
    229         return bean;
    230     }
    231 
    232     public void clear() {
    233         throw new UnsupportedOperationException();
    234     }
    235 
    236     public boolean containsKey(Object key) {
    237         return keySet().contains(key);
    238     }
    239 
    240     public boolean containsValue(Object value) {
    241         for (Iterator it = keySet().iterator(); it.hasNext(); ) {
    242             Object v = get(it.next());
    243             if (((value == null) && (v == null)) || (value != null && value.equals(v)))
    244                 return true;
    245         }
    246         return false;
    247     }
    248 
    249     public int size() {
    250         return keySet().size();
    251     }
    252 
    253     public boolean isEmpty() {
    254         return size() == 0;
    255     }
    256 
    257     public Object remove(Object key) {
    258         throw new UnsupportedOperationException();
    259     }
    260 
    261     public void putAll(Map t) {
    262         for (Iterator it = t.keySet().iterator(); it.hasNext(); ) {
    263             Object key = it.next();
    264             put(key, t.get(key));
    265         }
    266     }
    267 
    268     public boolean equals(Object o) {
    269         if (o == null || !(o instanceof Map)) {
    270             return false;
    271         }
    272         Map other = (Map) o;
    273         if (size() != other.size()) {
    274             return false;
    275         }
    276         for (Iterator it = keySet().iterator(); it.hasNext(); ) {
    277             Object key = it.next();
    278             if (!other.containsKey(key)) {
    279                 return false;
    280             }
    281             Object v1 = get(key);
    282             Object v2 = other.get(key);
    283             if (!((v1 == null) ? v2 == null : v1.equals(v2))) {
    284                 return false;
    285             }
    286         }
    287         return true;
    288     }
    289 
    290     public int hashCode() {
    291         int code = 0;
    292         for (Iterator it = keySet().iterator(); it.hasNext(); ) {
    293             Object key = it.next();
    294             Object value = get(key);
    295             code += ((key == null) ? 0 : key.hashCode()) ^
    296                     ((value == null) ? 0 : value.hashCode());
    297         }
    298         return code;
    299     }
    300 
    301     // TODO: optimize
    302     public Set entrySet() {
    303         HashMap<Object, Object> copy = new HashMap<>();
    304         for (Object key : keySet()) {
    305             copy.put(key, get(key));
    306         }
    307         return Collections.unmodifiableMap(copy).entrySet();
    308     }
    309 
    310     public Collection values() {
    311         Set keys = keySet();
    312         List<Object> values = new ArrayList<>(keys.size());
    313         for (Object key : keys) {
    314             values.add(get(key));
    315         }
    316         return Collections.unmodifiableCollection(values);
    317     }
    318 
    319     /*
    320      * @see java.util.AbstractMap#toString
    321      */
    322     public String toString() {
    323         StringBuffer sb = new StringBuffer();
    324         sb.append('{');
    325         for (Iterator it = keySet().iterator(); it.hasNext(); ) {
    326             Object key = it.next();
    327             sb.append(key);
    328             sb.append('=');
    329             sb.append(get(key));
    330             if (it.hasNext()) {
    331                 sb.append(", ");
    332             }
    333         }
    334         sb.append('}');
    335         return sb.toString();
    336     }
    337 }
      1 package com.zhouyy.netBank.framework.cglib.beans;
      2 
      3 import org.springframework.asm.ClassVisitor;
      4 import org.springframework.asm.Label;
      5 import org.springframework.asm.Type;
      6 import org.springframework.cglib.beans.FixedKeySet;
      7 import org.springframework.cglib.core.*;
      8 import org.springframework.util.StringUtils;
      9 
     10 import java.beans.PropertyDescriptor;
     11 import java.util.HashMap;
     12 import java.util.Iterator;
     13 import java.util.Locale;
     14 import java.util.Map;
     15 
     16 class BeanMapEmitter extends ClassEmitter {
     17     private static final Type BEAN_MAP = TypeUtils.parseType(BeanMap.class.getName());
     18     private static final Type FIXED_KEY_SET = TypeUtils.parseType(FixedKeySet.class.getName());
     19     private static final Signature CSTRUCT_OBJECT = TypeUtils.parseConstructor("Object");
     20     private static final Signature CSTRUCT_STRING_ARRAY = TypeUtils.parseConstructor("String[]");
     21     private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object, Object)");
     22     private static final Signature BEAN_MAP_PUT = TypeUtils.parseSignature("Object put(Object, Object, Object)");
     23     private static final Signature KEY_SET = TypeUtils.parseSignature("java.util.Set keySet()");
     24     private static final Signature NEW_INSTANCE = new Signature("newInstance", BEAN_MAP, new Type[]{Constants.TYPE_OBJECT});
     25     private static final Signature GET_PROPERTY_TYPE = TypeUtils.parseSignature("Class getPropertyType(String)");
     26     private static final Signature CAST_DATA_TYPE = TypeUtils.parseSignature("Object cast(Object,Class)");
     27     private static final Signature TO_LOWER_CASE = TypeUtils.parseSignature("String toLowerCase()");
     28     private static final Type TYPE_BASIC_DATA_CAST = TypeUtils.parseType(BasicDataCast.class.getName());
     29     private final boolean ignoreKeyCase;
     30 
     31     public BeanMapEmitter(ClassVisitor v, String className, Class type, int require, boolean ignoreKeyCase) {
     32         super(v);
     33         this.ignoreKeyCase = ignoreKeyCase;
     34         begin_class(Constants.V1_7, Constants.ACC_PUBLIC, className, BEAN_MAP, null, Constants.SOURCE_FILE);
     35         EmitUtils.null_constructor(this);
     36         EmitUtils.factory_method(this, NEW_INSTANCE);
     37         generateConstructor();
     38 
     39         Map getters = makePropertyMap(ReflectUtils.getBeanGetters(type));
     40         Map setters = makePropertyMap(ReflectUtils.getBeanSetters(type));
     41         Map<Object, Object> allProps = new HashMap<>();
     42         allProps.putAll(getters);
     43         allProps.putAll(setters);
     44 
     45         if (require != 0) {
     46             for (Iterator it = allProps.keySet().iterator(); it.hasNext(); ) {
     47                 String name = (String) it.next();
     48                 if ((((require & BeanMap.REQUIRE_GETTER) != 0) && !getters.containsKey(name)) ||
     49                         (((require & BeanMap.REQUIRE_SETTER) != 0) && !setters.containsKey(name))) {
     50                     it.remove();
     51                     getters.remove(name);
     52                     setters.remove(name);
     53                 }
     54             }
     55         }
     56         generateGet(type, getters);
     57         generatePut(type, setters);
     58 
     59         String[] allNames = getNames(allProps);
     60         generateKeySet(allNames);
     61         generateGetPropertyType(allProps, allNames);
     62         end_class();
     63     }
     64 
     65     private String lowerCaseName(String name) {
     66         return name.toLowerCase(Locale.US);
     67     }
     68 
     69     private String underscoreName(String name) {
     70         if (!StringUtils.hasLength(name)) {
     71             return "";
     72         }
     73         StringBuilder result = new StringBuilder();
     74         result.append(lowerCaseName(name.substring(0, 1)));
     75         for (int i = 1; i < name.length(); i++) {
     76             String s = name.substring(i, i + 1);
     77             String slc = lowerCaseName(s);
     78             if (!s.equals(slc)) {
     79                 result.append("_").append(slc);
     80             } else {
     81                 result.append(s);
     82             }
     83         }
     84         return result.toString();
     85     }
     86 
     87     private Map makePropertyMap(PropertyDescriptor[] props) {
     88         Map<Object, Object> names = new HashMap<>();
     89         for (PropertyDescriptor pd : props) {
     90             if (ignoreKeyCase) {
     91                 names.put(lowerCaseName(pd.getName()), pd);
     92                 String underscoredName = underscoreName(pd.getName());
     93                 if (!lowerCaseName(pd.getName()).equals(underscoredName)) {
     94                     names.put(underscoredName, pd);
     95                 }
     96             } else {
     97                 names.put(pd.getName(), pd);
     98             }
     99         }
    100         return names;
    101     }
    102 
    103     @SuppressWarnings("ToArrayCallWithZeroLengthArrayArgument")
    104     private String[] getNames(Map propertyMap) {
    105         return (String[]) propertyMap.keySet().toArray(new String[propertyMap.size()]);
    106     }
    107 
    108     private void generateConstructor() {
    109         CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT, null);
    110         e.load_this();
    111         e.load_arg(0);
    112         e.super_invoke_constructor(CSTRUCT_OBJECT);
    113         e.return_value();
    114         e.end_method();
    115     }
    116 
    117     private void generateGet(Class type, final Map getters) {
    118         final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null);
    119         e.load_arg(0);
    120         e.checkcast(Type.getType(type));
    121         e.load_arg(1);
    122         e.checkcast(Constants.TYPE_STRING);
    123         EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
    124             public void processCase(Object key, Label end) {
    125                 PropertyDescriptor pd = (PropertyDescriptor) getters.get(key);
    126                 MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod());
    127                 e.invoke(method);
    128                 e.box(method.getSignature().getReturnType());
    129                 e.return_value();
    130             }
    131 
    132             public void processDefault() {
    133                 e.aconst_null();
    134                 e.return_value();
    135             }
    136         });
    137         e.end_method();
    138     }
    139 
    140     private void generatePut(Class type, final Map setters) {
    141         final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_PUT, null);
    142         e.load_arg(0);
    143         e.checkcast(Type.getType(type));
    144         e.load_arg(1);
    145         e.checkcast(Constants.TYPE_STRING);
    146         //是否忽略大小写
    147         if (ignoreKeyCase) {
    148             e.invoke_virtual(Constants.TYPE_STRING, TO_LOWER_CASE);
    149         }
    150         EmitUtils.string_switch(e, getNames(setters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
    151             public void processCase(Object key, Label end) {
    152                 PropertyDescriptor pd = (PropertyDescriptor) setters.get(key);
    153                 if (pd.getReadMethod() == null) {
    154                     e.aconst_null();
    155                 } else {
    156                     MethodInfo read = ReflectUtils.getMethodInfo(pd.getReadMethod());
    157                     e.dup();
    158                     e.invoke(read);
    159                     e.box(read.getSignature().getReturnType());
    160                 }
    161                 e.swap(); // move old value behind bean
    162                 e.load_arg(2);
    163 
    164                 MethodInfo write = ReflectUtils.getMethodInfo(pd.getWriteMethod());
    165                 Type setterType = write.getSignature().getArgumentTypes()[0];
    166                 EmitUtils.load_class(e, setterType);
    167                 e.invoke_static(TYPE_BASIC_DATA_CAST, CAST_DATA_TYPE);
    168                 e.box(Constants.TYPE_OBJECT);
    169 
    170                 e.unbox(write.getSignature().getArgumentTypes()[0]);
    171                 e.invoke(write);
    172                 e.return_value();
    173             }
    174 
    175             public void processDefault() {
    176                 // fall-through
    177             }
    178         });
    179         e.aconst_null();
    180         e.return_value();
    181         e.end_method();
    182     }
    183 
    184     private void generateKeySet(String[] allNames) {
    185         // static initializer
    186         declare_field(Constants.ACC_STATIC | Constants.ACC_PRIVATE, "keys", FIXED_KEY_SET, null);
    187 
    188         CodeEmitter e = begin_static();
    189         e.new_instance(FIXED_KEY_SET);
    190         e.dup();
    191         EmitUtils.push_array(e, allNames);
    192         e.invoke_constructor(FIXED_KEY_SET, CSTRUCT_STRING_ARRAY);
    193         e.putfield("keys");
    194         e.return_value();
    195         e.end_method();
    196 
    197         // keySet
    198         e = begin_method(Constants.ACC_PUBLIC, KEY_SET, null);
    199         e.load_this();
    200         e.getfield("keys");
    201         e.return_value();
    202         e.end_method();
    203     }
    204 
    205     private void generateGetPropertyType(final Map allProps, String[] allNames) {
    206         final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_TYPE, null);
    207         e.load_arg(0);
    208         EmitUtils.string_switch(e, allNames, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
    209             public void processCase(Object key, Label end) {
    210                 PropertyDescriptor pd = (PropertyDescriptor) allProps.get(key);
    211                 EmitUtils.load_class(e, Type.getType(pd.getPropertyType()));
    212                 e.return_value();
    213             }
    214 
    215             public void processDefault() {
    216                 e.aconst_null();
    217                 e.return_value();
    218             }
    219         });
    220         e.end_method();
    221     }
    222 }
  • 相关阅读:
    git常用命令
    IDEA设置
    redis基础
    SQL 基础
    springboot 配置日志 打印不出来sql
    阿里巴巴开发规范最新版
    rabbitmq用户权限
    rabbitMQ配置文件
    RabbitMQ配置文件(rabbitmq.conf)
    C++模板编程:如何使非通用的模板函数实现声明和定义分离
  • 原文地址:https://www.cnblogs.com/chinazhou-wang/p/11815664.html
Copyright © 2020-2023  润新知