com.diboot.core.util.BeanUtils Maven / Gradle / Ivy
package com.diboot.core.util;
import com.diboot.core.config.Cons;
import com.diboot.core.entity.BaseEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.cglib.beans.BeanCopier;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Bean相关处理工具类
* @author Mazhicheng
* @version v2.0
* @date 2019/01/01
*/
public class BeanUtils {
private static final Logger log = LoggerFactory.getLogger(BeanUtils.class);
/**
* 连接符号
*/
private static final String CHANGE_FLAG = "->";
/**
* 忽略对比的字段
*/
private static final Set IGNORE_FIELDS = new HashSet(){{
add("createTime");
}};
/***
* 缓存BeanCopier
*/
private static Map BEAN_COPIER_INST_MAP = new ConcurrentHashMap<>();
/***
* 缓存类-Lambda的映射关系
*/
private static Map CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>();
/***
* 获取实例
* @param source
* @param target
* @return
*/
private static BeanCopier getBeanCopierInstance(Object source, Object target){
//build key
String beanCopierKey = source.getClass().toString() +"_"+ target.getClass().toString();
BeanCopier copierInst = BEAN_COPIER_INST_MAP.get(beanCopierKey);
if(copierInst == null){
copierInst = BeanCopier.create(source.getClass(), target.getClass(), false);
BEAN_COPIER_INST_MAP.put(beanCopierKey, copierInst);
}
return copierInst;
}
/**
* Copy属性到另一个对象
* @param source
* @param target
*/
public static Object copyProperties(Object source, Object target){
BeanCopier copierInst = getBeanCopierInstance(source, target);
copierInst.copy(source, target, null);
return target;
}
/***
* 将对象转换为另外的对象实例
* @param source
* @param clazz
* @param
* @return
*/
public static T convert(Object source, Class clazz){
if(source == null){
return null;
}
T target = null;
try{
target = clazz.getConstructor().newInstance();
copyProperties(source, target);
}
catch (Exception e){
log.warn("对象转换异常, class="+clazz.getName());
}
return target;
}
/***
* 将对象转换为另外的对象实例
* @param sourceList
* @param clazz
* @param
* @return
*/
public static List convertList(List sourceList, Class clazz){
if(V.isEmpty(sourceList)){
return Collections.emptyList();
}
List resultList = new ArrayList<>();
// 类型相同,直接跳过
if(clazz.getName().equals(sourceList.get(0).getClass().getName())){
return sourceList;
}
// 不同,则转换
try{
for(Object source : sourceList){
T target = clazz.getConstructor().newInstance();
copyProperties(source, target);
resultList.add(target);
}
}
catch (Exception e){
log.warn("对象转换异常, class="+clazz.getName());
}
return resultList;
}
/***
* 附加Map中的属性值到Model
* @param model
* @param propMap
*/
public static void bindProperties(Object model, Map propMap){
try{// 获取类属性
BeanInfo beanInfo = Introspector.getBeanInfo(model.getClass());
// 给 JavaBean 对象的属性赋值
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor descriptor : propertyDescriptors) {
String propertyName = descriptor.getName();
if (!propMap.containsKey(propertyName)){
continue;
}
Object value = propMap.get(propertyName);
Class type = descriptor.getWriteMethod().getParameterTypes()[0];
Object[] args = new Object[1];
String fieldType = type.getName();
// 类型不一致,需转型
if(!value.getClass().getTypeName().equals(fieldType)){
if(value instanceof String){
// String to Date
if(fieldType.equalsIgnoreCase(Date.class.getName())){
args[0] = D.fuzzyConvert((String)value);
}
// Map中的String型转换为其他型
else if(fieldType.equalsIgnoreCase(Boolean.class.getName())){
args[0] = V.isTrue((String)value);
}
else if (fieldType.equalsIgnoreCase(Integer.class.getName()) || "int".equals(fieldType)) {
args[0] = Integer.parseInt((String)value);
}
else if (fieldType.equalsIgnoreCase(Long.class.getName())) {
args[0] = Long.parseLong((String)value);
}
else if (fieldType.equalsIgnoreCase(Double.class.getName())) {
args[0] = Double.parseDouble((String)value);
}
else if (fieldType.equalsIgnoreCase(Float.class.getName())) {
args[0] = Float.parseFloat((String)value);
}
else{
args[0] = value;
log.warn("类型不一致,暂无法自动绑定,请手动转型一致后调用!字段类型: {} vs {} ", value.getClass().getTypeName(), fieldType);
}
}
else{
args[0] = value;
log.warn("类型不一致,且Map中的value非String类型,暂无法自动绑定,请手动转型一致后调用! {} vs {} ", value.getClass().getTypeName(), fieldType);
}
}
else{
args[0] = value;
}
descriptor.getWriteMethod().invoke(model, args);
}
}
catch (Exception e){
log.warn("复制Map属性到Model异常: " + e.getMessage(), e);
}
}
/***
* 获取对象的属性值
* @param obj
* @param field
* @return
*/
public static Object getProperty(Object obj, String field){
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
return wrapper.getPropertyValue(field);
}
/***
* 获取对象的属性值并转换为String
* @param obj
* @param field
* @return
*/
public static String getStringProperty(Object obj, String field){
Object property = getProperty(obj, field);
if(property == null){
return null;
}
return String.valueOf(property);
}
/***
* 设置属性值
* @param obj
* @param field
* @param value
*/
public static void setProperty(Object obj, String field, Object value) {
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
wrapper.setPropertyValue(field, value);
}
/***
* Key-Object对象Map
* @param allLists
* @return
*/
public static Map convertToStringKeyObjectMap(List allLists, String... fields){
if(allLists == null || allLists.isEmpty()){
return null;
}
Map allListMap = new LinkedHashMap<>(allLists.size());
// 转换为map
try{
for(T model : allLists){
String key = null;
if(V.isEmpty(fields)){
//未指定字段,以id为key
key = getStringProperty(model, Cons.FieldName.id.name());
}
// 指定了一个字段,以该字段为key,类型同该字段
else if(fields.length == 1){
key = getStringProperty(model, fields[0]);
}
else{ // 指定了多个字段,以字段S.join的结果为key,类型为String
List list = new ArrayList();
for(String fld : fields){
list.add(getProperty(model, fld));
}
key = S.join(list);
}
if(key != null){
allListMap.put(key, model);
}
else{
log.warn(model.getClass().getName() + " 的属性 "+fields[0]+" 值存在 null,转换结果需要确认!");
}
}
}
catch(Exception e){
log.warn("转换key-model异常", e);
}
return allListMap;
}
/***
* 构建上下级关联的树形结构的model
* @param allModels
* @param
* @return
*/
public static List buildTree(List allModels){
if(V.isEmpty(allModels)){
return null;
}
// 提取所有的top level对象
List topLevelModels = new ArrayList();
for(T model : allModels){
Object parentId = getProperty(model, Cons.FieldName.parentId.name());
if(parentId == null || V.fuzzyEqual(parentId, 0)){
topLevelModels.add(model);
}
}
if(V.isEmpty(topLevelModels)){
return topLevelModels;
}
// 提取向下一层的对象
buildDeeperLevelTree(topLevelModels, allModels);
// 返回第一层级节点(二级及以上子级通过children属性获取)
return topLevelModels;
}
/***
* 构建下一层级树形结构
* @param parentModels
* @param allModels
* @param
*/
private static void buildDeeperLevelTree(List parentModels, List allModels){
List deeperLevelModels = new ArrayList();
Map parentLevelModelMap = convertToStringKeyObjectMap(parentModels, Cons.FieldName.id.name());
for(T model : allModels){
Object parentId = getProperty(model, Cons.FieldName.parentId.name());
if(parentLevelModelMap.keySet().contains(String.valueOf(parentId)) && !parentId.equals(model.getId())){
deeperLevelModels.add(model);
}
}
if(V.isEmpty(deeperLevelModels)){
return;
}
for(T model : deeperLevelModels){
Object parentId = getProperty(model, Cons.FieldName.parentId.name());
T parentModel = parentLevelModelMap.get(String.valueOf(parentId));
if(parentModel!=null){
List children = (List) getProperty(parentModel, Cons.FieldName.children.name());
if(children == null){
children = new ArrayList();
setProperty(parentModel, Cons.FieldName.children.name(), children);
}
children.add(model);
}
}
// 递归进入下一层级
buildDeeperLevelTree(deeperLevelModels, allModels);
}
/***
* 提取两个model的差异值
* @param oldModel
* @param newModel
* @return
*/
public static String extractDiff(BaseEntity oldModel, BaseEntity newModel){
return extractDiff(oldModel, newModel, null);
}
/***
* 提取两个model的差异值,只对比指定字段
* @param oldModel
* @param newModel
* @return
*/
public static String extractDiff(BaseEntity oldModel, BaseEntity newModel, Set fields){
if(newModel == null || oldModel == null){
log.warn("调用错误,Model不能为空!");
return null;
}
Map oldMap = oldModel.toMap();
Map newMap = newModel.toMap();
Map result = new HashMap<>(oldMap.size()+newMap.size());
for(Map.Entry entry : oldMap.entrySet()){
if(IGNORE_FIELDS.contains(entry.getKey())){
continue;
}
String oldValue = entry.getValue()!=null ? String.valueOf(entry.getValue()) : "";
Object newValueObj = newMap.get(entry.getKey());
String newValue = newValueObj!=null? String.valueOf(newValueObj) : "";
// 设置变更的值
boolean checkThisField = fields == null || fields.contains(entry.getKey());
if(checkThisField && !oldValue.equals(newValue)){
result.put(entry.getKey(), S.join(oldValue, CHANGE_FLAG, newValue));
}
// 从新的map中移除该key
if(newValueObj!=null){
newMap.remove(entry.getKey());
}
}
if(!newMap.isEmpty()){
for(Map.Entry entry : newMap.entrySet()){
if(IGNORE_FIELDS.contains(entry.getKey())){
continue;
}
Object newValueObj = entry.getValue();
String newValue = newValueObj!=null? String.valueOf(newValueObj) : "";
// 设置变更的值
if(fields==null || fields.contains(entry.getKey())){
result.put(entry.getKey(), S.join("", CHANGE_FLAG, newValue));
}
}
}
oldMap = null;
newMap = null;
// 转换结果为String
return JSON.toJSONString(result);
}
/**
* 从list对象列表中提取指定属性值到新的List
* @param objectList 对象list
* @param getterFn get方法
* @param
* @return
*/
public static List collectToList(List objectList, IGetter getterFn){
if(V.isEmpty(objectList)){
return Collections.emptyList();
}
String getterPropName = convertToFieldName(getterFn);
return collectToList(objectList, getterPropName);
}
/**
* 从list对象列表中提取Id主键值到新的List
* @param objectList 对象list
* @param
* @return
*/
public static List collectIdToList(List objectList){
if(V.isEmpty(objectList)){
return Collections.emptyList();
}
return collectToList(objectList, Cons.FieldName.id.name());
}
/***
* 从list对象列表中提取指定属性值到新的List
* @param objectList
* @param getterPropName
* @param
* @return
*/
public static List collectToList(List objectList, String getterPropName){
List fieldValueList = new ArrayList();
try{
for(E object : objectList){
Object fieldValue = getProperty(object, getterPropName);
if(!fieldValueList.contains(fieldValue)){
fieldValueList.add(fieldValue);
}
}
}
catch (Exception e){
log.warn("提取属性值异常, getterPropName="+getterPropName, e);
}
return fieldValueList;
}
/**
* 绑定map中的属性值到list
* @param setFieldFn
* @param getFieldFun
* @param fromList
* @param valueMatchMap
* @param
*/
public static void bindPropValueOfList(ISetter setFieldFn, List fromList, IGetter getFieldFun, Map valueMatchMap){
if(V.isEmpty(fromList)){
return;
}
// function转换为字段名
String setterFieldName = convertToFieldName(setFieldFn), getterFieldName = convertToFieldName(getFieldFun);
bindPropValueOfList(setterFieldName, fromList, getterFieldName, valueMatchMap);
}
/***
* 从对象集合提取某个属性值到list中
* @param setterFieldName
* @param fromList
* @param getterFieldName
* @param valueMatchMap
* @param
*/
public static void bindPropValueOfList(String setterFieldName, List fromList, String getterFieldName, Map valueMatchMap){
if(V.isEmpty(fromList) || V.isEmpty(valueMatchMap)){
return;
}
try{
for(E object : fromList){
Object fieldValue = getProperty(object, getterFieldName);
Object value = null;
if(valueMatchMap.containsKey(fieldValue)){
value = valueMatchMap.get(fieldValue);
}
else{
// 获取到当前的属性值
String fieldValueStr = getStringProperty(object, getterFieldName);
// 获取到当前的value
value = valueMatchMap.get(fieldValueStr);
}
// 赋值
setProperty(object, setterFieldName, value);
}
}
catch (Exception e){
log.warn("设置属性值异常, setterFieldName="+setterFieldName, e);
}
}
/***
* 转换方法引用为属性名
* @param fn
* @return
*/
public static String convertToFieldName(IGetter fn) {
SerializedLambda lambda = getSerializedLambda(fn);
String methodName = lambda.getImplMethodName();
String prefix = null;
if(methodName.startsWith("get")){
prefix = "get";
}
else if(methodName.startsWith("is")){
prefix = "is";
}
if(prefix == null){
log.warn("无效的getter方法: "+methodName);
}
return S.uncapFirst(S.substringAfter(methodName, prefix));
}
/***
* 转换方法引用为属性名
* @param fn
* @return
*/
public static String convertToFieldName(ISetter fn) {
SerializedLambda lambda = getSerializedLambda(fn);
String methodName = lambda.getImplMethodName();
if(!methodName.startsWith("set")){
log.warn("无效的setter方法: "+methodName);
}
return S.uncapFirst(S.substringAfter(methodName, "set"));
}
/**
* 获取类所有属性(包含父类)
* @param clazz
* @return
*/
public static List extractAllFields(Class clazz){
List fieldList = new ArrayList<>();
Set fieldNameSet = new HashSet<>();
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
if(V.notEmpty(fields)){ //被重写属性,以子类override的为准
Arrays.stream(fields).forEach((field)->{
if(!fieldNameSet.contains(field.getName())){
fieldList.add(field);
fieldNameSet.add(field.getName());
}
});
}
clazz = clazz.getSuperclass();
}
return fieldList;
}
/***
* 获取类对应的Lambda
* @param fn
* @return
*/
private static SerializedLambda getSerializedLambda(Serializable fn){
SerializedLambda lambda = CLASS_LAMDBA_CACHE.get(fn.getClass());
if(lambda == null){
try{
Method method = fn.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
lambda = (SerializedLambda) method.invoke(fn);
CLASS_LAMDBA_CACHE.put(fn.getClass(), lambda);
}
catch (Exception e){
log.error("获取SerializedLambda异常, class="+fn.getClass().getSimpleName(), e);
}
}
return lambda;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy