java cglib 用法_java通过cglib动态生成实体bean的操作

本文详细介绍了如何在Java中使用CGlib库动态生成实体Bean,包括依赖引入、`DynamicBeanEntity`类的实现,以及如何通过反射和CGlib将JSON转换为实体类。文中提供了一个示例,展示了如何创建动态Bean并执行其方法,以及如何从数据库获取表结构生成对应的Bean实例。
摘要由CSDN通过智能技术生成

maven依赖:

commons-beanutils

commons-beanutils

1.9.3

cglib

cglib-nodep

3.2.4

DynamicBeanEntity.class动态bean类:

package com.dym.entity;

import net.sf.cglib.beans.BeanGenerator;

import org.apache.commons.collections.map.MultiValueMap;

import java.lang.reflect.*;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

/**

* @author: zhaoxu

* @description:

*/

public class DynamicBeanEntity {

Object dynamicBean;

Class clazz;

public DynamicBeanEntity(Map dynAttrMap) {

this.dynamicBean = generateBean(dynAttrMap);

clazz = dynamicBean.getClass();

}

/**

* 获取所有属性值

*

* @return

* @throws IllegalAccessException

*/

public Map getValues() throws IllegalAccessException {

Map fieldValuesMap = new HashMap(16);

Field[] fields = clazz.getDeclaredFields();

for (Field field : fields) {

field.setAccessible(true);

Object fieldValue = field.get(dynamicBean);

fieldValuesMap.put(field.getName().split("\\$cglib_prop_")[1], fieldValue);

}

return fieldValuesMap;

}

/**

* 获取动态bean所有方法信息

*

* @return

*/

public MultiValueMap getMethods() {

MultiValueMap map = new MultiValueMap();

Method[] methods = clazz.getMethods();

for (Method method : methods) {

Type[] genericParameterTypes = method.getGenericParameterTypes();

if (genericParameterTypes.length > 0) {

for (Type type : genericParameterTypes) {

map.put(method.getName(), type);

}

} else {

map.put(method.getName(), null);

}

}

return map;

}

/**

* 执行某个方法

*

* @param methodName

* @param parameters

* @return

* @throws InvocationTargetException

* @throws IllegalAccessException

* @throws NoSuchMethodException

*/

public Object executeMethod(String methodName, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {

ArrayList paramTypeList = new ArrayList();

for (Object paramType : parameters) {

paramTypeList.add(paramType.getClass());

}

Class[] classArray = new Class[paramTypeList.size()];

Method method = clazz.getMethod(methodName, paramTypeList.toArray(classArray));

Object invoke = method.invoke(dynamicBean, parameters);

return invoke;

}

/**

* 设置属性值

*

* @param property

* @param value

* @throws NoSuchFieldException

* @throws IllegalAccessException

*/

public void setValue(String property, Object value) throws NoSuchFieldException, IllegalAccessException {

Field declaredField = clazz.getDeclaredField("$cglib_prop_" + property);

declaredField.setAccessible(true);

declaredField.set(dynamicBean, value);

}

/**

* 获取属性值

*

* @param property

* @return

* @throws NoSuchFieldException

* @throws IllegalAccessException

*/

public Object getValue(String property) throws NoSuchFieldException, IllegalAccessException {

Field declaredField = clazz.getDeclaredField("$cglib_prop_" + property);

declaredField.setAccessible(true);

Object value = declaredField.get(dynamicBean);

return value;

}

public Object getEntity() {

return this.dynamicBean;

}

/**

* 利用cglib的BeanGenerator创建对象

*

* @param dynAttrMap

* @return

*/

private Object generateBean(Map dynAttrMap) {

BeanGenerator generator = new BeanGenerator();

Iterator iterator = dynAttrMap.keySet().iterator();

while (iterator.hasNext()) {

String key = iterator.next().toString();

generator.addProperty(key, (Class) dynAttrMap.get(key));

}

return generator.create();

}

}

test.class测试类测试动态生成bean

package com.dym.attr;

import com.dym.entity.DynamicBeanEntity;

import org.apache.commons.collections.map.MultiValueMap;

import java.lang.reflect.InvocationTargetException;

import java.util.HashMap;

import java.util.Map;

/**

* @author: zhaoxu

* @description:

*/

public class test {

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {

// 设置属性们,默认16

HashMap propertyMap = new HashMap(16);

propertyMap.put("name", String.class);

propertyMap.put("age", Integer.class);

propertyMap.put("height", Double.class);

// 生成动态 Entity

DynamicBeanEntity bean = new DynamicBeanEntity(propertyMap);

//设置属性值

bean.setValue("name", "zx");

bean.setValue("age", 22);

bean.setValue("height", 175.0);

//获取属性值

Map values = bean.getValues();

//获取可执行的方法

MultiValueMap methods = bean.getMethods();

//执行某个方法

bean.executeMethod("setAge", 23);

System.out.println("动态bean的age属性:"+bean.getValue("age"));

}

}

test.class测试类测试链接数据库动态生成bean

package com.dym.test;

import com.dym.util.DBUtil;

import com.dym.util.DynmicEntity;

import org.springframework.stereotype.Component;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Map;

/**

* @author: zhaoxu

* @description:

*/

@Component

public class test {

public static void main(String[] args) {

ArrayList beans = new ArrayList<>();

Connection conn = null;

PreparedStatement prst = null;

String sql = "";

sql = "select table_name from information_schema.tables where table_schema=\'public\'";

conn = DBUtil.getConn();

try {

prst = conn.prepareStatement(sql);

ResultSet rs = prst.executeQuery();

while (rs.next()) {

String tableName = rs.getString(1);

Map attrMap = new HashMap<>();

String findFieldSql = "SELECT format_type(a.atttypid,a.atttypmod) as type,a.attname as name, a.attnotnull as notnull \n" +

"FROM pg_class as c,pg_attribute as a where c.relname = \'" + tableName + "\' and a.attrelid = c.oid and a.attnum>0";

PreparedStatement fieldsPrst = conn.prepareStatement(findFieldSql);

ResultSet fieldsRs = fieldsPrst.executeQuery();

while (fieldsRs.next()) {

String fieldType = fieldsRs.getString(1);

String fieldName = fieldsRs.getString(2);

attrMap.put(fieldName, Object.class);

}

DynmicEntity bean = new DynmicEntity(attrMap);

beans.add(bean);

}

} catch (SQLException e) {

e.printStackTrace();

}

DBUtil.close(prst, conn);

}

}

DBUtil.class:

package com.dym.util;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

/**

* @author: zhaoxu

* @description:

*/

public class DBUtil {

private final static String URL="jdbc:postgresql://localhost:5432/dynmic";

private final static String NAME="postgres";

private final static String PASS="123456";

private static Connection conn=null;

/**

*

*@Title:DBUtil

*@Description:

*/

public DBUtil(){

}

/**

*

* @Tiltle getConn

* @return Connection

* @Description:返回连接

*/

public static Connection getConn(){

//告诉jvm使用mysql

try {

//加载驱动,string为驱动名字

Class.forName("org.postgresql.Driver");

//连接数据库,得到Connection连接

conn=DriverManager.getConnection(URL,NAME,PASS);

//System.out.println("连接数据库: "+conn);

}catch(ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}catch(SQLException e){

e.printStackTrace();

}

return conn;

}

//关闭结果对象集

public static void close(ResultSet rs){

if(rs!=null){

try{

rs.close();

}catch(SQLException e){

e.printStackTrace();

}

}

}

//关闭编译语句对象

public static void close(PreparedStatement prst){

if(prst!=null){

try{

prst.close();

}catch(SQLException e){

e.printStackTrace();

}

}

}

//关闭结果对象集

public static void close(Connection conn){

if(conn!=null){

try{

conn.close();

}catch(SQLException e){

e.printStackTrace();

}

}

}

//对于更新操作关闭资源

public static void close(PreparedStatement prst,Connection conn){

close(prst);

close(conn);

}

//关闭所有

public static void close(ResultSet rs,PreparedStatement prst,Connection conn){

close(rs);

close(prst);

close(conn);

}

}

补充:java 反射 json动态转实体类

我就废话不多说了,大家还是直接看代码吧~

package test.refect;

public class Student {

// 姓名

private String name;

// 年龄

private String age;

// 住址

private String address;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getAge() {

return age;

}

public void setAge(String age) {

this.age = age;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

@Override

public String toString() {

return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";

}

public void sayHello(Book book){

System.out.println(book.getName());

}

}

package test.refect;

public class Book {

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

package test.refect;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.net.URLDecoder;

import java.util.Iterator;

import net.sf.json.JSONObject;

public class Main {

public static void main(String[] args) throws Exception {

//Student str --> Student 主类

String str = "test.refect.Student";

Class> clazz = Class.forName(str);

//Book实体 str --> Book 参数类

String bookStr = "test.refect.Book";

Class> bookClazz = Class.forName(bookStr);

//json --> Book 将参数类转为JSONOBJECT

String bookJson ="{\"name\":\"Java\"}";

JSONObject jsonObject=JSONObject.fromObject(bookJson);

//实例化参数类

Object bookInStance = bookClazz.newInstance();

// 通过JSONOBJECT 为参数类赋值

Iterator> keys = jsonObject.keys();

while (keys.hasNext()) {

Object key = keys.next();

Object value = jsonObject.get(key);

// 替换非法字符

String _key = String.valueOf(key).replaceFirst("\\W", "");

Field field = bookClazz.getDeclaredField(_key);

field.setAccessible(true);

field.set(bookInStance, URLDecoder.decode(String.valueOf(value), "UTF-8"));

field.setAccessible(false);

}

//将参数类注入到主类

Method method = clazz.getDeclaredMethod("sayHello", bookClazz);

//执行主类

method.invoke(clazz.newInstance(), bookInStance);

}

}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持得牛网。如有错误或未考虑完全的地方,望不吝赐教。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值