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反射,执行速度非常快。
大家如果想优化的话,可以试试下面的方法。
  1. public static void main(String[] args) {
  2. User user = new User();
  3. //使用reflectasm生产User访问类
  4. MethodAccess access = MethodAccess.get(User.class);
  5. //invoke setName方法name值
  6. access.invoke(user, "setName", "张三");
  7. //invoke getName方法 获得值
  8. String name = (String)access.invoke(user, "getName", null);
  9. System.out.println(name);
  10. }
原理 
   上面代码的确实现反射的功能,代码主要的核心是 MethodAccess.get(User.class); 
看了下源码,这段代码主要是通过asm生产一个User的处理类 UserMethodAccess(这个类主要是实现了invoke方法)的ByteCode,然后获得该对象,通过上面的invoke操作user类。 

ASM反射转换:

    1. private static Map<Class, MethodAccess> methodMap = new HashMap<Class, MethodAccess>();
    2. private static Map<String, Integer> methodIndexMap = new HashMap<String, Integer>();
    3. private static Map<Class, List<String>> fieldMap = new HashMap<Class, List<String>>();
    4. public static void copyProperties(Object desc, Object orgi) {
    5. MethodAccess descMethodAccess = methodMap.get(desc.getClass());
    6. if (descMethodAccess == null) {
    7. descMethodAccess = cache(desc);
    8. }
    9. MethodAccess orgiMethodAccess = methodMap.get(orgi.getClass());
    10. if (orgiMethodAccess == null) {
    11. orgiMethodAccess = cache(orgi);
    12. }
    13. List<String> fieldList = fieldMap.get(orgi.getClass());
    14. for (String field : fieldList) {
    15. String getKey = orgi.getClass().getName() + "." + "get" + field;
    16. String setkey = desc.getClass().getName() + "." + "set" + field;
    17. Integer setIndex = methodIndexMap.get(setkey);
    18. if (setIndex != null) {
    19. int getIndex = methodIndexMap.get(getKey);
    20. // 参数一需要反射的对象
    21. // 参数二class.getDeclaredMethods 对应方法的index
    22. // 参数对三象集合
    23. descMethodAccess.invoke(desc, setIndex.intValue(),
    24. orgiMethodAccess.invoke(orgi, getIndex));
    25. }
    26. }
    27. }
    28. // 单例模式
    29. private static MethodAccess cache(Object orgi) {
    30. synchronized (orgi.getClass()) {
    31. MethodAccess methodAccess = MethodAccess.get(orgi.getClass());
    32. Field[] fields = orgi.getClass().getDeclaredFields();
    33. List<String> fieldList = new ArrayList<String>(fields.length);
    34. for (Field field : fields) {
    35. if (Modifier.isPrivate(field.getModifiers())
    36. && !Modifier.isStatic(field.getModifiers())) { // 是否是私有的,是否是静态的
    37. // 非公共私有变量
    38. String fieldName = StringUtils.capitalize(field.getName()); // 获取属性名称
    39. int getIndex = methodAccess.getIndex("get" + fieldName); // 获取get方法的下标
    40. int setIndex = methodAccess.getIndex("set" + fieldName); // 获取set方法的下标
    41. methodIndexMap.put(orgi.getClass().getName() + "." + "get"
    42. + fieldName, getIndex); // 将类名get方法名,方法下标注册到map中
    43. methodIndexMap.put(orgi.getClass().getName() + "." + "set"
    44. + fieldName, setIndex); // 将类名set方法名,方法下标注册到map中
    45. fieldList.add(fieldName); // 将属性名称放入集合里
    46. }
    47. }
    48. fieldMap.put(orgi.getClass(), fieldList); // 将类名,属性名称注册到map中
    49. methodMap.put(orgi.getClass(), methodAccess);
    50. return methodAccess;
    51. }
    52. }

参考---https://blog.csdn.net/w05980598/article/details/79134379

Beanutils.copyProperties( )的使用与优化的更多相关文章

  1. BeanUtils.copyProperties()方法和PropertyUtils.copyProperties()的区别

    首先两者来源于同一个包: import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.Prop ...

  2. BeanUtils.copyProperties() 用法

    BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处 ...

  3. java 使用BeanUtils.copyProperties(Object source,Object target) 复制字段值

    BeanUtils.copyProperties(person, wsPerson);把person的字段值,复制给wsPerson // 只复制两个实体中,字段名称一样的 很有用的一个功能...

  4. BeanUtils.copyProperties() 用法--部分转

    把一个类对象copy到另一个类对象(这两个可以不同). 1.org.apache.commons.beanutils.BeanUtils.copyProperties(dest, src) org.s ...

  5. BeanUtils.copyProperties与PropertyUtils.copyProperties用法及区别

    一.简介: BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean 通常包含了大量的属性,很多情况下,对Jav ...

  6. BeanUtils.copyProperties()方法引入不同包

    两个对象之间拷贝相同的属性,可以使用BeanUtils.copyProperties()方法, BeanUtils.copyProperties(obj1,obj2); 提示有三个包可选. A,选择o ...

  7. BeanUtils.copyProperties VS PropertyUtils.copyProperties

    作为两个bean属性copy的工具类,他们被广泛使用,同时也很容易误用,给人造成困然:比如:昨天发现同事在使用BeanUtils.copyProperties copy有integer类型属性的bea ...

  8. 小知识点BeanUtils.copyProperties

     通过BeanUtils.copyProperties可以时间拷贝对象中的值,下面的new String[]{"cid","agreeFlag"," ...

  9. BeanUtils.copyProperties缓解代码压力,释放双手

    简单描述:之前在写代码的时候,经常把表单提交到后台的对象的参数,通过getter方法取出来,然后,再通过setter方法传递给需要的对象,代码中写了很多get set这种方法,后来听同事说,sprin ...

随机推荐

  1. Spring配置,事务使用

    1.spring redis session超时配置 <bean class="org.springframework.session.data.redis.config.annota ...

  2. jdbc(MySQL)

    1.连接数据库 2.使用配置文件 3.启用连接池 4.事务 JDBC WHAT? 用于执行 SQL 语句的 Java API WHY? 不需要了解每一种数据库连接操作方式 HOW? 加载驱动.获取连接 ...

  3. android 开发 xml绘制shape与Selector与layer-list 一 基础篇

    首先我们先来了解状态效果 android:state_pressed=["true" | "false"]  按下状态 android:state_focuse ...

  4. [Android]数据篇 --- SharedPreferences

    转载请标注:转载于http://www.cnblogs.com/Liuyt-61/p/6637515.html -------------------------------------------- ...

  5. uva-10887-枚举

    题意:集合S1和S2,把S2中的元素拼接到S1的后面去,生成新的元素,问有多少个不重复的元素 直接map.注意,不能用cin读取字符串,题目没有保证字符串中间没有空格 #include "p ...

  6. 《算法》第四章部分程序 part 8

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,图中找欧拉路径 ● 无向图中寻找欧拉路径,只注释了与欧拉环不同的地方 package package01; import edu.princeton. ...

  7. Feign 的简单使用(2)

    依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>sp ...

  8. leetcode989

    class Solution: def addToArrayForm(self, A, K): i = len(A) - 1 while i >= 0 and K > 0: A[i] += ...

  9. day24-抽象类与接口类

    接口类 1.继承有两种用途:一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继 ...

  10. BBS--首页、个人站点、ORM

    首页 首页文章排版渲染 登录不登录两种情况 1.bootstrap导航条 点击session 创建登陆后创建人物图表 bootstrap--样式 <li><a href=" ...