This is the 22nd day of my participation in the August Wen Challenge.More challenges in August

In some special scenarios, there is a case of manually creating Java classes. For example, I have a requirement that I want to generate a corresponding Java bean based on a simple Map object.

For this typical scenario, consider whether there is an open source utility class that is readily available. For example, we often come across Cglib, which generates proxy objects on the fly

Let’s take a look at creating beans using Cglib

1. Cglib dynamically creates beans

First add the cglib dependency

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>[3.3.0,)</version>
</dependency>
Copy the code

The following bean creation is mainly done with BeanGenereator + BeanMap

To create Java Bean objects, the BeanGenerator is used to define the property type of the generated object according to the type of the value in the 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());
    }
    // Generate entity beans based on attributes
    return generateBean(properties);
}

private Object generateBean(Map<String, Class> propertyMap) {
    // Dynamically create Bean objects based on a set of attribute names and attribute values
    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();  / / create a Bean
}
Copy the code

These two methods implement the creation of Java Bean objects based on the Map; At this point, the bean object has been generated and the member attributes have been specified, but the value has not been initialized

The next value setting is handled using a BeanMap

private void initObject(Map<String, Object> map) {
    // Create a BeanMap with entity beans to get and set values
    // This object is the entity class generated above
    beanMap = BeanMap.create(this.object);
    for(Map.Entry<String, Object> entry : map.entrySet()) { beanMap.put(entry.getKey(), entry.getValue()); }}Copy the code

If we want to get the member values of this object, we will do so using a BeanMap (since the newly generated Javabeans do not have corresponding GET /set methods).

public Object getValue(String key) {
    return beanMap.get(key);
}
Copy the code

Next, wrap the above code and give it a test

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());
        }
        // Generate entity beans based on attributes
        return generateBean(properties);
    }

    private void initObject(Map<String, Object> map) {
        // Create a BeanMap with entity beans to get and set values
        beanMap = BeanMap.create(this.object);
        for(Map.Entry<String, Object> entry : map.entrySet()) { beanMap.put(entry.getKey(), entry.getValue()); }}/** * returns the entity bean object **@return* /
    public Object getObject(a) {
        return this.object;
    }

    public Object getValue(String key) {
        return beanMap.get(key);
    }

    private Object generateBean(Map<String, Class> propertyMap) {
        // Dynamically create Bean objects based on a set of attribute names and attribute values
        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();  / / create a Bean
    }


    public static void main(String[] args) throws IllegalAccessException { // Set the class member properties
        HashMap<String, Object> map = new HashMap<>();
        map.put("id".123);
        map.put("name"."hello");
        map.put("now".new Date());

        CglibBean bean = new CglibBean(map);
        // Get the entity of the 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")); }}Copy the code

Let’s look at the test output

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

II. The other

1. A gray Blog:liuyueyi.github.io/hexblog

A gray personal blog, recording all the study and work in the blog, welcome everyone to go to stroll

2. Statement

As far as the letter is not as good, the above content is purely one’s opinion, due to the limited personal ability, it is inevitable that there are omissions and mistakes, if you find bugs or have better suggestions, welcome criticism and correction, don’t hesitate to appreciate

  • Micro Blog address: Small Gray Blog
  • QQ: a gray /3302797840
  • Wechat official account: One Grey Blog