Follow below steps to add annotation to a run time method.
Step 1: Define annotation.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Logger {
String value();
}
Step 2: Get an instance of ClassPool
ClassPool classPool = ClassPool.getDefault();
Step 3: Create a class and get ClassFile and ConstPool references
CtClass ctClass = classPool.makeClass("com.sample.App.Test");
ClassFile classFile = ctClass.getClassFile();
ConstPool constPool = classFile.getConstPool();
Step 4: Create AnnotationsAttribute
AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constPool,AnnotationsAttribute.visibleTag);
Annotation annotation = new Annotation("com.sample.app.annotations.Logger", constPool);
annotation.addMemberValue("value", new StringMemberValue("ERROR", constPool));
annotationsAttribute.addAnnotation(annotation);
Step 5: Create new Method object.
CtMethod ctMethod = CtNewMethod.make(Modifier.PUBLIC, CtClass.doubleType, "getPI", null, null, "return 3.14;", ctClass);
Step 6: Add annotation to the method.
ctMethod.getMethodInfo().addAttribute(annotationsAttribute);
Step 7: Add method to the class.
ctClass.addMethod(ctMethod);
Find the below working application.
package com.sample.app.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Logger {
String value();
}
App.java
package com.sample.app;
import java.lang.reflect.Modifier;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.StringMemberValue;
public class App {
public static void main(String args[]) throws Exception {
ClassPool classPool = ClassPool.getDefault();
// create a class and get ClassFile and ConstPool references
CtClass ctClass = classPool.makeClass("com.sample.App.Test");
ClassFile classFile = ctClass.getClassFile();
ConstPool constPool = classFile.getConstPool();
// create the annotation
AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constPool,
AnnotationsAttribute.visibleTag);
Annotation annotation = new Annotation("com.sample.app.annotations.Logger", constPool);
annotation.addMemberValue("value", new StringMemberValue("ERROR", constPool));
annotationsAttribute.addAnnotation(annotation);
CtMethod ctMethod = CtNewMethod.make(Modifier.PUBLIC, CtClass.doubleType, "getPI", null, null, "return 3.14;",
ctClass);
// Add annotation to the method.
ctMethod.getMethodInfo().addAttribute(annotationsAttribute);
// Add method to the class
ctClass.addMethod(ctMethod);
// Add annotation to the class.
// classFile.addAttribute(annotationsAttribute);
ctClass.writeFile("/Users/Shared/javassist");
}
}
Run App.java.
When you go to the directory /Users/Shared/javassist, you can see that Test.class file is created.
$tree /Users/Shared/javassist/
/Users/Shared/javassist/
└── com
└── sample
└── App
└── Test.class
3 directories, 1 file
Open Test.class file in java de-compiler to see the source code.
From the source code, you can confirm Logger annotation is added to getPI method.
No comments:
Post a Comment