zoukankan      html  css  js  c++  java
  • 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

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

     

  • 相关阅读:
    好玩/感人的小事
    本周最新文献速递20200207
    (史上最全)SNP位点与转录因子结合特异性数据库:GVATdb
    本周最新文献速递20210131
    【Python高级编程029 ● http协议 ● URL】
    【Python高级编程028 ● http协议 ● http协议介绍】
    【Python高级编程027 ● 网络编程 ● socket之send和recv原理剖析】
    【Python高级编程026 ● 网络编程 ● 多任务版TCP服务端程序开发】
    【Python高级编程025 ● 网络编程 ● 开发TCP网络程序注意点】
    【Python高级编程024 ● 网络编程 ● TCP服务端程序开发】
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5374339.html
Copyright © 2011-2022 走看看