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

多么奇妙的动态改动注解,执行时改动非常多问题就迎刃而解了!

 

posted @ 2016-04-10 15:57  zfyouxi  阅读(1377)  评论(0编辑  收藏  举报