Spring BeanWrapper 和Java BeanInfo实现对实体Getter和Setter操作

Spring BeanWrapper

BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器,由于BeanWrapper接口是PropertyAccessor的子接口,因此其也可以设置以及访问被包装对象的属性值。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性。用户很少需要直接使用BeanWrapper进行编程。

BeanWrapper的常用实现类有BeanWrapperImpl,BeanWrapperImpl内部已经支持PropertiesEditor功能(支持将字符串直接转换为具体的属性)

类名说明是否默认内置
ByteArrayPropertyEditor将字符串转换为byte数组
ClassEditor将字符串转换为Class对象
CustomBooleanEditor将字符串转换为boolean对象
CustomCollectionEditor将字符串转换为集合对象
CustomDateEditor将字符串转换为Date对象
CustomNumberEditor将字符串转换为Number对象
FileEditor将字符串转换为java.io.File对象
InputStreamEditor将字符串转换为InputStream流对象
LocaleEditor将字符串转换为Locale对象
PatternEditor将字符串转换为java.util.regex.Pattern对象
PropertiesEditor将字符串转换为Properties对象
StringTrimmerEditor将字符串做trim操作
URLEditor将字符串转换为URL对象

如有自己个性化实现转换需求,只需要继承PropertyEditorSupport就可以了,并注入到BeanWrapper中就好

//另外的一种创建BeanWrapper方式
//PropertyAccessorFactory.forBeanPropertyAccess(target);
BeanWrapper wrapper = new BeanWrapperImpl(Person.class);
wrapper.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
wrapper.setPropertyValue("name", "XXX");
wrapper.setPropertyValue("age", 20);
wrapper.setPropertyValue("date", "2018-08-10");

BeanWrapper cityWrapper = new BeanWrapperImpl(City.class);
cityWrapper.setPropertyValue("cityCode", "421142");
cityWrapper.setPropertyValue("name", "衡阳");

wrapper.setPropertyValue("city", cityWrapper.getWrappedInstance());
Person p = (Person)wrapper.getWrappedInstance();
System.out.println(p);

Java BeanInfo

  希望提供有关其 bean 的显式信息的 bean 实现者可以提供某个 BeanInfo 类,该类实现此 BeanInfo 接口并提供有关其 bean 的方法、属性、事件等显式信息。
  bean 实现者不必提供一组完整的显式信息。可以挑选出希望提供的信息,其余部分将通过使用 bean 类方法的低级别反射和应用标准设计模式的自动分析来获得。
  有机会提供大量不同的信息作为各种 XyZDescriptor 类的一部分。但不必惊慌,真正需要的只是提供各种构造方法所需的最少核心信息。
  请参见 SimpleBeanInfo 类,它提供了用于 BeanInfo 类的一个便捷 “noop” 基类,可以为那些想要返回显式信息的特定位置重写该基类。
要学习有关 bean 的所有行为,请参见 Introspector 类。

其中getPropertyDescriptors方法就是我想要的方法

 /**
 * Returns descriptors for all properties of the bean.
 * <p>
 * If a property is indexed, then its entry in the result array
 * belongs to the {@link IndexedPropertyDescriptor} subclass
 * of the {@link PropertyDescriptor} class.
 * A client of the {@code getPropertyDescriptors} method
 * can use the {@code instanceof} operator to check
 * whether a given {@code PropertyDescriptor}
 * is an {@code IndexedPropertyDescriptor}.
 *
 * @return  an array of {@code PropertyDescriptor} objects,
 *          or {@code null} if the information is to
 *          be obtained through the automatic analysis
 */
PropertyDescriptor[] getPropertyDescriptors();

根据PropertyDescriptor我们可以获取到字段信息,字段对应的Getter和Setter方法,故就可以实现Bean转换Map,Map转换为Bean的小目标了,请看代码:

/**
 * <description>Map转换为实体对象</description>
 *
 * @param map
 * @param clazz
 * @return
 * @author: ouyp
 * @since: 2018年08月04日 下午11:42:30
 */
public <T> T map2Bean(Map<String, Object> map, Class<T> clazz) {
    T obj = BeanUtils.instantiate(clazz);
    try {
        BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
        for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
            String name = pd.getName();
            if (map.containsKey(name)) {
                pd.getWriteMethod().invoke(obj, map.get(name));
            }
        }
    } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        e.printStackTrace();
    }
    return obj;
}

/**
 * <description>实体对象转换为Map</description>
 *
 * @param t
 * @return
 * @author: ouyp
 * @since: 2018年08月04日 下午11:42:59
 */
public <T> Map<String, Object> bean2Map(T t) {
    Map<String, Object> map = new HashMap<>();
    try {
        BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass());
        for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
            String name = pd.getName();
            map.put(name, pd.getReadMethod().invoke(t));
        }
    } catch (IllegalAccessException | IntrospectionException | IllegalArgumentException | InvocationTargetException e) {
        e.printStackTrace();
    }
    return map;
}

参考链接

  1. Spring BeanWrapper分析
  2. Spring 学习 (二)__BeanWrapper及其实现
  3. java 使用BeanInfo实现bean实体与map之间的互相转换
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值