java 注解修改代码,JAVAssist---动态修改注解

本文探讨了一种有趣的技术点——动态修改Java注解,以解决需要在运行时动态切换数据源的问题。通过使用JAVAssist库,实现了对`@PersistenceContext`注解中`unitName`的动态修改,从而实现数据源的动态切换,简化了代码维护和问题解决。
摘要由CSDN通过智能技术生成

标签:?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

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

标签:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值