前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BeanWrapper解析

BeanWrapper解析

作者头像
爱撒谎的男孩
发布2019-12-31 15:51:10
5640
发布2019-12-31 15:51:10
举报
文章被收录于专栏:码猿技术专栏码猿技术专栏

文章目录

  1. 1. 简介
  2. 2. 常用API
  3. 3. PropertyDescriptor
  4. 4. 实例

简介

  • BeanWrapper是Spring底层经常使用的一个接口,简单来说是对Bean的一种包装,包括对Bean的属性、方法,数据等。
  • 唯一的一个实现类是BeanWrapperImpl,继承和实现关系图如下:

常用API

  • public BeanWrapperImpl(Object object):指定对象构造
  • public BeanWrapperImpl(Class<?> clazz):指定Class构造,内部会通过反射调用clazz的默认无参构造方法进行实例化
  • public final Object getWrappedInstance():获取对象实例
  • public PropertyDescriptor getPropertyDescriptor(String propertyName:获取指定属性的PropertyDescriptor
  • public PropertyDescriptor[] getPropertyDescriptors():获取所有属性的PropertyDescriptor【包括继承而来的】
  • public Object getPropertyValue(String propertyName):获取指定属性的值

PropertyDescriptor

  • 简称属性描述器,是对属性的封装,包括属性的类型,值,get和set方法,可以通过属性描述器可以很简单的获取和修改对应的值。
  • 两个概念如下:
    • ReadMethod:即是对应属性的get方法
    • WriteMethod:即是对应属性的set方法

实例

  • 我们可以同BeanWrapperPropertyDescriptor可以很轻松实现属性的复制,下面是本人手写的一个复制的工具类【当然这个是很粗糙的,和BeanUtils中的copyPropreties方法不能相提并论,不喜勿喷】
代码语言:javascript
复制
/**
 * 对象复制【浅克隆】
 */
public class NewCopyUtils {
    private static final String CLASS="class";
    /**
     * 复制对象【只能复制基本数据类型,浅克隆】
     * @param source 源对象
     * @param target 目标对象
     * @param ingoreAgrs 忽略的属性
     * @throws Exception
     */
    public static void copyProperties(Object source,Object target,String... ingoreAgrs) throws Exception {
        if (source.getClass().isInterface()||target.getClass().isInterface()){
            throw new Exception("source和target不能为接口");
        }
        BeanWrapper sourceWrap = createBeanWrap(source);
        BeanWrapper targetWrap = createBeanWrap(target);
        PropertyDescriptor[] targetPds = targetWrap.getPropertyDescriptors();
        PropertyDescriptor[] sourcePds = sourceWrap.getPropertyDescriptors();
        //根据名称分组,减少一层循环
        Map<String, List<PropertyDescriptor>> map = Arrays.asList(sourcePds).parallelStream().filter(o -> !StringUtils.equals(CLASS, o.getName())).collect(Collectors.groupingBy(o -> o.getName()));
        for (int i = 0; i < targetPds.length; i++) {
            PropertyDescriptor tpd=targetPds[i];
            //去掉class属性和不要的复制的属性
            if (!StringUtils.equals(CLASS,tpd.getName())&& !Arrays.asList(ingoreAgrs).contains(tpd.getName())){
                List<PropertyDescriptor> list = map.getOrDefault(tpd.getName(), null);
                if (Objects.nonNull(list)){
                    Method writeMethod = tpd.getWriteMethod();
                    Method readMethod = list.get(0).getReadMethod();
                    if (Objects.isNull(writeMethod)&&Objects.isNull(readMethod)){
                        throw  new Exception("属性必须有get和set方法");
                    }
                    Object o = readMethod.invoke(source);
                    writeMethod.invoke(target,o);
                }
            }
        }
    }
    /**
     * 构造BeanWrapImpl
     * @param source 对象
     * @return BeanWrapper
     */
    private static BeanWrapper createBeanWrap(Object source){
        return new BeanWrapperImpl(source);
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 常用API
  • PropertyDescriptor
  • 实例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档