标签:?ITOOV3.0开始了,需要研究一些技术难点,先来说一个我觉得比较有趣的技术点吧,需求是这样的,我们需要动态的切换数据源,又由于我们是通过实体单元的注入来完成的,实体单元是通过注解的形式注入的,这样如果我们想修改数据源那么必然就要动态的修改注解(当然可能还有其他的解决方式,但是我觉得动态修改注解还是很有趣的)所以就从动态修改注解开始吧:
先来看看我们需要修改注解的代码:
/**
* EntityManager的实例化
* @author 陈丽娜
* @version 1.0.0 , 2015年3月30日 下午8:43:27
* @param
*/
public class CollectionBase extends BaseEaoImpl {
/**
* 注入实体单元
*/
@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
多么神奇的动态修改注解,运行时修改很多问题就迎刃而解了!
标签: