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

多么神奇的动态修改注解,运行时修改很多问题就迎刃而解了!

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。