Here's a practical Eclipse IDE Java Annotation Processing demo using AnnotationMirror:
Project Structure:
AnnotationMirrorDemo/
├── src/
│ ├── annotations/
│ │ └── DataClass.java
│ ├── processors/
│ │ └── DataProcessor.java
│ └── demo/
│ └── User.java
├── resources/
│ └── META-INF/
│ └── services/
│ └── javax.annotation.processing.Processor
└── pom.xml (for Maven) or .classpath
Step 1: Create the Annotation
// File: src/annotations/DataClass.java
package annotations;
import java.lang.annotation.*;
@Retention(RetentionPolicy.SOURCE) // Only needed at compile time
@Target(ElementType.TYPE) // Can only be applied to classes
public @interface DataClass {
String tableName() default "";
boolean persistent() default true;
String[] tags() default {};
Class<?> repository() default Void.class;
}
Step 2: Create the Annotation Processor
// File: src/processors/DataProcessor.java
package processors;
import annotations.DataClass;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.util.*;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.Writer;
import java.util.*;
import java.util.stream.Collectors;
@SupportedAnnotationTypes("annotations.DataClass")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
public class DataProcessor extends AbstractProcessor {
private ProcessingEnvironment processingEnv;
private Elements elementUtils;
private Types typeUtils;
private Filer filer;
private Messager messager;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
this.processingEnv = processingEnv;
this.elementUtils = processingEnv.getElementUtils();
this.typeUtils = processingEnv.getTypeUtils();
this.filer = processingEnv.getFiler();
this.messager = processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.NOTE, "DataProcessor initialized for @DataClass");
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
for (Element element : annotatedElements) {
if (element.getKind() == ElementKind.CLASS) {
processDataClass((TypeElement) element);
}
}
}
return true; // Claim the annotation
}
private void processDataClass(TypeElement classElement) {
try


