JAVAssist---动态改动注解
ITOOV3.0開始了,须要研究一些技术难点,先来说一个我认为比較有趣的技术点吧。需求是这种。我们须要动态的切换数据源,又因为我们是通过实体单元的注入来完毕的。实体单元是通过注解的形式注入的。这样假设我们想改动数据源那么必定就要动态的改动注解(当然可能还有其它的解决方案,可是我认为动态改动注解还是非常有趣的)所以就从动态改动注解開始吧:
先来看看我们须要改动注解的代码:
/** * EntityManager的实例化 * @author 陈丽娜 * @version 1.0.0 , 2015年3月30日 下午8:43:27 * @param <T> */ public class CollectionBase<T> extends BaseEaoImpl<T> { /** * 注入实体单元 */ @PersistenceContext(unitName="collection-entity") protected EntityManager em; /**EntityManger * 实例化 */ @Override protected EntityManager getEntityManager() { return this.em; } }
须要改动的是unitName.
那么该怎样改动呢?開始是没有不论什么思路的,但当时的我总有种感觉一定能够改动。所以就查了一下,发现了JAVAssist:开源的分析。编辑和创建java字节码的类库。
更深入的认识能够百度了解一下。以下一个小的demo来改动一下注解:
首先来看是怎样获得这个注解的:
@Test public void ReadTest() throws NotFoundException{ ClassPool pool = ClassPool.getDefault(); //获取要改动的类的全部信息 CtClass ct = pool.get("com.tgb.itoo.collection.base.CollectionBase"); //获取类中的方法 CtMethod[] cms = ct.getDeclaredMethods(); //获取第一个方法(由于仅仅有一个方法) CtMethod cm = cms[0]; System.out.println("方法名称====" + cm.getName()); //获取方法信息 MethodInfo methodInfo = cm.getMethodInfo(); //获取类里的em属性 CtField cf = ct.getField("em"); //获取属性信息 FieldInfo fieldInfo = cf.getFieldInfo(); System.out.println("属性名称===" + cf.getName()); //获取注解属性 AnnotationsAttribute attribute = (AnnotationsAttribute) fieldInfo.getAttribute(AnnotationsAttribute.visibleTag); System.out.println(attribute); //获取注解 Annotation annotation = attribute.getAnnotation("javax.persistence.PersistenceContext"); System.out.println(annotation); //获取注解的值 String text =((StringMemberValue) annotation.getMemberValue("unitName")).getValue() ; System.out.println("注解名称===" + text); }
执行结果:
方法名称====getEntityManager 属性名称===em @javax.persistence.PersistenceContext(unitName="collection-entity") @javax.persistence.PersistenceContext(unitName="collection-entity") 注解名称===collection-entity
改动注解的方法与获取的一样,仅仅是须要为获取的注解赋值,代码例如以下:
@Test public void UpdateTest() throws NotFoundException{ ClassPool pool = ClassPool.getDefault(); //获取须要改动的类 CtClass ct = pool.get("com.tgb.itoo.collection.base.CollectionBase"); //获取类里的全部方法 CtMethod[] cms = ct.getDeclaredMethods(); CtMethod cm = cms[0]; System.out.println("方法名称====" + cm.getName()); MethodInfo minInfo = cm.getMethodInfo(); //获取类里的em属性 CtField cf = ct.getField("em"); FieldInfo fieldInfo = cf.getFieldInfo(); System.out.println("属性名称===" + cf.getName()); ConstPool cp = fieldInfo.getConstPool(); //获取注解信息 AnnotationsAttribute attribute2 = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag); Annotation annotation = new Annotation("javax.persistence.PersistenceContext", cp); //改动名称为unitName的注解 annotation.addMemberValue("unitName", new StringMemberValue("basic-entity", cp)); attribute2.setAnnotation(annotation); minInfo.addAttribute(attribute2); //打印改动后方法 Annotation annotation2 = attribute2.getAnnotation("javax.persistence.PersistenceContext"); String text = ((StringMemberValue)annotation2.getMemberValue("unitName")).getValue(); System.out.println("改动后的注解名称===" + text); }
执行结果:
方法名称====getEntityManager 属性名称===em 改动后的注解名称===basic-entity
多么奇妙的动态改动注解,执行时改动非常多问题就迎刃而解了!