Runtime Annotation Processing
Read annotations at runtime using reflection to implement validation, routing, or injection logic.
Runtime Annotation Processing is a free Java Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Reading Class-Level Annotations
Retrieve annotations on a class using Class.getAnnotation() (single) or getAnnotations() (all). Returns null if the annotation is absent.
@Service
@RequestMapping("/api")
public class UserController {}
RequestMapping rm = UserController.class.getAnnotation(RequestMapping.class);
if (rm != null) System.out.println(Arrays.toString(rm.value())); // ["/api"]Reading Method Annotations
Get method annotations via method.getAnnotation(). Iterate getDeclaredMethods() to scan all methods in a class.
for (Method m : UserController.class.getDeclaredMethods()) {
GetMapping gm = m.getAnnotation(GetMapping.class);
if (gm != null) System.out.println(m.getName() + " -> " + Arrays.toString(gm.value()));
}Reading Field Annotations
Field annotations are used by validation and ORM frameworks. Iterate getDeclaredFields() and check for each relevant annotation.
for (Field f : User.class.getDeclaredFields()) {
Column col = f.getAnnotation(Column.class);
if (col != null) System.out.println(f.getName() + " -> column: " + col.name());
}Reading Parameter Annotations
Parameter annotations are available via method.getParameterAnnotations() — a 2D array (one row per parameter, one entry per annotation).
Method m = UserController.class.getDeclaredMethod("create", UserDto.class);
Annotation[][] pa = m.getParameterAnnotations();
for (Annotation a : pa[0]) System.out.println(a.annotationType().getSimpleName()); // e.g. ValidisAnnotationPresent
Use isAnnotationPresent(AnnotationType.class) as a quick null-safe check before reading the annotation value.
if (m.isAnnotationPresent(Transactional.class)) {
beginTransaction();
m.invoke(target, args);
commitTransaction();
}Building a Simple Dependency Injection Container
Scan a package for classes annotated with @Component, instantiate them via reflection, and store them in a map — a simplified Spring container.
Map<Class<?>, Object> beans = new HashMap<>();
for (Class<?> cls : scanPackage("com.example")) {
if (cls.isAnnotationPresent(Component.class)) {
beans.put(cls, cls.getDeclaredConstructor().newInstance());
}
}Injecting Fields Annotated with @Inject
After constructing beans, scan for @Inject-annotated fields and set them using reflection — mimicking field injection.
for (Object bean : beans.values()) {
for (Field f : bean.getClass().getDeclaredFields()) {
if (f.isAnnotationPresent(Inject.class)) {
f.setAccessible(true);
f.set(bean, beans.get(f.getType()));
}
}
}Runtime Validation with Annotation Values
Read constraint annotation values (like @Range(min=1, max=100)) and validate the field value against them at runtime.
for (Field f : dto.getClass().getDeclaredFields()) {
Range range = f.getAnnotation(Range.class);
if (range != null) {
f.setAccessible(true);
int val = (int) f.get(dto);
if (val < range.min() || val > range.max())
throw new ValidationException(f.getName() + " out of range");
}
}Reading Repeatable Annotations
For @Repeatable annotations, use getAnnotationsByType() to retrieve all instances from the container annotation transparently.
Tag[] tags = MyClass.class.getAnnotationsByType(Tag.class);
for (Tag t : tags) System.out.println(t.value());Scanning a Package with ClassPath Libraries
Standard Java reflection cannot list all classes in a package. Use libraries like Reflections, ClassGraph, or Spring's ClassPathScanningCandidateComponentProvider to scan classpath entries.
Reflections reflections = new Reflections("com.example.service");
Set<Class<?>> services = reflections.getTypesAnnotatedWith(Service.class);
services.forEach(System.out::println);Annotation Processing at Runtime: Summary
Runtime annotation processing powers dependency injection, validation, routing, and ORM. It is initialization-time work — process annotations once at startup, cache the results, and avoid reflection in per-request paths.
Quick Check
Which method retrieves all instances of a @Repeatable annotation?
Recap
Use getAnnotation/isAnnotationPresent for single annotations. Scan methods and fields with getDeclared*. Use getAnnotationsByType for repeatable annotations. Process at startup, cache results.
Frequently asked questions
Is the “Runtime Annotation Processing” lesson free?
Yes — the full text of “Runtime Annotation Processing” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “Runtime Annotation Processing”?
Read annotations at runtime using reflection to implement validation, routing, or injection logic. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Runtime Annotation Processing” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Defining Annotations: Elements and Defaults
- Retention Policies and Target Types
- Runtime Annotation Processing
- Compile-Time Annotation Processors