Java为实体类动态添加属性的方法详解

作者:执拗的小豆芽 时间:2023-09-01 05:31:43 

可以给已有实体类动态的添加字段并返回新的实体对象,不影响原来的实体对象结构。

添加依赖

<dependency>
           <groupId>cglib</groupId>
           <artifactId>cglib</artifactId>
           <version>2.2.2</version>
       </dependency>

<dependency>
           <groupId>commons-beanutils</groupId>
           <artifactId>commons-beanutils</artifactId>
           <version>1.9.4</version>
       </dependency>

代码

import com.google.common.collect.Maps;
import net.sf.cglib.beans.BeanGenerator;
import net.sf.cglib.beans.BeanMap;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.PropertyDescriptor;
import java.util.Map;

/**
* 动态为bean添加字段
* @Author gongl
* @Create 2022-01-11
*/
public class DynamicBeanUtils {

private static final Logger logger = LoggerFactory.getLogger(DynamicBeanUtils.class);

public static Object getTarget(Object dest, Map<String, Object> addProperties) {
       PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
       //得到原对象的属性
       PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(dest);
       Map<String, Class<?>> propertyMap = Maps.newHashMap();
       for (PropertyDescriptor d : descriptors) {
           if (!"class".equalsIgnoreCase(d.getName())) {
               propertyMap.put(d.getName(), d.getPropertyType());
           }
       }
       addProperties.forEach((k, v) -> propertyMap.put(k, v.getClass()));
       //构建新的对象
       DynamicBean dynamicBean = new DynamicBean(dest.getClass(), propertyMap);
       for (Map.Entry<String, Class<?>> entry : propertyMap.entrySet()) {
           try {
               if (!addProperties.containsKey(entry.getKey())) {//原来的值
                   dynamicBean.setValue(entry.getKey(), propertyUtilsBean.getNestedProperty(dest, entry.getKey()));
               }else {//新增的值
                   dynamicBean.setValue(entry.getKey(), addProperties.get(entry.getKey()));
               }
           } catch (Exception e) {
               logger.error(e.getMessage(), e);
           }
       }
       return dynamicBean.getTarget();
   }

private static class DynamicBean {
       /**
        * 目标对象
        */
       private Object target;

/**
        * 属性集合
        */
       private BeanMap beanMap;

public DynamicBean(Class<?> superclass, Map<String, Class<?>> propertyMap) {
           this.target = generateBean(superclass, propertyMap);
           this.beanMap = BeanMap.create(this.target);
       }

/**
        * bean 添加属性和值
        *
        * @param property
        * @param value
        */
       public void setValue(String property, Object value) {
           beanMap.put(property, value);
       }

/**
        * 获取属性值
        *
        * @param property
        * @return
        */
       public Object getValue(String property) {
           return beanMap.get(property);
       }

/**
        * 获取对象
        *
        * @return
        */
       public Object getTarget() {
           return this.target;
       }

/**
        * 根据属性生成对象
        *
        * @param superclass
        * @param propertyMap
        * @return
        */
       private Object generateBean(Class<?> superclass, Map<String, Class<?>> propertyMap) {
           BeanGenerator generator = new BeanGenerator();
           if (null != superclass) {
               generator.setSuperclass(superclass);
           }
           BeanGenerator.addProperties(generator, propertyMap);
           return generator.create();
       }
   }
}

测试

public static class TestBean{
       private String name;

public String getName() {
           return name;
       }

public void setName(String name) {
           this.name = name;
       }
   }
   public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
       TestBean bean = new TestBean();
       bean.setName("张三");
       Map<String, Object> map = new HashMap<>();
       map.put("age", 29);
       //添加参数age--->29
       Object obj = DynamicBeanUtils.getTarget(bean, map);
       //打印结果
       Method[] declaredMethods = obj.getClass().getDeclaredMethods();
       for(Method method:declaredMethods){
           if(method.getName().startsWith("get")){
               Object o=method.invoke(obj);
               System.out.println("属性值get方法->"+o);
           }
       }
   }

结果打印出name和age的值

Java为实体类动态添加属性的方法详解

来源:https://blog.csdn.net/weixin_47914635/article/details/123550354

标签:Java,实体类,动态,添加,属性
0
投稿

猜你喜欢

  • c++传递函数指针和bind的示例

    2021-06-18 18:34:38
  • Windows编写jar启动脚本和关闭脚本的操作方法

    2021-05-28 04:36:58
  • C# 如何调用C++ dll string类型返回

    2023-01-31 02:27:55
  • 在C#中global关键字的作用及其用法

    2021-12-24 04:33:19
  • RocketMQ producer容错机制源码解析

    2022-05-14 13:39:41
  • Java中的Gradle与Groovy的区别及存在的关系

    2023-05-13 17:28:46
  • C#实现输入10个数存入到数组中并求max和min及平均数的方法示例

    2023-11-30 05:58:54
  • Java系统的高并发解决方法详解

    2021-08-23 08:39:50
  • C#合并多种格式文件为PDF的方法

    2023-12-11 17:46:58
  • Java自定义异常类的实例详解

    2021-10-21 07:18:33
  • Java SSM配置文件案例详解

    2022-10-14 09:43:19
  • C语言实现字符串拼接和拷贝

    2021-06-07 14:50:09
  • Android 双击Back键退出应用的实现方法

    2023-07-06 05:41:41
  • Spring基于AspectJ的AOP开发案例解析

    2021-12-01 01:59:22
  • Java语言描述二叉树的深度和宽度

    2021-12-02 10:59:34
  • Android利用Flutter实现立体旋转效果

    2023-06-20 08:20:32
  • java list随机抽取元素的案例

    2023-12-22 22:21:59
  • 分析并发编程之LongAdder原理

    2023-05-11 17:19:30
  • C# ConfigHelper 辅助类介绍

    2023-11-20 21:53:09
  • 服务器端C#实现的CSS解析器

    2022-01-25 12:26:20
  • asp之家 软件编程 m.aspxhome.com