We have two options for annotation processing.
- Runtime annotation processing
- Compile time annotation processing
Why use compile time annotation processing?
- Validation
- Generate resource file
- Generate source files
Looking for documentation?
The JavaDoc seems to be the only place the API is documented.
API Breakdown
How it works
Annotation processing happens in a series of rounds. Each round a processor may be asked to process
annotations from a previous round.
- If the processor has not been created a new instance is created with the no-arg constructor
- The
Processor.init(ProcessingEnvironment)
method is
invoked
- The
getSupportedAnnotationTypes()
, getSupportedOptions()
and getSupportedSourceVersion()
are invoked once per round
- The
process
method is invoke as appropriate
Implementing a simple annotation processor
- Implement the
javax.annotation.processing.Processor
interface
- This is usually done be extending
javax.annotation.processing.AbstractProcessor
- Override the
process(Set<? extends TypeElement>
annotations, RoundEnvironment roundEnv)
method.
- Create the
META-INF/services/javax.annotation.processing.Processor
file with an entry for your processor
A look at the process
method
boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv);
javax.annotation.processing.ProcessingEnvironment
The most import methods from this are:
Do's and Don'ts
- Don't throw uncaught, even runtime, exceptions
- Don't use standard logging
- Don't try to get a
Class
typed value from an annotation
- Don't capture all annotations, e.g. use
@SupportedAnnotations("*")
- Do extend the
javax.annotation.processing.AbstractProcessor
- Do include the element when printing messages, especially with errors and warnings
- Do include the list of annotations processed by your processor