文档章节

一个Bean属性拷贝的工具类

h
 hn_old_man
发布于 2016/04/13 15:46
字数 1348
阅读 37
收藏 0
package com.fpi.spring.qaepb.cps.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.fpi.spring.qaepb.cps.entity.po.Project;
import com.fpi.spring.qaepb.cps.entity.po.ProjectApproval;

/**
 * bean的属性拷贝工具类
 * 
 * @date 2013-12-17
 * 
 * @author yang_qiao
 * 
 * @version 1.0
 */
public class BeanUtils {

    private static final Log logger = LogFactory.getLog(BeanUtils.class);

    /** bean嵌套 */
    private static final String NESTED = ".";

    /**
     * 复制bean的属性(支持嵌套属性,以点号分割)
     * 
     * @param source
     *            拷贝属性的源对象
     * 
     * @param dest
     *            拷贝属性的目的地对象
     * 
     * @param includeProperties
     *            拷贝的属性列表
     * 
     * @author yang_qiao
     * 
     * @throws InvocationTargetException
     * 
     * @throws IllegalAccessException
     * 
     * @throws IllegalArgumentException
     * 
     * @throws InstantiationException
     * 
     * @throws IntrospectionException
     * 
     * @date 2013-12-18
     */
    public static final void copyIncludeProperties(final Object source,
            Object dest, final String[] includeProperties)
            throws IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, InstantiationException,
            IntrospectionException {
        if (includeProperties == null || includeProperties.length == 0) {
            throw new IllegalArgumentException("未传入要拷贝的属性列表");
        }
        if (source == null) {
            throw new IllegalArgumentException("要拷贝的源对象为空");
        }
        if (dest == null) {
            throw new IllegalArgumentException("要拷贝的目的对象为空");
        }
        // 日志信息
        if (logger.isTraceEnabled()) {
            logger.trace("[source bean: " + source.getClass().getName() + " ]");
            logger.trace("[destination bean: " + dest.getClass().getName()
                    + " ]");
        }
        // 拷贝
        for (String property : includeProperties) {
            PropertyDescriptor sourcePropertyDescriptor = null;
            PropertyDescriptor destPropertyDescriptor = null;
            if (isSimpleProperty(property)) { // 简单属性
                sourcePropertyDescriptor = getProperty(property, source);
                destPropertyDescriptor = getProperty(property, dest);
                if (sourcePropertyDescriptor == null) {
                    throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                }
                if (destPropertyDescriptor == null) {
                    throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");
                }
                copyProperty(property, source, dest);
            } else { // 嵌套bean属性
                Object target = dest;
                Object realSource = source;
                String[] nestedProperty = getNestedProperty(property);
                if (nestedProperty != null && nestedProperty.length > 1) {
                    for (int i = 0; i < nestedProperty.length - 1; i++) {
                        sourcePropertyDescriptor = getProperty(
                                nestedProperty[i], realSource);
                        destPropertyDescriptor = getProperty(nestedProperty[i],
                                target);
                        if (sourcePropertyDescriptor == null) {
                            throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                        }
                        if (destPropertyDescriptor == null) {
                            throw new IllegalArgumentException(
                                    "要拷贝到的目标对象不存在该属性");
                        }
                        Method readMethod = sourcePropertyDescriptor
                                .getReadMethod();
                        realSource = readMethod.invoke(realSource);
                        readMethod = destPropertyDescriptor.getReadMethod();
                        Method writeMethod = destPropertyDescriptor
                                .getWriteMethod();
                        Object value = readMethod.invoke(target);
                        if (value == null) {
                            value = destPropertyDescriptor.getPropertyType()
                                    .newInstance();
                            writeMethod.invoke(target, value);
                        }
                        target = value;
                    }
                    final String prop = nestedProperty[nestedProperty.length - 1];
                    sourcePropertyDescriptor = getProperty(prop, realSource);
                    destPropertyDescriptor = getProperty(prop, target);
                    if (sourcePropertyDescriptor == null) {
                        throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                    }
                    if (destPropertyDescriptor == null) {
                        throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");
                    }
                    copyProperty(prop, realSource, target);
                }
            }
        }
    }

    /**
     * 复制bean的属性(支持嵌套属性,以点号分割)
     * 
     * @param source
     *            拷贝属性的源对象
     * 
     * @param dest
     *            拷贝属性的目的地对象
     * 
     * @param includeProperties
     *            拷贝的属性列表
     * 
     * @author yang_qiao
     * 
     * @throws IntrospectionException
     * 
     * @throws InvocationTargetException
     * 
     * @throws IllegalAccessException
     * 
     * @throws IllegalArgumentException
     * 
     * @throws InstantiationException
     * 
     * @throws ClassNotFoundException
     * 
     * @throws IOException
     * 
     * @date 2013-12-18
     */
    public static void copyProperties(final Object source, final Object dest,
            final String... excludeProperties) throws IntrospectionException,
            IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, InstantiationException, IOException,
            ClassNotFoundException {
        final Object backupSource = clone(dest);
        if (source == null) {
            throw new IllegalArgumentException("要拷贝的源对象为空");
        }
        if (dest == null) {
            throw new IllegalArgumentException("要拷贝的目的对象为空");
        }
        org.apache.commons.beanutils.BeanUtils.copyProperties(dest, source);
        // 还原排除的属性值
        revertProperties(backupSource, dest, excludeProperties);
    }

    /**
     * 从备份对象中还原属性
     * 
     * @param backup
     *            备份bean
     * 
     * @param target
     *            目标bean
     * 
     * @param properties
     *            属性列表
     * 
     * @author yang_qiao
     * 
     * @throws InvocationTargetException
     * 
     * @throws IllegalAccessException
     * 
     * @throws IllegalArgumentException
     * 
     * @throws IntrospectionException
     * 
     * @throws InstantiationException
     * 
     * @date 2013-12-18
     */
    private static void revertProperties(final Object backup, Object target,
            final String... properties) throws IllegalArgumentException,
            IllegalAccessException, InvocationTargetException,
            IntrospectionException, InstantiationException {
        if (properties == null || properties.length == 0) {
            return;
        }
        if (backup == null) {
            throw new IllegalArgumentException("备份对象为空");
        }
        if (target == null) {
            throw new IllegalArgumentException("目的对象为空");
        }
        // 日志信息
        if (logger.isTraceEnabled()) {
            logger.trace("[source bean: " + backup.getClass().getName() + " ]");
            logger.trace("[destination bean: " + target.getClass().getName()
                    + " ]");
        }
        // 拷贝
        for (String property : properties) {
            PropertyDescriptor sourcePropertyDescriptor = null;
            PropertyDescriptor destPropertyDescriptor = null;
            if (isSimpleProperty(property)) { // 简单属性
                sourcePropertyDescriptor = getProperty(property, backup);
                destPropertyDescriptor = getProperty(property, target);
                if (sourcePropertyDescriptor == null) {
                    throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                }
                if (destPropertyDescriptor == null) {
                    throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");
                }
                copyProperty(property, backup, target);
            } else { // 嵌套bean属性
                Object targetObj = target;
                Object realBackup = backup;
                String[] nestedProperty = getNestedProperty(property);
                if (nestedProperty != null && nestedProperty.length > 1) {
                    for (int i = 0; i < nestedProperty.length - 1; i++) {
                        sourcePropertyDescriptor = getProperty(
                                nestedProperty[i], realBackup);
                        destPropertyDescriptor = getProperty(nestedProperty[i],
                                targetObj);
                        if (sourcePropertyDescriptor == null) {
                            throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                        }
                        if (destPropertyDescriptor == null) {
                            throw new IllegalArgumentException(
                                    "要拷贝到的目标对象不存在该属性");
                        }
                        Method readMethod = sourcePropertyDescriptor
                                .getReadMethod();
                        realBackup = readMethod.invoke(realBackup);
                        if (realBackup == null) { // 判断备份对象嵌套属性是否为空
                            realBackup = sourcePropertyDescriptor
                                    .getPropertyType().newInstance();
                        }
                        Method writeMethod = destPropertyDescriptor
                                .getWriteMethod();
                        readMethod = destPropertyDescriptor.getReadMethod();
                        Object value = readMethod.invoke(targetObj);
                        if (value == null) {
                            value = destPropertyDescriptor.getPropertyType()
                                    .newInstance();
                            writeMethod.invoke(targetObj, value);
                        }
                        targetObj = value;
                    }
                    final String prop = nestedProperty[nestedProperty.length - 1];
                    sourcePropertyDescriptor = getProperty(prop, realBackup);
                    destPropertyDescriptor = getProperty(prop, targetObj);
                    if (sourcePropertyDescriptor == null) {
                        throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                    }
                    if (destPropertyDescriptor == null) {
                        throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");
                    }
                    copyProperty(prop, realBackup, targetObj);
                }
            }
        }
    }

    /**
     * 对象克隆
     * 
     * @author yang_qiao
     * 
     * @date 2013-12-18
     */
    private static Object clone(final Object value) throws IOException,
            ClassNotFoundException {
        // 字节数组输出流,暂存到内存中
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        // 序列化
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(value);
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        // 反序列化
        return ois.readObject();
    }

    /**
     * 判断是否为简单属性,是,返回ture
     * 
     * @author yang_qiao
     * 
     * @date 2013-12-18
     */
    private static boolean isSimpleProperty(final String property) {
        return !property.contains(NESTED);
    }

    /**
     * 获取目标bean的属性
     * 
     * @author yang_qiao
     * 
     * @date 2013-12-17
     */
    private static PropertyDescriptor getProperty(final String propertyName,
            final Object target) {
        if (target == null) {
            new IllegalArgumentException("查询属性的对象为空");
        }
        if (propertyName == null || "".equals(propertyName)) {
            new IllegalArgumentException("查询属性不能为空值");
        }
        PropertyDescriptor propertyDescriptor = null;
        try {
            propertyDescriptor = new PropertyDescriptor(propertyName,
                    target.getClass());
        } catch (IntrospectionException e) {
            logger.info("不存在该属性");
            return null;
        }
        return propertyDescriptor;
    }

    /**
     * 单个属性复制--原数据源和目的数据源必须要有该属性方可
     * 
     * @author yang_qiao
     * 
     * @throws InvocationTargetException
     * 
     * @throws IllegalAccessException
     * 
     * @throws IllegalArgumentException
     * 
     * @throws IntrospectionException
     * 
     * @date 2013-12-17
     */
    public static void copyProperty(final String propertyName,
            final Object source, Object dest) throws IllegalArgumentException,
            IllegalAccessException, InvocationTargetException,
            IntrospectionException {
        PropertyDescriptor property;
        property = new PropertyDescriptor(propertyName, source.getClass());
        Method getMethod = property.getReadMethod();
        Object value = getMethod.invoke(source);
        property = new PropertyDescriptor(propertyName, dest.getClass());
        Method setMethod = property.getWriteMethod();
        setMethod.invoke(dest, value);
    }

    /**
     * 获取嵌套Bean的属性
     * 
     * @author yang_qiao
     * 
     * @date 2013-12-18
     */
    public static String[] getNestedProperty(final String nestedProperty) {
        if (nestedProperty == null || "".equals(nestedProperty)) {
            new IllegalArgumentException("参数为空值");
        }
        return nestedProperty.split("\\" + NESTED);
    }

    public static void main(String[] args) throws IllegalArgumentException,
            IllegalAccessException, InvocationTargetException,
            InstantiationException, IntrospectionException, IOException,
            ClassNotFoundException {
        Project oldProject = new Project();
        Project newProject = new Project();
        ProjectApproval projectApproval = new ProjectApproval();
        projectApproval.setFirstCheckComment("jsoncheck");
        projectApproval.setExplorationComment("shitCheck");
        oldProject.setProjectApproval(projectApproval);
        oldProject.setBuildAddress("json");
        oldProject.setContact("json");
        final String[] includeProperties = new String[] { "contact",
                "projectApproval.firstCheckComment",
                "projectApproval.explorationComment" };
        BeanUtils.copyIncludeProperties(oldProject, newProject,
                includeProperties);
        System.out.println(newProject.getContact());
        System.out.println(newProject.getProjectApproval()
                .getFirstCheckComment());
        System.out.println(newProject.getProjectApproval()
                .getExplorationComment());
        System.out.println(newProject.getApprovalStatus());
        System.out.println(newProject.getBuildAddress());

        System.out.println("================================");

        oldProject = new Project();
        newProject = new Project();
        projectApproval = new ProjectApproval();
        projectApproval.setFirstCheckComment("jsoncheck_");
        projectApproval.setExplorationComment("shitCheck_");
        oldProject.setProjectApproval(projectApproval);
        oldProject.setBuildAddress("json_");
        oldProject.setContact("json_");
        final String[] excludeProperties = null;
        BeanUtils.copyProperties(oldProject, newProject, excludeProperties);
        System.out.println(newProject.getContact());
        System.out.println(newProject.getProjectApproval()
                .getExplorationComment());
        System.out.println(newProject.getProjectApproval()
                .getFirstCheckComment());
        System.out.println(newProject.getApprovalStatus());
        System.out.println(newProject.getBuildAddress());

    }

}


© 著作权归作者所有

下一篇: Clazz
h
粉丝 0
博文 16
码字总数 3567
作品 0
郑州
私信 提问
commons-beanutils

概述 commons-beanutil开源库是apache组织的一个基础的开源库,为apache中许多类提供工具方法,学习它是学习其他开源库实现的基础。 Commons-beanutil中包含大量和JavaBean操作有关的工具方法...

wuchongchang
2011/09/15
1K
0
原型模式之 深度拷贝 工具类

看了 一些 原型模式,原来就是 深度拷贝,浅拷贝的。工作了这么久,说实话,我还没有真实使用过 拷贝的方法的。。。特别是浅拷贝 更加不敢乱用了,万一引用什么的搞混了就麻烦了。而且 浅拷贝...

之渊
2018/06/12
8
0
springMvc源码学习之:spring源码总结

转载自:http://www.cnblogs.com/davidwang456/p/4213652.html spring beans下面有如下源文件包: org.springframework.beans, 包含了操作java bean的接口和类。 org.springframework.beans.......

无信不立
2016/11/04
0
0
Java内省(Introspector)

Java内省(Introspector) Java内省技术专门用来操作JavaBean的属性。 为什么要学内省? 开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦...

_-Leon-_
2014/07/14
248
0
高性能bean mapping类库--Easy-mapper

Easy-mapper是一个轻量、可扩展的高性能bean mapping类库。基于Javassist字节码增强技术实现动态bean属性映射工作,可自定义属性映射规则,包括名称、Transformer函数等,支持Java8的lambda表...

匿名
2016/08/09
677
0

没有更多内容

加载失败,请刷新页面

加载更多

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
今天
11
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
今天
7
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
今天
8
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
今天
11
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部