JAVAssist --- modify annotation dynamically, javassist --- Annotation
ITOOV3.0 has started, and some technical difficulties need to be studied. Let's talk about a technical point that I think is interesting. The requirement is as follows. We need to switch data sources dynamically, because we are done through entity unit injection, entity units are injected through annotations, in this way, if we want to modify the data source, we must modify the annotation dynamically (of course, there may be other solutions, but I think it is interesting to modify the annotation dynamically) so let's start with modifying the annotation dynamically: Let's take a look at the code for modifying the annotation:
/*** EntityManager instantiation * @ author Chen Lina * @ version 1.0.0, march 30, 2015 8:43:27 * @ param <T> */public class CollectionBase <T> extends BaseEaoImpl <T> {/*** inject entity Unit */@ PersistenceContext (unitName = "collection- entity ") protected EntityManager em;/** EntityManger * instantiate */@ Override protected EntityManager getEntityManager () {return this. em ;}}
UnitName must be modified.
So how can we modify it? There was no idea at first, but at that time I always felt that it could be modified. So I checked it and found the JAVAssist: open-source analysis. Edit and create a java bytecode class library. For more information, see Baidu. The following is a small demo to modify the annotation:
First, let's look at how to get this annotation:
@ Testpublic void ReadTest () throws NotFoundException {ClassPool pool = ClassPool. getDefault (); // obtain all information about the class to be modified. CtClass ct = pool. get ("com. tgb. itoo. collection. base. collectionBase "); // obtain the CtMethod [] cms = ct in the class. getDeclaredMethods (); // obtain the first method (because there is only one method) CtMethod cm = cms [0]; System. out. println ("method name =" + cm. getName (); // obtain method information MethodInfo methodInfo = cm. getMethodInfo (); // obtain the em attribute CtField cf = ct in the class. getField ("em"); // obtain the attribute information FieldInfo fieldInfo = cf. getFieldInfo (); System. out. println ("attribute name =" + cf. getName (); // obtain the annotation attribute AnnotationsAttribute attribute = (AnnotationsAttribute) fieldInfo. getAttribute (AnnotationsAttribute. visibleTag); System. out. println (attribute); // obtain the Annotation annotation Annotation = attribute. getAnnotation ("javax. persistence. persistenceContext "); System. out. println (annotation); // obtain the annotation value String text = (StringMemberValue) annotation. getMemberValue ("unitName ")). getValue (); System. out. println ("annotation name =" + text );}
Running result:
Method Name === getEntityManager property name === em@javax.persistence.PersistenceContext (unitName = "collection-entity") @ javax. persistence. persistenceContext (unitName = "collection-entity") annotation name = collection-entity
The method for modifying the annotation is the same as that for obtaining it. You only need to assign values to the obtained annotation. The Code is as follows:
@ Testpublic void UpdateTest () throws NotFoundException {ClassPool pool = ClassPool. getDefault (); // obtain the class CtClass ct = pool to be modified. get ("com. tgb. itoo. collection. base. collectionBase "); // obtain all methods in the class. CtMethod [] cms = ct. getDeclaredMethods (); CtMethod cm = cms [0]; System. out. println ("method name =" + cm. getName (); MethodInfo minInfo = cm. getMethodInfo (); // obtain the em attribute CtField cf = ct in the class. getField ("em"); FieldInfo fieldInfo = cf. getFieldInfo (); System. out. println ("attribute name =" + cf. getName (); ConstPool cp = fieldInfo. getConstPool (); // obtain the annotation information AnnotationsAttribute attribute2 = new AnnotationsAttribute (cp, annotationsattri. visibleTag); Annotation annotation = new Annotation ("javax. persistence. persistenceContext ", cp); // modify annotation of the annotation named unitName. addMemberValue ("unitName", new StringMemberValue ("basic-entity", cp); attribute2.setAnnotation (annotation); minInfo. addattriation (attribute2); // print the modified Annotation annotation2 = attribute2.getAnnotation ("javax. persistence. persistenceContext "); String text = (StringMemberValue) annotation2.getMemberValue (" unitName ")). getValue (); System. out. println ("modified annotation name =" + text );}
Running result:
Method Name === getEntityManager attribute name === em modified annotation name === basic-entity
What a magical dynamic modification annotation can solve many problems during runtime modification!