1.创建一个类,用来接收动态添加属性后的一些值
package com.yunzhi.village.test;
import lombok.Data;
import org.springframework.cglib.beans.BeanGenerator;
import org.springframework.cglib.beans.BeanMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@Data
public class DynamicBean {
private Object object = null; // 动态生成的类
private BeanMap beanMap = null; // 存放属性名称以及属性的类型
public DynamicBean() {
super();
}
public DynamicBean(Map propertyMap) {
this.object = generateBean(propertyMap);
this.beanMap = BeanMap.create(this.object);
}
/**
* @param propertyMap
* @return
*/
private Object generateBean(Map propertyMap) {
BeanGenerator generator = new BeanGenerator();
Set keySet = propertyMap.keySet();
for (Iterator<String> i = keySet.iterator(); i.hasNext(); ) {
String key = (String) i.next();
generator.addProperty(key, (Class) propertyMap.get(key));
}
return generator.create();
}
/**
* set beanMap
* @param property
* @param value ֵ
*/
public void setValue(Object property, Object value) {
beanMap.put(property, value);
}
/**
* ͨget beanMap
* @param property
* @return ֵ
*/
public Object getValue(String property) {
return beanMap.get(property);
}
}
2.业务逻辑代码
moneyMap:代表业务中需要动态添加的属性(属性名和值)
/**
*参数说明:
* object : 查询结果数组中对象。
* moneyMap : 为对象对应所有月份数据集合
* Map<String,Bigdecimal>, 存放了月份及金额
*/
private Object dynamicClass(Object object, Map<String, BigDecimal> moneyMap) throws Exception {
// 字段 - 值 集合
HashMap<String, Object> returnMap = new HashMap<>();
// 字段 - 字段类型 集合
HashMap<String, Object> typeMap = new HashMap<>();
// 获取传入类
Class<? extends Object> type = object.getClass();
BeanInfo beanInfo = Introspector.getBeanInfo(type);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
// 获取对象中已存在的数据
for (int i = 0; i < propertyDescriptors.length; i++) {
PropertyDescriptor descriptor = propertyDescriptors[i];
String propertyName = descriptor.getName();
if (!propertyName.equals("class") && !propertyName.equals("monthMap")) {
Method readMethod = descriptor.getReadMethod();
Object result = readMethod.invoke(object, new Object[0]);
if (result != null) {
returnMap.put(propertyName, result);
} else {
String propertyType = descriptor.getPropertyType().toString();
if (propertyType.contains("java.math.BigDecimal")) {
returnMap.put(propertyName, new BigDecimal(0));
} else {
returnMap.put(propertyName, "");
}
}
typeMap.put(propertyName, descriptor.getPropertyType());
}
}
// 获取月份数据, 变为字段属性
Set<String> monthKeys = moneyMap.keySet();
for (Iterator<String> it = monthKeys.iterator(); it.hasNext();) {
String key = (String) it.next();
// 字段类型
typeMap.put(key, Class.forName("java.math.BigDecimal"));
// 字段对应值
returnMap.put(key, moneyMap.get(key));
}
// map转换成实体对象
DynamicBean bean = new DynamicBean(typeMap);
// 赋值
Set<String> keys = typeMap.keySet();
for (Iterator<String> it = keys.iterator(); it.hasNext();) {
String key = (String) it.next();
bean.setValue(key, returnMap.get(key));
}
Object obj = bean.getObject();
return obj;
}
3.执行即可
public static void main(String[] args) throws Exception {
Test test = new Test();
User user = new User("ddd","温州","","男",12);
Map<String, BigDecimal> map = new HashMap<>();
map.putIfAbsent("2", new BigDecimal(45678));
map.putIfAbsent("4", new BigDecimal(12365));
Object o = test.dynamicClass(user, map);
}
此处的 o 对象,是把user中的属性和动态添加的 BigDecimal 2 = 45678 和 BigDecimal 4 = 45678整合到o对象中。
4.涉及的Spring技术(后续可能会出Spring源码讲解的文章)
BeanInfo beanInfo = Introspector.getBeanInfo(type); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();BeanMap beanMap;BeanGenerator generator = new BeanGenerator();