beans实现的类装换工具

public class BeanUtils {

    private static final BeanCopier FAILBACK = new BeanCopier() {
        @Override
        public void copy(Object from, Object to, Converter converter) {
            throw new UnsupportedOperationException();
        }
    };

    private static ConcurrentMap<Class, ConcurrentMap<Class, BeanCopier>> beanCopierMap = new ConcurrentHashMap<>();

    /**
     * 复制属性, 会自动缓存以加快速度,建议使用传入Class的方法
     * 
     * @param src
     * @param dest
     * @return 复制的目标对象,注入如果src为null,则这里会返回null
     */
    public static Object copy(Object src, Object dest) {
        if (src == null) {
            return null;
        }
        if (dest == null) {
            throw new NullPointerException("dest is null");
        }
        ConcurrentMap<Class, BeanCopier> innerMap = beanCopierMap.get(src.getClass());
        if (innerMap == null) {
            innerMap = new ConcurrentHashMap();
            ConcurrentMap<Class, BeanCopier> temp = beanCopierMap.putIfAbsent(src.getClass(), innerMap);
            if (temp != null) {
                innerMap = temp;
            }
        }
        BeanCopier beanCopier = innerMap.get(dest.getClass());
        if (beanCopier == null) {
            if(src.getClass().getClassLoader() != dest.getClass().getClassLoader()){
                beanCopier = FAILBACK;//cglib的复制器不支持复制两个classloader不同的类(其实如果src的classloader是dest的classloader的父亲,是可以支持的,这里简化处理,只判断是不是相同)
            }else {
                beanCopier = BeanCopier.create(src.getClass(), dest.getClass(), false);
            }
            BeanCopier temp = innerMap.putIfAbsent(dest.getClass(), beanCopier);
            if (temp != null) {
                beanCopier = temp;
            }
        }
        if(beanCopier == FAILBACK){
            //当两个类的类加载器不同时,降级为使用spring BeanUtils来复制属性,这个的性能会差很多。
            org.springframework.beans.BeanUtils.copyProperties(src, dest);
        }else {
            beanCopier.copy(src, dest, null);
        }

        return dest;
    }

    /**
     * 复制属性, 会自动缓存以加快速度
     * 
     * @param src
     * @param destClass 目标类,要求该类必须有无参构造函数
     * @param <T>
     * @return
     */
    public static <T> T copy(Object src, Class<T> destClass) {
        if (src == null) {
            return null;
        }
        try {
            T dest = destClass.newInstance();
            copy(src, dest);
            return dest;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 把list中的每个对象都转换为目标类的对象
     * 
     * @param srcList
     * @param destClass
     * @param <T>
     * @return
     */
    public static <T> List<T> copyList(List<?> srcList, Class<T> destClass) {
        if (srcList == null) {
            return Collections.emptyList();
        }
        List<T> retList = new ArrayList<>();
        for (Object src : srcList) {
            T destInstance = copy(src, destClass);
            retList.add(destInstance);
        }
        return retList;
    }

    public static Map<String, Object> transBeanToMap(Object obj) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!"class".equals(key)) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    map.put(key, value);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return map;
    }

    private static class User{
        private String name;
    }

    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        Objenesis objenesis = new ObjenesisStd();
        ObjectInstantiator<User> factory = objenesis.getInstantiatorOf(User.class);
        long start = System.currentTimeMillis();
        for(int i=0;i<100000000;i++) {
//            factory.newInstance();
            objenesis.newInstance(User.class);
        }
        start = System.currentTimeMillis() - start;
        System.out.println(start);

        start = System.currentTimeMillis();
        for(int i=0;i<100000000;i++) {
            User.class.newInstance();
        }
        start = System.currentTimeMillis() - start;
        System.out.println(start);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大道至简@EveryDay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值