您的位置:首页 > 财经 > 产业 > 网络营销推广方法是对什么和什么的合理利用_室内设计公司排行_企业网站建设价格_广州的百度推广公司

网络营销推广方法是对什么和什么的合理利用_室内设计公司排行_企业网站建设价格_广州的百度推广公司

2025/1/9 19:03:49 来源:https://blog.csdn.net/vipshop_fin_dev/article/details/144355696  浏览:    关键词:网络营销推广方法是对什么和什么的合理利用_室内设计公司排行_企业网站建设价格_广州的百度推广公司
网络营销推广方法是对什么和什么的合理利用_室内设计公司排行_企业网站建设价格_广州的百度推广公司

问题描述

apache的BeanUtils工具集中用来把map对象转换为java对象的BeanUtils#populate方法会因为单例的原因其转换器Converter被相互污染覆盖问题

maven依赖

<dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.4</version>
</dependency>

方法源码


public static void populate(final Object bean, final Map<String, ? extends Object> properties)throws IllegalAccessException, InvocationTargetException {// 源码此处获取的是单例对象BeanUtilsBean.getInstance().populate(bean, properties);
}

测试场景

场景一

map不存在属性时

测试代码

/*** map没有age属性*/
public static void test1() throws Exception {DemoObj fromObj = new DemoObj();Map<String, Object> map = Maps.newHashMap();map.put("name", "张三");BeanUtils.populate(fromObj, map);System.out.println(Thread.currentThread().getName() + ":没有age属性,转换器不生效:"+ JsonUtil.toStr(fromObj));
}

输出结果

main:没有age属性,转换器不生效:{"age":null,"name":"张三"}

场景二

map存在age属性,自带的转换器默认值为0

测试代码


/*** map存在age属性,自带的转换器默认值为0*/
public static void test2() throws Exception {DemoObj fromObj = new DemoObj();Map<String, Object> map = Maps.newHashMap();map.put("name", "李四");map.put("age", null);BeanUtils.populate(fromObj, map);System.out.println(Thread.currentThread().getName() +":自带的转换器默认值为0:"+JsonUtil.toStr(fromObj));
}

输出结果

main:自带的转换器默认值为0:{"age":0,"name":"李四"}

场景三

静态代码块注入自定义转换器,默认值设置为null

测试代码


static {ConvertUtils.register(new IntegerConverter(null), Integer.class);
}public static void test2() throws Exception {DemoObj fromObj = new DemoObj();Map<String, Object> map = Maps.newHashMap();map.put("name", "李四");map.put("age", null);BeanUtils.populate(fromObj, map);System.out.println(Thread.currentThread().getName() +":转换器默认值为:"+JsonUtil.toStr(fromObj));
}

输出结果

main:转换器默认值为:{"age":null,"name":"李四"}

场景四

在场景三的基础上,我们增加了一个转换器重新注册的函数调用,该函数会重置转换器对象

转换器重置的源代码

    public static void deregister() {ConvertUtilsBean.getInstance().deregister();}// 获取的依旧是单例对象protected static ConvertUtilsBean getInstance() {return BeanUtilsBean.getInstance().getConvertUtils();}public void deregister() {converters.clear();registerPrimitives(false);registerStandard(false, false);registerOther(true);registerArrays(false, 0);register(BigDecimal.class, new BigDecimalConverter());register(BigInteger.class, new BigIntegerConverter());}

测试代码

static {ConvertUtils.register(new IntegerConverter(null), Integer.class);
}public static void test2() throws Exception {DemoObj fromObj = new DemoObj();Map<String, Object> map = Maps.newHashMap();map.put("name", "李四");map.put("age", null);BeanUtils.populate(fromObj, map);System.out.println(Thread.currentThread().getName() +":转换器默认值为:"+JsonUtil.toStr(fromObj));
}public static void test3() throws Exception {DemoObj fromObj = new DemoObj();Map<String, Object> map = Maps.newHashMap();map.put("name", "王五");map.put("age", null);BeanUtils.populate(fromObj, map);System.out.println(Thread.currentThread().getName() + ":age被赋值默认值:"+ JsonUtil.toStr(fromObj));// 重置转换器ConvertUtils.deregister();
}public static void main(String[] args) throws Exception {new Thread(()-> {try {// 睡眠,等test2先跑完Thread.sleep(1000);test2();} catch (Exception e) {throw new RuntimeException(e);}}).start();new Thread(()-> {try {test3();} catch (Exception e) {throw new RuntimeException(e);}}).start();}

输出结果

当前线程执行时,转换器还是静态代码块所注册的默认值为null的转换器,但是在test3执行完后会重置单例的转换器对象Thread-2:age被赋值默认值:{"age":null,"name":"王五"}所以线程睡眠结束后再执行转换时,发现转换器已被污染,转换的属性默认值非预期值Thread-1:转换器默认值为:{"age":0,"name":"李四"}

场景五

在场景四的基础上重新创建一个单例对象,并且该单例提前注册一个自定义默认值为null的的转换器

新增类


public class CustBeanUtils {private static final BeanUtilsBean beanUtilsBean;public CustBeanUtils() {}public static void populate(Object bean, Map<String, ? extends Object> properties) throws Exception {beanUtilsBean.populate(bean, properties);}static {ConvertUtilsBean convertUtilsBean = new ConvertUtilsBean();convertUtilsBean.register(new IntegerConverter(null), Integer.class);beanUtilsBean = new BeanUtilsBean(convertUtilsBean, new PropertyUtilsBean());}
}

测试代码

static {ConvertUtils.register(new IntegerConverter(null), Integer.class);
}public static void test2() throws Exception {DemoObj fromObj = new DemoObj();Map<String, Object> map = Maps.newHashMap();map.put("name", "李四");map.put("age", null);BeanUtils.populate(fromObj, map);System.out.println(Thread.currentThread().getName() +":转换器默认值为:"+JsonUtil.toStr(fromObj));
}public static void test3() throws Exception {DemoObj fromObj = new DemoObj();Map<String, Object> map = Maps.newHashMap();map.put("name", "王五");map.put("age", null);BeanUtils.populate(fromObj, map);System.out.println(Thread.currentThread().getName() + ":age被赋值默认值:"+ JsonUtil.toStr(fromObj));// 重置转换器ConvertUtils.deregister();
}public static void test4() throws Exception {DemoObj fromObj = new DemoObj();Map<String, Object> map = Maps.newHashMap();map.put("name", "赵六");map.put("age", null);CustBeanUtils.populate(fromObj, map);System.out.println(Thread.currentThread().getName() + ":CustBeanUtils 新建了一个BeanUtilsBean,不受其影响,age也不会被赋值默认值0:"+ JsonUtil.toStr(fromObj));
}public static void main(String[] args) throws Exception {new Thread(()-> {try {Thread.sleep(1000);test2();} catch (Exception e) {throw new RuntimeException(e);}}).start();new Thread(()-> {try {test3();} catch (Exception e) {throw new RuntimeException(e);}}).start();new Thread(()-> {try {Thread.sleep(2000);test4();} catch (Exception e) {throw new RuntimeException(e);}}).start();}

输出结果

线程2执行时,转换器还是静态代码块所注册的默认值为null的转换器,但是在test3执行完后会重置单例的转换器对象Thread-2:age被赋值默认值:{"age":null,"name":"王五"}所以线程1睡眠结束后再执行转换时,发现转换器已被污染,转换的属性默认值非预期值Thread-1:转换器默认值为:{"age":0,"name":"李四"}由于线程3用的是一个新的单例对象,所以其转换结果并不受原生的工具集中转换器重置的函数所影响Thread-3:CustBeanUtils 新建了一个BeanUtilsBean,不受其影响,age也不会被赋值默认值0:{"age":null,"name":"赵六"}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com