在程序的运行过程中,我们可能需要根据一些给定字符串来动态生成实体;
由于给定字符串每次都不相同, 所以每次生成的实体对象的变量和值均不相同,依靠cglib包的一些方法可以将此功能实现。
首先添加jar包:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.2.4</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
</dependency>
根据属性动态生成对象方法:
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.cglib.beans.BeanGenerator;
import java.util.Map;
/**
* 实体工具类
*/
public class GenerateObjectUtil {
/**
* 根据属性动态生成对象,并赋值
* <p>
* 注意:返回生成的对象属性,均在设置属性前加入前缀$cglib_prop_,例如$cglib_prop_userId
*
* @param propertyMap Map<生成的对象变量名称,生成的对象变量值>
* @return Object
*/
public static Object generateObjectByField(Map<String, Object> propertyMap) throws Exception {
BeanGenerator generator = new BeanGenerator();
for (Map.Entry<String, Object> entry : propertyMap.entrySet()) {
generator.addProperty(entry.getKey(), entry.getValue().getClass());
}
// 构建对象
Object obj = generator.create();
// 赋值
for (Map.Entry<String, Object> en : propertyMap.entrySet()) {
BeanUtils.setProperty(obj, en.getKey(), en.getValue());
}
return obj;
}
}
下面是main方法的最终调用实现:
public class Test {
public static void main(String[] args) throws Exception {
Map<String,Object> map = new HashMap<>();
map.put("userName","张三");
map.put("password",123456);
Object obj = GenerateObjectUtil.generateObjectByField(map);
System.out.println(new Gson().toJson(obj));
}
}
输出结果为:
可以看到我随手构造的实体已经成功构造并赋值。
通过结果可以发现一个问题,生成的实体属性,均加上了“$cglib_prop_”的前缀,在使用的过程中应当注意。
我们可以将生成的对象通过转换为json字符串,替换掉前缀再转换回Bean的方法来去掉前缀【修改刚刚的工具方法】:
public static Object generateObjectByField(Map<String, Object> propertyMap) throws Exception {
BeanGenerator generator = new BeanGenerator();
for (Map.Entry<String, Object> entry : propertyMap.entrySet()) {
generator.addProperty(entry.getKey(), entry.getValue().getClass());
}
Object obj = generator.create();
for (Map.Entry<String, Object> en : propertyMap.entrySet()) {
BeanUtils.setProperty(obj, en.getKey(), en.getValue());
}
// json转换去掉前缀
String gsonString = new Gson().toJson(obj).replace("$cglib_prop_", "");
return new Gson().fromJson(gsonString, Object.class);
}
此时再输出结果:
ok,完美!