如何在SpringMVC框架中利用Java反射机制和Javassist实现Java对象、属性、注解的动态创建生成
2016-12-23 13:25
1106 查看
简单介绍Java的反射原理
Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。Java程序要能够运行,java虚拟机需要事先加载java类,目前我们的程序在编译期就已经确定哪些java类需要被加载。
Java的反射机制是在编译时并不确定哪个类需要被加载,而是在程序运行时才加载、探知、自审。这样的特点就是反射。
何为自审:通过Java的反射机制能够探知到java类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。
Java的反射原理最典型的应用就是各种Java IDE:比如Jcreator,eclipse,idea等,当我们构建出一个对象时,去调用该对象的方法和属性的时候。一按点,IDE工具就会自动的把该对象能够使用的所有的方法和属性全部都列出来,供我们进行选择。这就是利用了Java反射的原理,是对我们创建对象的探知、自审的过程。
直接上代码。
主方法类
工具类:
一
二
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 读取配置文件
*
* @author
*
*/
}
Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。Java程序要能够运行,java虚拟机需要事先加载java类,目前我们的程序在编译期就已经确定哪些java类需要被加载。
Java的反射机制是在编译时并不确定哪个类需要被加载,而是在程序运行时才加载、探知、自审。这样的特点就是反射。
何为自审:通过Java的反射机制能够探知到java类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。
Java的反射原理最典型的应用就是各种Java IDE:比如Jcreator,eclipse,idea等,当我们构建出一个对象时,去调用该对象的方法和属性的时候。一按点,IDE工具就会自动的把该对象能够使用的所有的方法和属性全部都列出来,供我们进行选择。这就是利用了Java反射的原理,是对我们创建对象的探知、自审的过程。
直接上代码。
主方法类
import java.io.FileWriter; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.Statement; import java.util.Date; import com.soa.mdm.exception.CustomException; import com.soa.mdm.util.DateUtil; import com.soa.mdm.util.DbUtil; import com.soa.mdm.util.GetEntityPathUtil; import com.soa.mdm.util.PropertiesUtil; import com.soa.mdm.util.StringUtil; import com.soa.mdm.util.tableNameUtil; /** * 如何在SpringMVC框架中利用Java反射机制和Javassist实现Java对象、属性、注解的动态创建生成 * * @author Mr.z * @createTime 2016年12月23日-下午3:54:47 * @version 1.0.0 */ public class DynamicCreateObjectFromDatabase { private String packageOutPath = "com.soa.mdm.entity";// 指定实体生成所在包的路径 private String[] colNames; // 列名数组 private String[] colTypes; // 列名类型数组 private int[] colSizes; // 列名大小数组 private boolean isImportUtil = false; // 是否需要导入包java.util.* private boolean isImportSql = false; // 是否需要导入包java.sql.* private String tableName = ""; // 数据库表名称 private String entityTableName = ""; // 实体表名称 private String primaryKeyName = ""; // 表主键 private String authorName = "Mr.Z"; public static void main(String[] args) throws Exception { DynamicCreateObjectFromDatabase dcofd = new DynamicCreateObjectFromDatabase(); dcofd.GenEntityOracle("code_rules");//code_rules为数据库中的表名 } /** * 生成oracle表实体 * * @author Mr.Z * @throws Exception * @Time 2016年12月22日 下午3:57:30 */ public void GenEntityOracle(String tablename) throws Exception { this.tableName = tablename; entityTableName = tableNameUtil.initTableName(tablename); String schema = tableNameUtil.upperCaseTableName(PropertiesUtil.getValue("jdbc.username")); Connection con = null; String sql = "select * from " + tablename; con = DbUtil.getCon(); DatabaseMetaData databaseMetaData = con.getMetaData(); ResultSet rsPriKeys = databaseMetaData.getPrimaryKeys(null, schema, tableNameUtil.upperCaseTableName(tablename)); if (rsPriKeys.getFetchSize() < 1) { throw new CustomException("表或视图不存在!"); } if (rsPriKeys.next()) { if (StringUtil.isEmpty(rsPriKeys.getString(4))) { throw new CustomException("表主键不能为空!"); } primaryKeyName = rsPriKeys.getString(4); } Statement pstmt = con.createStatement(); ResultSet rs = pstmt.executeQuery(sql); ResultSetMetaData rsmd = rs.getMetaData(); int size = rsmd.getColumnCount(); System.out.println(size); colNames = new String[size]; colTypes = new String[size]; colSizes = new int[size]; for (int i = 0; i < size; i++) { colNames[i] = rsmd.getColumnName(i + 1); // 获取列命 colTypes[i] = rsmd.getColumnTypeName(i + 1); // 获取列类型 if (colTypes[i].equalsIgnoreCase("date") || colTypes[i].equalsIgnoreCase("timestamp")) { isImportUtil = true; } if (colTypes[i].equalsIgnoreCase("blob") || colTypes[i].equalsIgnoreCase("char")) { isImportSql = true; } colSizes[i] = rsmd.getColumnDisplaySize(i + 1); } String content = parse(colNames, colTypes, colSizes); // File directory = new File(""); // System.out.println("绝对路径:"+directory.getAbsolutePath()); // System.out.println("相对路径:"+directory.getCanonicalPath()); String outputPath = GetEntityPathUtil.getEntityPath(entityTableName); /* * outputPath = * "E:\\workspace\\Mdm\\src\\main\\java\\com\\soa\\mdm\\entity\\" + initcap(tablename) + " * .java"; */ FileWriter fw = new FileWriter(outputPath); PrintWriter pw = new PrintWriter(fw); pw.println(content); pw.flush(); pw.close(); DbUtil.closeCon(con); } /** * 功能:生成实体类主体代码 * * @param colNames * 列名数组 * @param colTypes * 列名类型数组 * @param colSizes * 列名大小数组 * @return */ private String parse(String[] colNames, String[] colTypes, int[] colSizes) { StringBuffer sb = new StringBuffer(); sb.append("package " + this.packageOutPath + ";\r\n\r\n"); // 判断是否导入工具包 if (isImportUtil) { sb.append("import java.util.Date;\r\n\r\n"); } if (isImportSql) { sb.append("import java.sql.*;\r\n\r\n"); } sb.append("import javax.persistence.Entity;\r\n"); sb.append("import javax.persistence.GeneratedValue;\r\n"); sb.append("import javax.persistence.Id;\r\n"); sb.append("import javax.persistence.Table;\r\n\r\n"); sb.append("import org.hibernate.annotations.GenericGenerator;\r\n"); sb.append("\r\n"); // 注释部分 sb.append("/**\r\n"); sb.append("* @author cc\r\n"); sb.append("* " + entityTableName + " 实体类\r\n"); sb.append("* @version 1.0.0\r\n"); sb.append("* @date" + DateUtil.formatDate(new Date(), "yyyy年MM月dd日") + " " + this.authorName + "\r\n"); sb.append("* @company china-sa\r\n"); sb.append("*/ \r\n"); // Hibernate注解部分 sb.append("@Entity\r\n"); sb.append("@Table(name = \"" + tableName + "\")\r\n"); // 实体部分 sb.append("public class " + tableNameUtil.initTableName(entityTableName) + "{\r\n\r\n"); processAllAttrs(sb);// 属性 sb.append("\r\n"); processAllMethod(sb);// get set方法 sb.append("}\r\n\r\n"); return sb.toString(); } /* * 功能:生成所有属性 * * @param sb */ private void processAllAttrs(StringBuffer sb) { for (int i = 0; i < colNames.length; i++) { sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + colNames[i] + ";\r\n"); } } /** * 功能:生成所有方法 * * @param sb */ private void processAllMethod(StringBuffer sb) { for (int i = 0; i < colNames.length; i++) { if (primaryKeyName.equals(colNames[i])) { sb.append("\t@Id\r\n\t"); sb.append("@GeneratedValue(generator = \"system-uuid\")\r\n\t"); sb.append("@GenericGenerator(name = \"system-uuid\", strategy = \"uuid\")\r\n"); } sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + tableNameUtil.initTableName(colNames[i]) + "(){\r\n"); sb.append("\t\treturn " + colNames[i] + ";\r\n"); sb.append("\t}\r\n\r\n"); sb.append("\tpublic void set" + tableNameUtil.initTableName(colNames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " " + colNames[i] + "){\r\n"); sb.append("\t\t this." + colNames[i] + "=" + colNames[i] + ";\r\n"); sb.append("\t}\r\n\r\n"); } } /** * 功能:获得列的数据类型 * * @param sqlType * @return */ private String sqlType2JavaType(String sqlType) { if (sqlType.equalsIgnoreCase("binary_double")) { return "double"; } else if (sqlType.equalsIgnoreCase("binary_float")) { return "float"; } else if (sqlType.equalsIgnoreCase("blob")) { return "byte[]"; } else if (sqlType.equalsIgnoreCase("blob")) { return "byte[]"; } else if (sqlType.equalsIgnoreCase("char") || sqlType.equalsIgnoreCase("nvarchar2") || sqlType.equalsIgnoreCase("varchar2")) { return "String"; } else if (sqlType.equalsIgnoreCase("date") || sqlType.equalsIgnoreCase("timestamp") || sqlType.equalsIgnoreCase("timestamp with local time zone") || sqlType.equalsIgnoreCase("timestamp with time zone")) { return "Date"; } else if (sqlType.equalsIgnoreCase("number")) { return "Integer"; } return "String"; } }
工具类:
一
import java.io.File; /** * 获取路径 * * @author cc * @createTime 2016年12月22日-下午4:48:06 * @version 1.0.0 */ public class GetEntityPathUtil { public static String getEntityPath(String tableName) throws Exception { File directory = new File(""); String packageOutPath = "com\\soa\\mdm\\entity";// 指定实体生成所在包的路径 System.out.println("绝对路径:" + directory.getAbsolutePath()); /* System.out.println("相对路径:" + directory.getCanonicalPath()); */ String outputPath = directory.getAbsolutePath() + "\\src\\main\\java\\" + packageOutPath + "\\" + tableName + ".java"; return outputPath; }
二
public class tableNameUtil { public static void main(String[] args) { // 将表名去掉下划线转化为峰驼式 String tableName = tableNameUtil.initTableName("code_rules"); System.out.println(tableName); // 将表名全部转化为大写 String upperCasetableName = tableNameUtil.upperCaseTableName("code_rules"); } /** * 功能:将表名转化为实体名称,以下划线分割 如:code_rules => CodeRules * * @param str * @return */ public static String initTableName(String str) { StringBuffer resultStr = new StringBuffer(); String[] strArr = str.split("_"); for (String s : strArr) { char[] ch = s.toCharArray(); if (ch[0] >= 'a' && ch[0] <= 'z') { ch[0] = (char) (ch[0] - 32); } resultStr.append(new String(ch)); } return resultStr.toString(); } /** * 功能:将表名转化大写 如:code_rules => CODE_RULES * * @param str * @return */ public static String upperCaseTableName(String str) { char[] ch = str.toCharArray(); StringBuilder sb = new StringBuilder(); for (char c : ch) { if (c >= 'a' && c <= 'z') { c = (char) (c - 32); } sb.append(c); } return sb.toString(); } }
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 读取配置文件
*
* @author
*
*/
public class PropertiesUtil { public static void main(String[] args) { System.out.println(PropertiesUtil.getValue("jdbc.password")); } /** * 读取配置文件 * * @param key * @return value */ public static String getValue(String key) { Properties prop = new Properties(); InputStream in = new PropertiesUtil().getClass().getResourceAsStream("/jdbc.properties"); try { prop.load(in); } catch (IOException e) { e.printStackTrace(); } return prop.getProperty(key); }
}
部分工具包没贴出来,比如日期转字符串、JDBC连接数据库等 **效果图:** ![此图为生成的注释、注解等信息](https://img-blog.csdn.net/20161223133528465?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjc5NTQ5NDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) ![此图为生成的注释、注解等信息](https://img-blog.csdn.net/20161223133542356?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjc5NTQ5NDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
相关文章推荐
- 利用Java反射机制和Javassist实现Java对象及其属性的动态创建生成
- 利用Java反射机制和Javassist实现Java对象及其属性的动态创建生成
- 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】
- 如何利用java的反射机制动态的取得对象的属性?
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- 自己在项目中的学习总结:利用工厂模式+反射机制+缓存机制,实现动态创建不同的数据层对象接口
- Java利用反射实现对象之间相同属性复制
- 字节码操作_javassist库_动态创建新类_属性_方法_构造器_API详解JAVA216-217
- 利用Apache的commons-beanutils和commons-collections包实现Java对象的按属性排序
- java动态代理对象实现日志的拦截(annotation自定义注解方式)
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- Java—java中如何实现动态数组的创建与赋值
- JAVA动态模块的设计实现以及如何通过newInstance()来创建带参的构造类实例
- 如何开发一个java开源框架-----Jvn框架之实现自动生成在线文档(第七讲)
- Java中如何实现一个类在内存里只能创建一个实例对象
- [Java]利用反射机制动态加载并创建包含参数的对象
- 教你如何利用POI和JFreeChart框架实现生成Excel文件(生成 统计图)
- Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解
- 如何开发一个java开源框架-----Jvn框架之实现用注解代替配置文件
- SpringMVC中使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换(下)