CGLIB在没有创建类的情况下生成一个bean

没有类,能有bean,之前是不敢想象的,但是cglib做到了

基于BeanGenerator和BeanMap自动生成了一个bean

复制代码
public class CglibBean {
    private Object object = null;

    private BeanMap beanMap = null;

    public CglibBean() {
        super();
    }

    public CglibBean(Map<String,Class<?>> propertyMap) {
        this.object=generateBean(propertyMap);
        this.beanMap=BeanMap.create(this.object);
    }

    private Object generateBean(Map<String, Class<?>> propertyMap) {
        if(propertyMap==null||propertyMap.isEmpty()){
            return null;
        }
        BeanGenerator beanGenerator = new BeanGenerator();
        for (Map.Entry<String, Class<?>> entry : propertyMap.entrySet()) {
            beanGenerator.addProperty(entry.getKey(), entry.getValue());
        }
        return beanGenerator.create();
    }

    public void setValue(String property, Object value) {
        beanMap.put(property, value);
    }

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

    public Object getObject() {
        return object;
    }

    public static void main(String[] args) throws ClassNotFoundException {
        HashMap<String, Class<?>> propertyMap = new HashMap<>();
        propertyMap.put("id",Class.forName("java.lang.Integer"));
        propertyMap.put("name",Class.forName("java.lang.String"));
        propertyMap.put("age",Class.forName("java.lang.Integer"));
        CglibBean cglibBean = new CglibBean(propertyMap);
        cglibBean.setValue("id",1);
        cglibBean.setValue("name","www");
        cglibBean.setValue("age",17);
        Object object1 = cglibBean.getObject();
        Class<?> aClass = object1.getClass();
        System.out.println(aClass);
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println("field:"+field.getName());
        }
        Method[] methods = aClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("method:"+method.getName());
        }

        System.out.println(JSON.toJSONString(object1));
        System.out.println(cglibBean.getValue("id"));
        System.out.println(cglibBean.getValue("name"));
        System.out.println(cglibBean.getValue("age"));
    }
}
复制代码

既能赋值,也能获取值,虽然没创建类,既有field,也有method,这就是CGLIB的魅力

 还有一种情况,我已经有一个类了,但是新需求要求增加一个属性,我又不想改代码,能动态加吗?

答案是可以!

复制代码
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.sf.cglib.beans.BeanGenerator;
import net.sf.cglib.beans.BeanMap;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class DynamicObject {

    private Object object;    //对象

    private BeanMap beanMap;    //对象的属性

    private BeanGenerator beanGenerator;    //对象生成器

    private Map<String, Class<?>> allProperty;    //对象的<属性名, 属性名对应的类型>

    public DynamicObject() {
    }


    /**给对象属性赋值
     *
     * @param property
     * @param value
     */
    public void setValue(String property, Object value){
        beanMap.put(property, value);
    }

    private void setValue(Object object, Map<String, Class<?>> property){
        for(String propertyName : property.keySet()){
            if(allProperty.containsKey(propertyName)){
                Object propertyValue = getPropertyValueByName(object, propertyName);
                this.setValue(propertyName, propertyValue);
            }
        }
    }

    private void setValue(Map<String, Object> propertyValue){
        for(Map.Entry<String, Object> entry : propertyValue.entrySet()){
            this.setValue(entry.getKey(), entry.getValue());
        }
    }

    /**通过属性名获取属性值
     *
     * @param property
     * @return
     */
    public Object getValue(String property){
        return beanMap.get(property);
    }

    /**获取该bean的实体
     *
     * @return
     */
    public Object getObject(){
        return this.object;
    }

    public Map<String, Class<?>> getAllProperty() {
        return allProperty;
    }


    private Object generateObject(Map<String,Class<?>> propertyMap){
        if(null == beanGenerator){
            beanGenerator = new BeanGenerator();
        }

        Set<String> keySet = propertyMap.keySet();
        for (String key : keySet) {
            beanGenerator.addProperty(key, propertyMap.get(key));
        }
        return beanGenerator.create();
    }

    /**添加属性名与属性值
     *
     * @param propertyType
     * @param propertyValue
     */
    private void addProperty(Map<String,Class<?>> propertyType, Map<String, Object> propertyValue ){
        if(null == propertyType){
            throw new RuntimeException("动态添加属性失败!");
        }
        Object oldObject = object;
        object = generateObject(propertyType);
        beanMap = BeanMap.create(object);

        if(null != oldObject){
            setValue(oldObject, allProperty);
        }

        setValue(propertyValue);
        if(null == allProperty){
            allProperty = propertyType;
        }else{
            allProperty.putAll(propertyType);
        }
    }

    /**获取对象中的所有属性名与属性值
     *
     * @param object
     * @return
     * @throws ClassNotFoundException
     */
    public Map<String, Class<?>> getAllPropertyType(Object object) throws ClassNotFoundException{
        Map<String, Class<?>> map = new HashMap<String, Class<?>>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            String propertyName = field.getName();
            Class<?> propertyType = Class.forName(field.getGenericType().getTypeName());
            map.put(propertyName, propertyType);
        }
        return map;
    }

    /**获取对象中的所有属性名与属性值
     *
     * @param object
     * @return
     * @throws ClassNotFoundException
     */
    public Map<String, Object> getAllPropertyValue(Object object) throws ClassNotFoundException, IllegalAccessException {
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            String propertyName = field.getName();
//            Object propertyValue = getPropertyValueByName(object, propertyName);
            field.setAccessible(true);
            Object propertyValue = field.get(object);
            map.put(propertyName, propertyValue);
        }
        return map;
    }

    /**根据属性名获取对象中的属性值
     *
     * @param propertyName
     * @param object
     * @return
     */


    private Object getPropertyValueByName(Object object, String propertyName){
        String methodName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        Object value = null;
        try {
            Method method = object.getClass().getMethod(methodName, new Class[]{});
            value = method.invoke(object, new Object[]{});
        } catch (Exception e) {
            System.err.println(String.format("从对象%s获取%s的=属性值失败", object, propertyName));
        }
        return value;
    }


    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException {

        User user = new User();
        user.setName("张三");
        user.setAge(20);

        DynamicObject dynamicBean = new DynamicObject();

        //1、在原来的对象新增属性
        Map<String, Class<?>> allPropertyType = dynamicBean.getAllPropertyType(user);
        Map<String, Object> allPropertyValue = dynamicBean.getAllPropertyValue(user);
        allPropertyType.put("phone", Class.forName("java.lang.String"));
        allPropertyValue.put("phone", "1321111111");
        dynamicBean.addProperty(allPropertyType, allPropertyValue);

        System.out.println(JSON.toJSON(dynamicBean.getObject()));

        //2、动态创建一个新对象
        Map<String, Class<?>> newPropertyType = new HashMap<>();
        Map<String, Object> newPropertyValue = new HashMap<>();
        newPropertyType.put("address", Class.forName("java.lang.String"));
        newPropertyValue.put("address", "地址地址");

        dynamicBean.addProperty(newPropertyType, newPropertyValue);

        Object entity = dynamicBean.getObject();

        System.out.println(JSONObject.toJSONString(entity));
    }
}
复制代码

其中user就是我们已经定义好的类,只有两个属性

复制代码
public class User {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
复制代码

我们在不改变user的情况下,基于user生成了一个新的bean

输出:

{"phone":"1321111111","name":"张三","age":20}
{"address":"地址地址","age":20,"name":"张三","phone":"1321111111"}

 

posted @   Mars.wang  阅读(108)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
历史上的今天:
2021-03-13 spark经典PDF电子书
2021-03-13 软件工程、编程语言经典PDF电子书
2021-03-13 数据库系统方面经典PDF电子书
2021-03-13 计算机网络类经典PDF电子书
2017-03-13 python正则表达式
2017-03-13 python之数据分析pandas
2017-03-13 python文件IO
点击右上角即可分享
微信分享提示