/** * Copyright (c) 2018-2028, DreamLu 卢春梦 ([email protected]). * <p> * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p> * http://www.gnu.org/licenses/lgpl.html * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springblade.core.tool.utils; import org.springblade.core.tool.support.BeanProperty; import org.springblade.core.tool.support.BaseBeanCopier; import org.springframework.beans.BeansException; import org.springframework.cglib.beans.BeanGenerator; import org.springframework.cglib.beans.BeanMap; import org.springframework.cglib.core.CodeGenerationException; import org.springframework.util.Assert; import java.beans.PropertyDescriptor; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * 实体工具类 * * @author L.cm */ public class BeanUtil extends org.springframework.beans.BeanUtils { /** * 实例化对象 * @param clazz 类 * @param <T> 泛型标记 * @return 对象 */ @SuppressWarnings("unchecked") public static <T> T newInstance(Class<?> clazz) { return (T) instantiateClass(clazz); } /** * 实例化对象 * @param clazzStr 类名 * @param <T> 泛型标记 * @return 对象 */ public static <T> T newInstance(String clazzStr) { try { Class<?> clazz = Class.forName(clazzStr); return newInstance(clazz); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } /** * 获取Bean的属性 * @param bean bean * @param propertyName 属性名 * @return 属性值 */ public static Object getProperty(Object bean, String propertyName) { Assert.notNull(bean, "bean Could not null"); return BeanMap.create(bean).get(propertyName); } /** * 设置Bean属性 * @param bean bean * @param propertyName 属性名 * @param value 属性值 */ public static void setProperty(Object bean, String propertyName, Object value) { Assert.notNull(bean, "bean Could not null"); BeanMap.create(bean).put(propertyName, value); } /** * 深复制 * * 注意:不支持链式Bean * * @param source 源对象 * @param <T> 泛型标记 * @return T */ @SuppressWarnings("unchecked") public static <T> T clone(T source) { return (T) BeanUtil.copy(source, source.getClass()); } /** * copy 对象属性到另一个对象,默认不使用Convert * * 注意:不支持链式Bean,链式用 copyProperties * * @param source 源对象 * @param clazz 类名 * @param <T> 泛型标记 * @return T */ public static <T> T copy(Object source, Class<T> clazz) { BaseBeanCopier copier = BaseBeanCopier.create(source.getClass(), clazz, false); T to = newInstance(clazz); copier.copy(source, to, null); return to; } /** * 拷贝对象 * * 注意:不支持链式Bean,链式用 copyProperties * * @param source 源对象 * @param targetBean 需要赋值的对象 */ public static void copy(Object source, Object targetBean) { BaseBeanCopier copier = BaseBeanCopier .create(source.getClass(), targetBean.getClass(), false); copier.copy(source, targetBean, null); } /** * Copy the property values of the given source bean into the target class. * <p>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. * <p>This is just a convenience method. For more complex transfer needs, * @param source the source bean * @param target the target bean class * @param <T> 泛型标记 * @throws BeansException if the copying failed * @return T */ public static <T> T copyProperties(Object source, Class<T> target) throws BeansException { T to = newInstance(target); BeanUtil.copyProperties(source, to); return to; } /** * 将对象装成map形式 * @param bean 源对象 * @return {Map} */ @SuppressWarnings("unchecked") public static Map<String, Object> toMap(Object bean) { return BeanMap.create(bean); } /** * 将map 转为 bean * @param beanMap map * @param valueType 对象类型 * @param <T> 泛型标记 * @return {T} */ public static <T> T toBean(Map<String, Object> beanMap, Class<T> valueType) { T bean = BeanUtil.newInstance(valueType); BeanMap.create(bean).putAll(beanMap); return bean; } /** * 给一个Bean添加字段 * @param superBean 父级Bean * @param props 新增属性 * @return {Object} */ public static Object generator(Object superBean, BeanProperty... props) { 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(); } /** * 获取 Bean 的所有 get方法 * @param type 类 * @return PropertyDescriptor数组 */ public static PropertyDescriptor[] getBeanGetters(Class type) { return getPropertiesHelper(type, true, false); } /** * 获取 Bean 的所有 set方法 * @param type 类 * @return PropertyDescriptor数组 */ public static PropertyDescriptor[] getBeanSetters(Class type) { return getPropertiesHelper(type, false, true); } private static PropertyDescriptor[] getPropertiesHelper(Class type, boolean read, boolean write) { try { PropertyDescriptor[] all = BeanUtil.getPropertyDescriptors(type); if (read && write) { return all; } else { List<PropertyDescriptor> properties = new ArrayList<>(all.length); for (PropertyDescriptor pd : all) { if (read && pd.getReadMethod() != null) { properties.add(pd); } else if (write && pd.getWriteMethod() != null) { properties.add(pd); } } return properties.toArray(new PropertyDescriptor[0]); } } catch (BeansException ex) { throw new CodeGenerationException(ex); } } }