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"}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源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