Java動態生成類以及動態新增屬性
阿新 • • 發佈:2018-11-01
有個技術實現需求:動態生成類,其中類中的屬性來自引數物件中的全部屬性以及來自引數物件propertities檔案。
那麼技術實現支援:使用cglib代理。
具體的實現步驟:
1.cglib的jar包(cglib-nodep):我用的是cglib-nodep-2.2.jar
2.封裝的cglib類:
3.需求的實現類:
4.技術實現目的:前臺框架表格資料來源實際上就是帶有資料的實體,但是grid中資料的型別、已經是否可見、toolbar工具欄上的按鈕、是否分頁,是針對實體而言,所以目前把這些資訊作為實體的配置檔案。在展示頁面之前,讀取全部資訊,轉為引數物件的完整物件。
package com.citics.test.model; import java.util.Iterator; import java.util.Map; import java.util.Set; import net.sf.cglib.beans.BeanGenerator; import net.sf.cglib.beans.BeanMap; public class DynamicBean { private Object object = null;//動態生成的類 private BeanMap beanMap = null;//存放屬性名稱以及屬性的型別 public DynamicBean() { super(); } @SuppressWarnings("rawtypes") public DynamicBean(Map propertyMap) { this.object = generateBean(propertyMap); this.beanMap = BeanMap.create(this.object); } /** * 給bean屬性賦值 * @param property 屬性名 * @param value 值 */ public void setValue(Object property, Object value) { beanMap.put(property, value); } /** * 通過屬性名得到屬性值 * @param property 屬性名 * @return 值 */ public Object getValue(String property) { return beanMap.get(property); } /** * 得到該實體bean物件 * @return */ public Object getObject() { return this.object; } /** * @param propertyMap * @return */ @SuppressWarnings("rawtypes") private Object generateBean(Map propertyMap) { 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(); } }
3.需求的實現類:
package com.citics.platformx.test.controller; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.InputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Set; import com.citics.test.model.DynamicBean; import com.citics.test.model.LeapRole; public class ClassUtil { private String filepath="/config/";//配置檔案路徑 public String getFilepath() { return filepath; } public void setFilepath(String filepath) { this.filepath = filepath; } @SuppressWarnings({ "rawtypes","unchecked"}) public Object dynamicClass(Object object) throws Exception{ HashMap returnMap = new HashMap(); HashMap typeMap=new HashMap(); //讀取配置檔案 Properties prop=new Properties(); String sourcepackage=object.getClass().getName(); String classname=sourcepackage.substring(sourcepackage.lastIndexOf(".")+1); InputStream in=ClassUtil.class.getResourceAsStream(filepath+classname+".properties"); prop.load(in); Set<String> keylist=prop.stringPropertyNames(); Class type=object.getClass(); BeanInfo beanInfo = Introspector.getBeanInfo(type); PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors(); for(int i=0;i<propertyDescriptors.length;i++){ PropertyDescriptor descriptor=propertyDescriptors[i]; String propertyName = descriptor.getName(); if(!propertyName.equals("class")){ Method readMethod=descriptor.getReadMethod(); Object result = readMethod.invoke(object, new Object[0]); if (result != null) { returnMap.put(propertyName, result); } else { returnMap.put(propertyName, ""); } typeMap.put(propertyName, descriptor.getPropertyType()); } } //載入配置檔案中的屬性 Iterator<String> iterator=keylist.iterator(); while(iterator.hasNext()){ String key=iterator.next(); returnMap.put(key, prop.getProperty(key)); typeMap.put(key, Class.forName("java.lang.String")); } //map轉換成實體物件 DynamicBean bean = new DynamicBean(typeMap); //賦值 Set keys=typeMap.keySet(); for(Iterator it=keys.iterator();it.hasNext();){ String key = (String) it.next(); bean.setValue(key, returnMap.get(key)); } Object obj=bean.getObject(); return obj; } public static void main(String[] args) throws Exception{ new ClassUtil().dynamicClass(new LeapRole()); } }
4.技術實現目的:前臺框架表格資料來源實際上就是帶有資料的實體,但是grid中資料的型別、已經是否可見、toolbar工具欄上的按鈕、是否分頁,是針對實體而言,所以目前把這些資訊作為實體的配置檔案。在展示頁面之前,讀取全部資訊,轉為引數物件的完整物件。