注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

obsolete

wanna go

 
 
 

日志

 
 

运行时动态修改注解  

2013-06-06 17:00:37|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

  由于当前项目采用了分表策略,故一个实体会对应多个相同结构的表。只是映射的表名不一样而已~项目又使用憨包儿呢特,让我采用原生SQL总感觉不是那么爽,咋办呢?!第一念头就是如果能够动态映射就好啦,也就是现在想查table1只需将实体对应的table映射为table1即可。咋个实现动态映射呢?!也就是需要动态改变类的注解。又咋个能够动态改变类的注解呢?!本质上修改字节码,重新加载类即可,也就是所谓的字节码增强功能~  看都看不懂字节码咋个修改呢?!还是需要站在巨人的肩上才行。ASM以及JDK自带的字节码增强都不用,马上想到CGlib,javassist。。。还是痛苦的折腾了良久,为了大家不走我的弯路~ 直接上代码先~

 

Java代码  收藏代码
  1. public class ClassPoolUtils {  
  2.       
  3.       
  4.     /** 
  5.      * 动态ORM映射 
  6.      *  
  7.      * @param entityClassName   待映射的实体全限定类名 
  8.      * @param tableName         待映射的表名 
  9.      * @return                  映射后的类对象 
  10.      */  
  11.     public static Class<?> tableMapping(String entityClassName, String tableName){  
  12.         Class<?> c = null;  
  13.         try {  
  14.             ClassPool classPool = ClassPool.getDefault();  
  15.             classPool.appendClassPath(new ClassClassPath(ClassPoolUtils.class));  
  16.             classPool.importPackage("javax.persistence");  
  17.             CtClass clazz = classPool.get(entityClassName);  
  18.             ClassFile classFile = clazz.getClassFile();  
  19.              
  20.             System.out.println("增强前Entity01:" + clazz.getAnnotation(Entity.class));  
  21.             System.out.println("增强前Table02:" + clazz.getAnnotation(Table.class));  
  22.               
  23.             ConstPool constPool = classFile.getConstPool();  
  24.             Annotation tableAnnotation = new Annotation("javax.persistence.Table", constPool);  
  25.             tableAnnotation.addMemberValue("name"new StringMemberValue(tableName, constPool));  
  26.             // 获取运行时注解属性  
  27.             AnnotationsAttribute attribute = (AnnotationsAttribute)classFile.getAttribute(AnnotationsAttribute.visibleTag);  
  28.             attribute.addAnnotation(tableAnnotation);  
  29.             classFile.addAttribute(attribute);  
  30.             classFile.setVersionToJava5();  
  31.             //clazz.writeFile();  
  32.               
  33.             System.out.println("增强后Entity001:" + clazz.getAnnotation(Entity.class));  
  34.             System.out.println("增强后Table002:" + clazz.getAnnotation(Table.class));  
  35.             //TODO 当前ClassLoader中必须尚未加载该实体。(同一个ClassLoader加载同一个类只会加载一次)  
  36.             c = clazz.toClass();  
  37.             System.out.println("增强后toClass-Entity0001:" + c.getAnnotation(Entity.class));  
  38.             System.out.println("增强后toClass-Table0002:" + c.getAnnotation(Table.class));  
  39.         } catch (Exception e) {  
  40.             e.printStackTrace();  
  41.         }  
  42.           
  43.         return c;  
  44.     }  
  45.   
  46.     public static void main(String[] args) {       
  47.           ClassPoolUtils.tableMapping("com.andy.model.Order""order1");  
  48.     }  

 

   执行结果:

 

写道
增强前Entity01:@javax.persistence.Entity
增强前Table02:null
增强后Entity001:@javax.persistence.Entity
增强后Table002:@javax.persistence.Table(name="order1")
增强后toClass-Entity0001:@javax.persistence.Entity(name=)
增强后toClass-Table0002:@javax.persistence.Table(schema=, catalog=, uniqueConstraints=[], name=order1)
 
  评论这张
 
阅读(891)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018