package com.xxx.beancopier;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier; /**
* @Type BeanCopier
* @Desc 属性copy类
* @author
* @date 2017-01-06
* @Version V1.0
*/
public class BeanCopier {
private BeanCopier() {
} public static <DestType> DestType propertiesCopy(Object orig, DestType dest) {
if (orig == null || dest == null) {
throw new RuntimeException("参数不能为null");
} Method[] destMethods = dest.getClass().getMethods();
for (Method destMethod : destMethods) {
if (needCopy(destMethod)) {
MethodCopy methodCopy = new MethodCopy(destMethod);
methodCopy.copy(orig, dest);
}
}
return dest;
} private static boolean needCopy(Method method) {
PropertyCopy annotation = method.getAnnotation(PropertyCopy.class);
if (annotation != null && annotation.ignore())
return false;
return method.getName().startsWith("set") && method.getParameterTypes().length == 1
&& Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers());
} static class MethodCopy {
private Method method;
private String methodName;
private Method getterMethod; public MethodCopy(Method destMethod) {
method = destMethod;
methodName = destMethod.getName();
} private void copy(Object orig, Object dest) {
try {
this.getterMethod = orig.getClass().getMethod("get" + methodName.substring(3));
} catch (NoSuchMethodException e) {
throw new RuntimeException("对象【" + orig + "】中缺失【" + methodName.replaceFirst("set", "get") + "()】方法!");
}
Object propertyValue = invokeMethod(orig, getterMethod);
if (propertyValue != null) {
invokeMethod(dest, method, propertyValue);
}
} private Object invokeMethod(Object targerObject, Method method, Object... args) {
if (method == null) {
throw new RuntimeException("被调用方法不能为空!");
}
// 验证参数数量
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != args.length) {
throw new RuntimeException("方法【" + method + "】的参数数量【" + parameterTypes.length + "】和反射调用时的参数数量【"
+ args.length + "】不相符,无法完成调用!");
} try {
method.setAccessible(true);
return method.invoke(targerObject, args);
} catch (Throwable e) {
throw new RuntimeException("调用对象【" + targerObject + "】的【" + method + "】方法,参数为【" + args + "】时发生异常:", e);
}
} }
} @Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
@Documented
@interface PropertyCopy {
/**
* 被标注方法是否被忽略拷贝
* @return
*/
boolean ignore() default false;
}

使用如下:

StudentDTO studentDTO1 = BeanCopier.propertiesCopy(student, new StudentDTO());

自己通过反射写的一个属性copy类的更多相关文章

  1. 我写的一个ExcelHelper通用类,可用于读取或生成数据

    读取或生成EXCEL数据的方法有很多,一般常见的有: 1.通过OFFICE EXCEL组件,优点:读取与生成EXCEL文件方便,缺点:服务器上必须安装OFFICE软件,且进程无法及时释放 2.通过第三 ...

  2. 我写了一个java实体类,implements了Serializable接口,然后我如何让serialversionUID自动生成

    写了一个java实体类,implements了Serializable接口,让serialversionUID自动生成方法: 1.点击类旁边的警告符号: 2.选择Add generated seria ...

  3. 自己用反射写的一个request.getParameter工具类

    适用范围:当我们在jsp页面需要接收很多值的时候,如果用request.getParameter(属性名)一个一个写的话那就太麻烦了,于是我想是 否能用反射写个工具类来简化这样的代码,经过1个小时的代 ...

  4. entity framework 6 我写了一个公用数据类

    public class BaseDAL { string strConn = ""; public BaseDAL(string connString) { strConn = ...

  5. 同事写了一个疯狂的类构造器,我要疯了,Builder 模式都不会么?!

    疯狂的类构造器 最近栈长在做 Code Review 时,发现一段创建对象的方法: Task task = new Task(112, "紧急任务", "处理一下这个任务 ...

  6. 新手写的一个DBCP工具类

    package com.xx.questionnaire.util.dao; import java.io.IOException; import java.sql.Connection; impor ...

  7. BeanUtils对象属性copy的性能对比以及源码分析

    1. 对象属性拷贝的常见方式及其性能 在日常编码中,经常会遇到DO.DTO对象之间的转换,如果对象本身的属性比较少的时候,那么我们采用硬编码手工setter也还ok,但如果对象的属性比较多的情况下,手 ...

  8. JavaScript写一个表格排序类

    依稀记得那是上个星期六的下午,我参加了网易暑期实习生招聘笔试.考得相当糟糕,编程题3个题通过了2个,简答题没做对,选择题貌似是20个题猜了6-7个,99%是挂了,唉唉唉!生活不只眼前的苟且,学习的脚步 ...

  9. 如何写好一个UITableView

    本文是直播分享的简单文字整理,直播共分为上.下两部分. 第一部分: 优酷 :http://v.youku.com/v_show/id_XMTUzNzQzMDU0NA%3Cmark%3E.html Or ...

随机推荐

  1. cubieboard 配置WIFI

    1.先装好驱动程序 2.ifconfig查看无线网卡的名称,比如 3.修改/etc/networking/interfaces,配置 wpa-essid填写WIFI名称 wpa-psk填写密码 4. ...

  2. 搜索广告与广告网络Demand技术-搜索广告

    搜索广告 搜索广告就是一个典型的Ad Network,但是搜索广告非常重要,它的收入非常高,所以它有其独特之处,复杂度也比展示广告要高.它与展示广告在点击率预测,检索部分差不多,它的特点:1. 用户定 ...

  3. VS XCOPY

    有时在项目开发过程中,某个项目不直接依赖于另外一个项目,也就是说在编码上不需要使用另外一个项目上的代码,但实际运行的时候需要用到,我们通常的做法是把另外项目中需要用到的DLL拷过来放到该项目的BIN文 ...

  4. ASP.NET Web API的消息处理管道: HttpRoutingDispatcher

    ASP.NET Web API的消息处理管道: HttpRoutingDispatcher 认情况下,作为消息处理管道“龙头”的HttpServer的Dispatcher属性返回一个HttpRouti ...

  5. Windows核心编程学习九:利用内核对象进行线程同步

    注:源码为学习<Windows核心编程>的一些尝试,非原创.若能有助于一二访客,幸甚. 1.程序框架 #include "Queue.h" #include <t ...

  6. Linux:备份

    一.每日备份数据 该脚本backupday.sh用来每日备份你需要备份的文件或目录 使用办法 1)打开脚本修改要备份的目录或文件和备份到的目录(如从A备份到B) 2)修改后运行脚本 需要备份数据时,直 ...

  7. linux下搭建svn本地服务器

    在linux下搭建svn本地服务器可以很好的管理自己的代码,具体过程如下: # mkdir svn_local # cd svn_local  # svnadmin create led_diplay ...

  8. 深刻理解HDFS工作机制

    深入理解一个技术的工作机制是灵活运用和快速解决问题的根本方法,也是唯一途径.对于HDFS来说除了要明白它的应用场景和用法以及通用分布式架构之外更重要的是理解关键步骤的原理和实现细节.在看这篇博文之前需 ...

  9. 用ajax对数据进行查看人员信息

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. 微信小程序开源项目库汇总

    最近做了一个微信小程序开源项目库汇总,里面集合了OpenDigg 上的优质的微信小程序开源项目库,方便移动开发人员便捷的找到自己需要的项目工具等,感兴趣的可以到GitHub上给个star. UI组件 ...