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的值
来源:https://blog.csdn.net/weixin_47914635/article/details/123550354
标签:Java,实体类,动态,添加,属性
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
c++传递函数指针和bind的示例
2021-06-18 18:34:38
Windows编写jar启动脚本和关闭脚本的操作方法
2021-05-28 04:36:58
![](https://img.aspxhome.com/file/2023/8/61298_0s.png)
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
![](https://img.aspxhome.com/file/2023/6/95946_0s.png)
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
![](https://img.aspxhome.com/file/2023/3/119533_0s.png)
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
![](https://img.aspxhome.com/file/2023/9/96759_0s.png)
java list随机抽取元素的案例
2023-12-22 22:21:59
![](https://img.aspxhome.com/file/2023/0/71920_0s.jpg)
分析并发编程之LongAdder原理
2023-05-11 17:19:30
![](https://img.aspxhome.com/file/2023/9/65599_0s.jpg)
C# ConfigHelper 辅助类介绍
2023-11-20 21:53:09
服务器端C#实现的CSS解析器
2022-01-25 12:26:20