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. MEF只导出类的成员

    MEF只导出类的成员 通过前面两篇文章的介绍,相信各位会明白MEF中有不少实用价值.上一文中我们也讨论了导入与导出,对于导出导入,今天我们再深入一点点,嗯,只是深入一点点而已,不会很难的,请大家务必放 ...

  2. IP:网际协议

    IP:网际协议 1.概述      IP是TCP/IP协议族中最为核心的协议.所有的TCP,UDP,ICMP,IGMP数据都以IP数据报格式传输.      IP提供不可靠,无连接的数据报传送服务. ...

  3. centos6.5 搭建nginx1.6.0 +gridfs +mongodb2.4..10环境

    一) 缘由 因为公司业务需要,需要搭建图片服务器,需求很简单:读取+上传图片,当时第一考虑用nginx来作,但考虑到单纯用nginx来作,无法水平扩展和管理,一旦遇到海量图片,就无办法 扩展.所以考虑 ...

  4. aix上使用裸设备安装oracle10g数据库

    一.检查系统信息 [root@aix222 /]# oslevel -r 5300-08 [root@aix222 /]# prtconf | grep -i mem Memory Size: 190 ...

  5. 导入excle数据

    导入excle数据 1.if (File.Exists(strFileName)) // 当文件存在时             {                 m_fileName = strFi ...

  6. Visual Studio属性配置中使用宏

    在学习C语言的时候,我们曾经遇到过一个宏的概念.宏的作用机理本质上是宏的展开,C语言中的宏的用法也有很多种(水其实很深...),不过从感觉上来讲,人们大致上会在以下的场景中,利用宏来解决一些窘境:一是 ...

  7. Elasticsearch中doc_value的认识

    前言:本文的目的是为后续磁盘空间利用优化做铺垫.主要知识点来源于官网文档 一.doc_value是什么 绝大多数的fields在默认情况下是indexed,因此字段数据是可被搜索的.倒排索引中按照一定 ...

  8. 将前台input中的数据异步传到后台并存入数据库

    将前台input中的数据异步传到后台并存入数据库 先看图: 利用ajax异步交互数据,并不是以json数组的形式将数据传到后台,而是利用字符数组的形式将其传到后台.动态新增每一行数据,将每一列对应的数 ...

  9. linux查找文件的命令【转】

    原文链接:http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html 1. fi ...

  10. Oracle常用查询

    -- 创建Oracle sequence create sequence SEQ_XXHF minvalue 1 maxvalue 9999999999999999999999999999 start ...