当前位置:Gxlcms > 数据库问题 > 构建施耐德楼控系统数据库后台服务器示例工程五(JAVA动态生成类)

构建施耐德楼控系统数据库后台服务器示例工程五(JAVA动态生成类)

时间:2021-07-01 10:21:17 帮助过:24人阅读

szx.core.util.sub; 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(); } }

2)生成DynamicBean类

    public List<Object> executeSQLGetColumAndValue(String sql)
    {
        Map<String, Class> columnMap = new HashMap<String, Class>();
        DynamicBean beanUtil = null;
        Object ob = null;

        Connection conn = null;
        ResultSet rs = null;
        ResultSetMetaData rsm = null;
        List<Object> list = null;
        try {
            conn = SessionFactoryUtils.getDataSource(super.getSessionFactory()).getConnection();
            rsm = conn.prepareStatement(sql).executeQuery().getMetaData();
            for(int i = 1; i <= rsm.getColumnCount(); i++)
            {
                columnMap.put(rsm.getColumnName(i), Class.forName(rsm.getColumnClassName(i)));
//              System.out.println("colName:"+rsm.getColumnName(i).toString()
//                      +",colNameValue"+rsm.getColumnClassName(i).toString());
            }
            ob = new DynamicBean(columnMap).getObject();

            rs = conn.prepareStatement(sql).executeQuery();

            list = new LinkedList<Object>();
            Class cls = ob.getClass();
            Field[] fields = cls.getDeclaredFields();
            while(rs.next())
            {
                Object tmp = cls.newInstance();

                for(int i = 0; i < fields.length; i++)
                {
                    String fieldName = fields[i].getName().replace("$cglib_prop_", "");

                    String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

                    Method setMethod = cls.getDeclaredMethod(setMethodName, new Class[]{fields[i].getType()});

                    setMethod.invoke(tmp, rs.getObject(fieldName));

                    //System.out.println("fieldName:"+fieldName+",setMethodName:"+setMethodName+",\nsetMethod:"+setMethod);
                }

                list.add(tmp);
            }

            return list;
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        } finally {
            try {

            } catch (Exception ex) {
            }
            try {
                conn.close();
            } catch (Exception ex) {
            }
        }

    }

上面的示例功能是:从数据库中读取表数据,将读取来的值赋予动态创建的对象中。
上述使用CGLIB的核心代码如下:

Map<String, Class> columnMap = new HashMap<String, Class>();
DynamicBean beanUtil = null;
Object ob = null;

.......

columnMap.put(rsm.getColumnName(i), Class.forName(rsm.getColumnClassName(i)));

.......

ob = new DynamicBean(columnMap).getObject();
Class cls = ob.getClass();
Field[] fields = cls.getDeclaredFields();
while(rs.next())
{
    Object tmp = cls.newInstance();

    for(int i = 0; i < fields.length; i++)
    {
        String fieldName = fields[i].getName().replace("$cglib_prop_", "");
        String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        Method setMethod = cls.getDeclaredMethod(setMethodName, new Class[]{fields[i].getType()});
        setMethod.invoke(tmp, rs.getObject(fieldName));
    }

    list.add(tmp);
}

3)从新生成的DynamicBean对象中读取属性及属性值

JSONObject jsonObject = new JSONObject();

Class valueClz = value.getClass();
//System.out.println("valueClz:"+valueClz);
if(valueClz.toString().contains("BeanGeneratorByCGLIB"))
{
    Field fields[] = value.getClass().getDeclaredFields();// 获得对象所有属性

    for (int j = 0; j < fields.length; j++) {
        Field field = fields[j];
        field.setAccessible(true);// 修改访问权限
        String propertyName = fields[j].getName().replace("$cglib_prop_", "");;
        jsonObject.put(propertyName, Object2JSONObject(field.get(value)));
        //System.out.println(propertyName + ":" + field.get(value));
    }
}                

上述判断Class类名是否包含”BeanGeneratorByCGLIB“这个字符串,仅是用于生成JSON串的工具类JSONUtil判断当前的对象是CGLIB创建的对象。
上面的获取对象的属性和值使用的是JAVA的反射机制。
3.CGLIB生成的类输出

动态的生成类名:class net.sf.cglib.empty.Object$$BeanGeneratorByCGLIB$$5fb90c30
属性名:$cglib_prop_AlarmTypeText,值:NORMAL
属性名:$cglib_prop_rownumber,值:1
属性名:$cglib_prop_AlarmTypeId,值:0

....................................

生成的JSON串:
{"ack": {
    "items": [
        {
            "AlarmTypeText": "NORMAL",
            "rownumber": 1,
            "AlarmTypeId": 0
        }
    ],
    "totalNum": 1
}}

4.其他
1)在Hibernate的OR Mapping、Spring的AOP都使用到了CGLIB完成其功能。
2)CGLIB处理动态生成类外,还可以完成这种动态代理,即代理没有实现接口的继承的类,可以使用CGLIB包。因为JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,就需要使用CGLIB包。
3)CGLIB底层采用的是ASM去实现的,ASM是一个JAVA字节码操纵框架,深入了解需要首先立即JAVA虚拟机JVM的原理。
上述三点需要逐一学习,本篇就不详细介绍了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

构建施耐德楼控系统数据库后台服务器示例工程五(JAVA动态生成类)

标签:java   cglib   java动态生成类   

人气教程排行