Beanutils.copyProperties( )的使用与优化
1.使用原因
因为现在都是前后端分离所以我们在响应APP端或者前端的时候会维护一套VO,那么DTO到VO的转换便是一堆get... set...这样的代码,比如好几个地方用到的话还要去复制粘贴来转换。所以这里的我就开始动脑子了。
2.解决问题
刚开始项目中是好几个地方在用,然后我就想把这段VO转换的代码抽取出来,先是想写个工具类,后来一想这是业务的代码。然后就写了一个抽象类。正好让其他接口直接继承。完美解决。
然后是发现VO转换的地方很多,有没有更方便的转换方法? 要不然一堆代码岂不是很掉价
3.使用Beanutils
这里使用的是 org.springframework.beans包下的copyProperties( )方法,他会把字段相同的Bean字段赋值,大大减少了代码量,但从其他程序员的建议说,这个操作会响应性能,数据量大的时候还没有直接get ,set性能好。
4.优化
这里是参考了这个大神的博客,ReflectASM,高性能的反射。 使用的话需要引入下面的依赖。
<!-- https://mvnrepository.com/artifact/com.esotericsoftware.reflectasm/reflectasm -->
<dependency>
<groupId>com.esotericsoftware.reflectasm</groupId>
<artifactId>reflectasm</artifactId>
<version>1.05</version>
</dependency> ReflectASM是一个很小的java类库,主要是通过asm生产类来实现java反射,执行速度非常快。
大家如果想优化的话,可以试试下面的方法。
- public static void main(String[] args) {
- User user = new User();
- //使用reflectasm生产User访问类
- MethodAccess access = MethodAccess.get(User.class);
- //invoke setName方法name值
- access.invoke(user, "setName", "张三");
- //invoke getName方法 获得值
- String name = (String)access.invoke(user, "getName", null);
- System.out.println(name);
- }
原理
上面代码的确实现反射的功能,代码主要的核心是 MethodAccess.get(User.class);
看了下源码,这段代码主要是通过asm生产一个User的处理类 UserMethodAccess(这个类主要是实现了invoke方法)的ByteCode,然后获得该对象,通过上面的invoke操作user类。
ASM反射转换:
- private static Map<Class, MethodAccess> methodMap = new HashMap<Class, MethodAccess>();
- private static Map<String, Integer> methodIndexMap = new HashMap<String, Integer>();
- private static Map<Class, List<String>> fieldMap = new HashMap<Class, List<String>>();
- public static void copyProperties(Object desc, Object orgi) {
- MethodAccess descMethodAccess = methodMap.get(desc.getClass());
- if (descMethodAccess == null) {
- descMethodAccess = cache(desc);
- }
- MethodAccess orgiMethodAccess = methodMap.get(orgi.getClass());
- if (orgiMethodAccess == null) {
- orgiMethodAccess = cache(orgi);
- }
- List<String> fieldList = fieldMap.get(orgi.getClass());
- for (String field : fieldList) {
- String getKey = orgi.getClass().getName() + "." + "get" + field;
- String setkey = desc.getClass().getName() + "." + "set" + field;
- Integer setIndex = methodIndexMap.get(setkey);
- if (setIndex != null) {
- int getIndex = methodIndexMap.get(getKey);
- // 参数一需要反射的对象
- // 参数二class.getDeclaredMethods 对应方法的index
- // 参数对三象集合
- descMethodAccess.invoke(desc, setIndex.intValue(),
- orgiMethodAccess.invoke(orgi, getIndex));
- }
- }
- }
- // 单例模式
- private static MethodAccess cache(Object orgi) {
- synchronized (orgi.getClass()) {
- MethodAccess methodAccess = MethodAccess.get(orgi.getClass());
- Field[] fields = orgi.getClass().getDeclaredFields();
- List<String> fieldList = new ArrayList<String>(fields.length);
- for (Field field : fields) {
- if (Modifier.isPrivate(field.getModifiers())
- && !Modifier.isStatic(field.getModifiers())) { // 是否是私有的,是否是静态的
- // 非公共私有变量
- String fieldName = StringUtils.capitalize(field.getName()); // 获取属性名称
- int getIndex = methodAccess.getIndex("get" + fieldName); // 获取get方法的下标
- int setIndex = methodAccess.getIndex("set" + fieldName); // 获取set方法的下标
- methodIndexMap.put(orgi.getClass().getName() + "." + "get"
- + fieldName, getIndex); // 将类名get方法名,方法下标注册到map中
- methodIndexMap.put(orgi.getClass().getName() + "." + "set"
- + fieldName, setIndex); // 将类名set方法名,方法下标注册到map中
- fieldList.add(fieldName); // 将属性名称放入集合里
- }
- }
- fieldMap.put(orgi.getClass(), fieldList); // 将类名,属性名称注册到map中
- methodMap.put(orgi.getClass(), methodAccess);
- return methodAccess;
- }
- }
参考---https://blog.csdn.net/w05980598/article/details/79134379
Beanutils.copyProperties( )的使用与优化的更多相关文章
- BeanUtils.copyProperties()方法和PropertyUtils.copyProperties()的区别
首先两者来源于同一个包: import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.Prop ...
- BeanUtils.copyProperties() 用法
BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处 ...
- java 使用BeanUtils.copyProperties(Object source,Object target) 复制字段值
BeanUtils.copyProperties(person, wsPerson);把person的字段值,复制给wsPerson // 只复制两个实体中,字段名称一样的 很有用的一个功能...
- BeanUtils.copyProperties() 用法--部分转
把一个类对象copy到另一个类对象(这两个可以不同). 1.org.apache.commons.beanutils.BeanUtils.copyProperties(dest, src) org.s ...
- BeanUtils.copyProperties与PropertyUtils.copyProperties用法及区别
一.简介: BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean 通常包含了大量的属性,很多情况下,对Jav ...
- BeanUtils.copyProperties()方法引入不同包
两个对象之间拷贝相同的属性,可以使用BeanUtils.copyProperties()方法, BeanUtils.copyProperties(obj1,obj2); 提示有三个包可选. A,选择o ...
- BeanUtils.copyProperties VS PropertyUtils.copyProperties
作为两个bean属性copy的工具类,他们被广泛使用,同时也很容易误用,给人造成困然:比如:昨天发现同事在使用BeanUtils.copyProperties copy有integer类型属性的bea ...
- 小知识点BeanUtils.copyProperties
通过BeanUtils.copyProperties可以时间拷贝对象中的值,下面的new String[]{"cid","agreeFlag"," ...
- BeanUtils.copyProperties缓解代码压力,释放双手
简单描述:之前在写代码的时候,经常把表单提交到后台的对象的参数,通过getter方法取出来,然后,再通过setter方法传递给需要的对象,代码中写了很多get set这种方法,后来听同事说,sprin ...
随机推荐
- elastalert新增自定义警告推送
举例,博主公司有自己的内部通讯工具(类似QQ),接下来用IM代称该工具.于是希望elastalert的警告推送可以支持IM的公众号群发功能. 等博主这个月知识库写了再来补充hah
- MySQL字符集及校对规则的理解
阅读目录:MySQL的字符集和校对规则 MySQL的字符集 MySQL与字符集 正确使用字符集 MySQL客户端与字符集 字符集编码转换原理 字符集常见处理操作 字符集的正确实践 MySQL的校对 ...
- Centos下添加用户并赋权
创建新用户 创建一个用户名为:linuxidc [root@localhost ~]# adduser linuxidc 为这个用户初始化密码,linux会判断密码复杂度,不过可以强行忽略: [roo ...
- 安卓手机H5底部fix定位,呼出键盘底部会上浮解决办法
<script type="text/javascript">var windowInnerHeight = window.innerHeight; //获取当前浏览器 ...
- h5py库安装问题解决
H5py官网教程完全有问题,这个大家都这么说,但是貌似问题出现在Numpy上,由于numpy的版本过高! 这里是官网的教程:http://docs.h5py.org/en/latest/build.h ...
- poi 导入Excel解析 2003 2007
Workbook wb = WorkbookFactory.create(new FileInputStream(file)); Sheet sheet = wb.getSheetAt(0);// 第 ...
- 阿里云实现putty私钥登录全过程
阿里云实现putty私钥登录全过程 1 putty生成公钥和私钥 1)putty生成公钥和私钥 记得在空白区域 滑动 2 公钥上传到阿里云 1)公钥上传 私钥存到本地 3 公钥绑定要登录的实例 4 ...
- 22.Windows及linux下gerapy使用
Windows安装 gerapy1.pip install gerapy2.gerapy init 3.cd gerapy(切换目录到gerapy文件夹)4.gerapy migrate5.gerap ...
- 销售人员的分析,也可以用类似RFM的思路吗?
本文转自知乎 作者:接地气的陈老师 ————————————————————————————————————————————————————— 有同学问:“销售人员的分析,也可以用类似RFM的思路吗, ...
- 笔记:pycharm 快捷键
[重要]pyCharm的编码一个坑: 2017-10-18 在使用pyCharm4.5,调用库bs4爬取页面时,有报错如下: UnicodeEncodeError: 'gbk' codec can't ...