【小工具】根据定义的白名单字段进行Bean的拷贝

背景

Bean的拷贝一直有一些类可以使用,比如Apache的org.apache.commons.beanutils.BeanUtils或者Spring的org.springframework.beans.BeanUtils

根据定义的白名单字段进行Bean的拷贝

我需要一个只拷贝我指定的字段的Bean拷贝,而Spring的org.springframework.beans.BeanUtils提供如下几个方法:

其中第2、3个是可以指定属性的,第2个指定可以通过Class指定,基本满足我的需求;第3个指定无须理会的字段。

我不想定义另外的类,或者另外的父类去指定部分属性,我想通过自己配置的白名单只拷贝白名单指定的属性:

package com.nicchagil.exercise.springbootexercise.util;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.BeanUtils;

public class BeanCopyUtils {
	
	/**
	 * 根据白名单字段拷贝Bean
	 */
	public static <T> T copyProperties(Object source, Class<T> clazz, String[] whiteProperties) {
		List<String> ignorePropertiesList = BeanCopyUtils.getIgnoreProperties(clazz, whiteProperties);
		
		String[] ignoreProperties = new String[ignorePropertiesList.size()];
		ignorePropertiesList.toArray(ignoreProperties);
		
		T target;
		try {
			target = clazz.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			throw new RuntimeException("通过Class实例化对象发生异常", e);
		}
		
		BeanUtils.copyProperties(source, target, ignoreProperties);
		return target;
	}
	
	/**
	 * 根据白名单字段字段获取无须理会的字段
	 * @param clazz
	 * @param whiteProperties
	 * @return
	 */
	public static List<String> getIgnoreProperties(Class<?> clazz, String[] whiteProperties) {
		List<String> allProperties = BeanCopyUtils.getAllProperties(clazz);
		
		if (allProperties == null || allProperties.size() == 0) {
			return null;
		}
		
		allProperties.removeAll(Arrays.asList(whiteProperties));
		return allProperties;
	}
	
	/**
	 * 获取全部属性名称
	 */
	public static List<String> getAllProperties(Class<?> clazz) {
		PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(clazz);
		
		if (propertyDescriptors == null || propertyDescriptors.length == 0) {
			return null;
		}
		
		List<String> properties = new ArrayList<String>();
		for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
			properties.add(propertyDescriptor.getName());
		}
		
		return properties;
	}

}

单元测试:

package com.nicchagil.exercise.springbootexercise;

import org.junit.Test;

import com.nicchagil.exercise.springbootexercise.util.BeanCopyUtils;

public class BeanCopyUtilsTest {
	
	@Test
	public void test() {
		User user = new User();
		user.setId(123);
		user.setName("Nick Huang");
		
		User userCopy = BeanCopyUtils.copyProperties(user, User.class, new String[] {"name"});
		System.out.println("user : " + user);
		System.out.println("userCopy : " + userCopy);
	}
	
	public static class User {
		private Integer id;
		private String name;
		public Integer getId() {
			return id;
		}
		public void setId(Integer id) {
			this.id = id;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		@Override
		public String toString() {
			return "User [id=" + id + ", name=" + name + "]";
		}
	}

}
posted @ 2017-12-30 17:45  nick_huang  阅读(714)  评论(0编辑  收藏  举报