Cglib应用:基于Map动态生成JavaBean对象

简介: 再某些特殊的场景下,存在手动创建java类的case,比如我有个需求,希望根据简单的Map对象,来生成一个对应的Java bean,可以怎么整?针对这个而典型的场景,先考虑是否有现成可用的开源工具类来实现,比如我们经常接触到cglib,它可以动态生成代理对象,那么生成Java Bean也没有什么问题接下来我们看一下使用cglib来创建bean的方式

再某些特殊的场景下,存在手动创建java类的case,比如我有个需求,希望根据简单的Map对象,来生成一个对应的Java bean,可以怎么整?


针对这个而典型的场景,先考虑是否有现成可用的开源工具类来实现,比如我们经常接触到cglib,它可以动态生成代理对象,那么生成Java Bean也没有什么问题


接下来我们看一下使用cglib来创建bean的方式


1. cglib动态创建bean



首先添加cglib的依赖

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>[3.3.0,)</version>
</dependency>
复制代码


接下来的bean创建,主要是借助 BeanGenereator + BeanMap来实现


创建Java Bean对象,主要借助 BeanGenerator来完成,需要根据传入的Map中value的类型,来定义生成对象的属性类型


private Object instanceObject(Map<String, Object> map) {
    Map<String, Class> properties = new HashMap<>(map.size());
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        properties.put(entry.getKey(), entry.getValue().getClass());
    }
    // 根据属性生成实体bean
    return generateBean(properties);
}
private Object generateBean(Map<String, Class> propertyMap) {
    //根据一组属性名和属性值的类型,动态创建Bean对象
    BeanGenerator generator = new BeanGenerator();
    Set keySet = propertyMap.keySet();
    for (Iterator i = keySet.iterator(); i.hasNext(); ) {
        String key = (String) i.next();
        generator.addProperty(key, (Class) propertyMap.get(key));
    }
    return generator.create();  //创建Bean
}
复制代码


上面这两个方法,就实现了根据Map来创建java bean对象;此时bean对象已经生成,成员属性也都指定了,但是还没有初始化value


接下来的value设置,则利用BeanMap来处理

private void initObject(Map<String, Object> map) {
    //用实体Bean创建BeanMap,用于获取和设置value
    // 这个object就是上面生成的实体类
    beanMap = BeanMap.create(this.object);
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        beanMap.put(entry.getKey(), entry.getValue());
    }
}
复制代码


如果我们希望获取这个object中的成员值,同样也是借助BeanMap来实现(因为新生成的JavaBean并没有赋予相应的get/set方法)


public Object getValue(String key) {
    return beanMap.get(key);
}
复制代码


接下来将上面的代码封装一下,并给一个测试

public class CglibBean {
    private Object object = null;
    private BeanMap beanMap = null;
    public CglibBean(Map<String, Object> map) {
        this.object = instanceObject(map);
        initObject(map);
    }
    private Object instanceObject(Map<String, Object> map) {
        Map<String, Class> properties = new HashMap<>(map.size());
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            properties.put(entry.getKey(), entry.getValue().getClass());
        }
        // 根据属性生成实体bean
        return generateBean(properties);
    }
    private void initObject(Map<String, Object> map) {
        //用实体Bean创建BeanMap,用于获取和设置value
        beanMap = BeanMap.create(this.object);
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            beanMap.put(entry.getKey(), entry.getValue());
        }
    }
    /**
     * 得到该实体bean对象
     *
     * @return
     */
    public Object getObject() {
        return this.object;
    }
    public Object getValue(String key) {
        return beanMap.get(key);
    }
    private Object generateBean(Map<String, Class> propertyMap) {
        //根据一组属性名和属性值的类型,动态创建Bean对象
        BeanGenerator generator = new BeanGenerator();
        Set keySet = propertyMap.keySet();
        for (Iterator i = keySet.iterator(); i.hasNext(); ) {
            String key = (String) i.next();
            generator.addProperty(key, (Class) propertyMap.get(key));
        }
        return generator.create();  //创建Bean
    }
    public static void main(String[] args) throws IllegalAccessException { // 设置类成员属性
        HashMap<String, Object> map = new HashMap<>();
        map.put("id", 123);
        map.put("name", "hello");
        map.put("now", new Date());
        CglibBean bean = new CglibBean(map);
        // 获得bean的实体
        Object object = bean.getObject();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field f: fields) {
            f.setAccessible(true);
            System.out.println("field: " + f.getName() + " = " + f.get(object));
        }
        System.out.println("----------------");
        System.out.println(bean.getValue("id"));
    }
}
复制代码


接下来我们看一下测试输出

field: $cglib_prop_now = Fri Aug 20 16:29:00 CST 2021
field: $cglib_prop_name = hello
field: $cglib_prop_id = 123
----------------
123



相关文章
|
6月前
|
存储 JavaScript 索引
js开发:请解释什么是ES6的Map和Set,以及它们与普通对象和数组的区别。
ES6引入了Map和Set数据结构。Map的键可以是任意类型且有序,与对象的字符串或符号键不同;Set存储唯一值,无重复。两者皆可迭代,支持for...of循环。Map有get、set、has、delete等方法,Set有add、delete、has方法。示例展示了Map和Set的基本操作。
103 3
|
23天前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
40 3
|
2月前
ES6中map对象的使用,确实比Object好使哈
ES6中Map对象的使用优势,包括任意类型作为键、直接获取大小、增删查改操作等。Map的键可以是函数、对象、NaN等,支持forEach循环和for...of循环。
30 1
ES6中map对象的使用,确实比Object好使哈
|
2月前
|
数据处理 Python
Pandas中的map函数应用
Pandas中的map函数应用
18 2
|
2月前
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
|
4月前
|
JSON JavaScript API
JS【详解】Map (含Map 和 Object 的区别,Map 的常用 API,Map与Object 的性能对比,Map 的应用场景和不适合的使用场景)
JS【详解】Map (含Map 和 Object 的区别,Map 的常用 API,Map与Object 的性能对比,Map 的应用场景和不适合的使用场景)
96 0
|
5月前
|
Java
Java list中的对象转为list,list中的对象转为map
Java list中的对象转为list,list中的对象转为map
108 1
|
5月前
|
安全 Java
如何测试map对象的线程不安全
【6月更文挑战第20天】如何测试map对象的线程不安全
41 0
|
6月前
|
Java
SpringBoot 项目启动初始化一个Map对象到内存
SpringBoot 项目启动初始化一个Map对象到内存
138 1
|
6月前
|
JavaScript
js Array map映射对象多个属性
js Array map映射对象多个属性
42 0