Annotation Processing
TL;DR
- Annotation Processing refers to scanning and acting upon annotations.
- There are two ways to process annotations: Runtime Processing (using Reflection, like Spring Boot) and Compile-Time Processing (using the Pluggable Annotation Processing API, like Lombok).
- Compile-time processing is much faster and can generate new source code before the final compilation finishes.
Concept
Most developers only ever use Runtime Annotation Processing via Reflection (e.g., checking method.isAnnotationPresent()). This is easy but slows down application startup time.
Compile-Time Annotation Processing (JSR 269) hooks directly into the javac compiler.
When you compile your code, javac checks if any Annotation Processors are registered. If so, it passes the source code syntax tree to the processor. The processor reads your annotations (like @Getter) and can generate entirely new .java files on the fly. javac then compiles those generated files alongside your original code.
This is exactly how Lombok, MapStruct, and Dagger work. They process annotations at compile-time to generate boilerplate code, resulting in zero performance penalty at runtime.
Examples
// Example of what an Annotation Processor does conceptually.
// 1. You write this code:
@Entity
public class User {
private String name;
}
// 2. The Compile-Time Processor (e.g., Hibernate Metamodel Generator)
// reads the @Entity annotation during compilation.
// 3. The Processor GENERATES a brand new file (User_.java):
@StaticMetamodel(User.class)
public abstract class User_ {
public static volatile SingularAttribute<User, String> name;
}
// 4. The compiler compiles both User.java and the newly generated User_.java.
Interview Questions
Q: Can a Compile-Time Annotation Processor modify existing code?
A: Strictly speaking, No. The official Pluggable Annotation Processing API is designed only to generate new files (new .java files, .xml files, etc.). It is explicitly forbidden from modifying existing source code (e.g., it cannot magically inject a getName() method directly into the User.class file).
Q: If it can’t modify code, how does Project Lombok work?
A: Lombok is a famous “hack”. It uses internal, undocumented, and unsupported APIs inside the javac and Eclipse compilers to forcefully modify the Abstract Syntax Tree (AST) directly during compilation. It rewrites your actual class definition before it is turned into bytecode. This is why Lombok often breaks when a new major version of Java is released—it relies on internal compiler internals rather than the official Annotation Processing API.