/* * Copyright (c) 2018-2028, DreamLu All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: DreamLu 卢春梦 (596392912@qq.com) */ package com.vci.starter.web.util.Lcm; import com.vci.starter.web.util.Lcm.beans.BeanProperty; import com.vci.starter.web.util.Lcm.beans.BladeBeanCopier; import com.vci.starter.web.util.Lcm.beans.BladeBeanMap; import com.vci.starter.web.util.Lcm.convert.BladeConverter; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyAccessorFactory; import org.springframework.cglib.beans.BeanGenerator; import org.springframework.lang.Nullable; import java.util.*; /** * 实体工具类 * * @author L.cm */ public class BeanUtil extends org.springframework.beans.BeanUtils { /** * 实例化对象 * * @param clazz 类 * @param 泛型标记 * @return 对象 */ @SuppressWarnings("unchecked") public static T newInstance(Class clazz) { return (T) instantiateClass(clazz); } /** * 实例化对象 * * @param clazzStr 类名 * @param 泛型标记 * @return 对象 */ public static T newInstance(String clazzStr) { try { Class clazz = ClassUtil.forName(clazzStr, null); return newInstance(clazz); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } /** * 获取Bean的属性, 支持 propertyName 多级 :test.user.name * * @param bean bean * @param propertyName 属性名 * @return 属性值 */ @Nullable public static Object getProperty(@Nullable Object bean, String propertyName) { if (bean == null) { return null; } BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean); return beanWrapper.getPropertyValue(propertyName); } /** * 设置Bean属性, 支持 propertyName 多级 :test.user.name * * @param bean bean * @param propertyName 属性名 * @param value 属性值 */ public static void setProperty(Object bean, String propertyName, Object value) { Objects.requireNonNull(bean, "bean Could not null"); BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean); beanWrapper.setPropertyValue(propertyName, value); } /** * 深复制 * *

* 支持 map bean *

* * @param source 源对象 * @param 泛型标记 * @return T */ @SuppressWarnings("unchecked") @Nullable public static T clone(@Nullable T source) { if (source == null) { return null; } return (T) BeanUtil.copy(source, source.getClass()); } /** * copy 对象属性,默认不使用Convert * *

* 支持 map bean copy *

* * @param source 源对象 * @param clazz 类名 * @param 泛型标记 * @return T */ @Nullable public static T copy(@Nullable Object source, Class clazz) { if (source == null) { return null; } return BeanUtil.copy(source, source.getClass(), clazz); } /** * copy 对象属性,默认不使用Convert * *

* 支持 map bean copy *

* * @param source 源对象 * @param sourceClazz 源类型 * @param targetClazz 转换成的类型 * @param 泛型标记 * @return T */ @Nullable public static T copy(@Nullable Object source, Class sourceClazz, Class targetClazz) { if (source == null) { return null; } BladeBeanCopier copier = BladeBeanCopier.create(sourceClazz, targetClazz, false); T to = newInstance(targetClazz); copier.copy(source, to, null); return to; } /** * copy 列表对象,默认不使用Convert * *

* 支持 map bean copy *

* * @param sourceList 源列表 * @param targetClazz 转换成的类型 * @param 泛型标记 * @return T */ public static List copy(@Nullable Collection sourceList, Class targetClazz) { if (sourceList == null || sourceList.isEmpty()) { return Collections.emptyList(); } List outList = new ArrayList<>(sourceList.size()); Class sourceClazz = null; for (Object source : sourceList) { if (source == null) { continue; } if (sourceClazz == null) { sourceClazz = source.getClass(); } T bean = BeanUtil.copy(source, sourceClazz, targetClazz); outList.add(bean); } return outList; } /** * 拷贝对象 * *

* 支持 map bean copy *

* * @param source 源对象 * @param targetBean 需要赋值的对象 */ public static void copy(@Nullable Object source, @Nullable Object targetBean) { if (source == null || targetBean == null) { return; } BladeBeanCopier copier = BladeBeanCopier .create(source.getClass(), targetBean.getClass(), false); copier.copy(source, targetBean, null); } /** * 拷贝对象,source 属性做 null 判断,Map 不支持,map 会做 instanceof 判断,不会 * *

* 支持 bean copy *

* * @param source 源对象 * @param targetBean 需要赋值的对象 */ public static void copyNonNull(@Nullable Object source, @Nullable Object targetBean) { if (source == null || targetBean == null) { return; } BladeBeanCopier copier = BladeBeanCopier .create(source.getClass(), targetBean.getClass(), false, true); copier.copy(source, targetBean, null); } /** * 拷贝对象并对不同类型属性进行转换 * *

* 支持 map bean copy *

* * @param source 源对象 * @param targetClazz 转换成的类 * @param 泛型标记 * @return T */ @Nullable public static T copyWithConvert(@Nullable Object source, Class targetClazz) { if (source == null) { return null; } return BeanUtil.copyWithConvert(source, source.getClass(), targetClazz); } /** * 拷贝对象并对不同类型属性进行转换 * *

* 支持 map bean copy *

* * @param source 源对象 * @param sourceClazz 源类 * @param targetClazz 转换成的类 * @param 泛型标记 * @return T */ @Nullable public static T copyWithConvert(@Nullable Object source, Class sourceClazz, Class targetClazz) { if (source == null) { return null; } BladeBeanCopier copier = BladeBeanCopier.create(sourceClazz, targetClazz, true); T to = newInstance(targetClazz); copier.copy(source, to, new BladeConverter(sourceClazz, targetClazz)); return to; } /** * 拷贝列表并对不同类型属性进行转换 * *

* 支持 map bean copy *

* * @param sourceList 源对象列表 * @param targetClazz 转换成的类 * @param 泛型标记 * @return List */ public static List copyWithConvert(@Nullable Collection sourceList, Class targetClazz) { if (sourceList == null || sourceList.isEmpty()) { return Collections.emptyList(); } List outList = new ArrayList<>(sourceList.size()); Class sourceClazz = null; for (Object source : sourceList) { if (source == null) { continue; } if (sourceClazz == null) { sourceClazz = source.getClass(); } T bean = BeanUtil.copyWithConvert(source, sourceClazz, targetClazz); outList.add(bean); } return outList; } /** * Copy the property values of the given source bean into the target class. *

Note: The source and target classes do not have to match or even be derived * from each other, as long as the properties match. Any bean properties that the * source bean exposes but the target bean does not will silently be ignored. *

This is just a convenience method. For more complex transfer needs, * * @param source the source bean * @param targetClazz the target bean class * @param 泛型标记 * @return T * @throws BeansException if the copying failed */ @Nullable public static T copyProperties(@Nullable Object source, Class targetClazz) throws BeansException { if (source == null) { return null; } T to = newInstance(targetClazz); BeanUtil.copyProperties(source, to); return to; } /** * Copy the property values of the given source bean into the target class. *

Note: The source and target classes do not have to match or even be derived * from each other, as long as the properties match. Any bean properties that the * source bean exposes but the target bean does not will silently be ignored. *

This is just a convenience method. For more complex transfer needs, * * @param sourceList the source list bean * @param targetClazz the target bean class * @param 泛型标记 * @return List * @throws BeansException if the copying failed */ public static List copyProperties(@Nullable Collection sourceList, Class targetClazz) throws BeansException { if (sourceList == null || sourceList.isEmpty()) { return Collections.emptyList(); } List outList = new ArrayList<>(sourceList.size()); for (Object source : sourceList) { if (source == null) { continue; } T bean = BeanUtil.copyProperties(source, targetClazz); outList.add(bean); } return outList; } /** * 将对象装成map形式 * * @param bean 源对象 * @return {Map} */ @SuppressWarnings("unchecked") public static Map toMap(@Nullable Object bean) { if (bean == null) { return new HashMap<>(0); } return BladeBeanMap.create(bean); } /** * 将map 转为 bean * * @param beanMap map * @param valueType 对象类型 * @param 泛型标记 * @return {T} */ public static T toBean(Map beanMap, Class valueType) { Objects.requireNonNull(beanMap, "beanMap Could not null"); T to = newInstance(valueType); if (beanMap.isEmpty()) { return to; } BeanUtil.copy(beanMap, to); return to; } /** * 给一个Bean添加字段 * * @param superBean 父级Bean * @param props 新增属性 * @return {Object} */ @Nullable public static Object generator(@Nullable Object superBean, BeanProperty... props) { if (superBean == null) { return null; } Class superclass = superBean.getClass(); Object genBean = generator(superclass, props); BeanUtil.copy(superBean, genBean); return genBean; } /** * 给一个class添加字段 * * @param superclass 父级 * @param props 新增属性 * @return {Object} */ public static Object generator(Class superclass, BeanProperty... props) { BeanGenerator generator = new BeanGenerator(); generator.setSuperclass(superclass); generator.setUseCache(true); for (BeanProperty prop : props) { generator.addProperty(prop.getName(), prop.getType()); } return generator.create(); } }