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. mybatis3.4测试CRUD

    导入包 H:\jar\jdbc\mysql-connector-java-5.1.13-bin.jarH:\jar\mybatis\mybatis-3.4.1\mybatis-3.4.1.jarH:\ ...

  2. CLR执行模型与常见的几个概念

    CLR执行模型与常见的几个概念 一.CLR执行模型 1.1从代码到程序集 CLR执行的模型是从代码开始,经过编译器生成托管模块,默认情况下可以让多个托管模块和资源生成程序集.下图为其大致过程. 1.2 ...

  3. ORM查询语言OQL

    ORM查询语言(OQL)简介--高级篇(续):庐山真貌 相关文章内容索引: ORM查询语言(OQL)简介--概念篇 ORM查询语言(OQL)简介--实例篇 ORM查询语言(OQL)简介--高级篇:脱胎 ...

  4. Winform 让跨线程访问变得更简单

    Winform 让跨线程访问变得更简单 前言 由于多线程可能导致对控件访问的不一致,导致出现问题.C#中默认是要线程安全的,即在访问控件时需要首先判断是否跨线程,如果是跨线程的直接访问,在运行时会抛出 ...

  5. C++中const用法详解

    本文主要内容来自CSDN论坛: http://bbs.csdn.net/topics/310007610 我做了下面几点补充. 补充: 1. 用const声明全局变量时, 该变量仅在本文件内可见, 类 ...

  6. JS中转义字符的处理

    //去掉html标签 1 2 3 function removeHtmlTab(tab) {  return tab.replace(/<[^<>]+?>/g,'');//删除 ...

  7. github 自学文档 希望可以给初学的人一些帮助

    一 .git的安装 windows下面的安装:https://git-for-windows.github.io  从这里下载完全无脑安装. 安装完成后,在开始菜单里找到"Git" ...

  8. jq,js简单实现类似Angular.js数据绑定效果

    刚了解了下Angular.js,发现Angular.js绑定数据方面非常方便,套下教程demo: <div ng-app="myApp" ng-controller=&quo ...

  9. 图像预处理(Evision)

    Convolution //采用线性过滤Linear combination of neighboring pixels using a convolution kernel−Pre-defined ...

  10. 【.NET】电话号码打星号(隐藏部分)

    描述:支持多个电话: //隐藏部分内容,支持一个值有多个联系方式,用逗号隔开.//参数:value - 值,subIndex - 从第几位开始,subQty - 隐藏几位数 protected str ...