How Reflection and Annotations Power Spring Boot - Deep Dive into Java's Runtime Magic

A deep dive into how Java uses Reflection and Annotations to power modern frameworks like Spring Boot.
When we write Java code, most of the time everything happens at compile time - classes, objects, and method calls are clearly defined.
But have you ever wondered:
How does Spring create objects automatically?
How does @Autowired work?
How does Hibernate map objects to database tables?
How do frameworks read annotations?
The answer lies in Reflection and Annotations in Java.
In this article, I'll explain:
what Reflection is
what annotations are
How they work internally
How they work together
Real-world framework usage
What is Reflection in Java?
Reflection in Java is an API that allows a program to:
Inspect classes at runtime
Access methods and fields (even private ones)
Create objects dynamically
Invoke methods dynamically
Modify internal state of objects
It is available in:
java.lang.reflect //package
Why Reflection is important?
Normally in Java:
Student s = new Student();
s.display();
Everything is known at compile time. But using reflection, we can:
Load class dynamically
Create object without using new
Call methods without knowing their names at compile time
This is heavily used in:
Spring framework
Hibernate ORM
JUnit
Dependency Injection containers
How to Get Class Object in Java
Reflection starts with the Class class. There are three ways:
Class c1 = Class.forName("com.example.Student");
Class c2 = Student.class;
Class c3 = obj.getClass();
Class.forName()
Loads class into JVM
Throws ClassNotFoundException
Commonly used in JDBC drivers
Creating Objects Using Reflection
Class<T> c = class.forName("Student");
Object obj = c.getDeclaredConstructor().newInstance();
This allows dynamic object creation.
Accessing Private Fields
Field field = c.getDeclaredField("name");
field.setAccessible(true);
field.set(obj, "Nandini");
Reflection can break encapsulation using setAccessible(true).
Invoking Methods Dynamically
Method method = c.getDeclaredMethod("display");
method.setAccessible(true);
method.invoke(obj);
This enables runtime behavior modification.
Disadvantages of Reflection
Slower than direct calls
Breaks encapsulation
Security risks
Harder debugging
Therefore, it should be used carefully.
What are Annotations in Java?
Annotations in Java provide metadata about:
Classes
Methods
Fields
Parameters
They do not change business logic directly but provide extra information to:
Compiler
JVM
Frameworks
Example:
@Override // annotation
Built-in Java Annotations
Some commonly used annotations:
//annotations
@Override
@Deprecated
@SuppressWarnings
@FunctionalInterface
Creating Custom Annotation in Java
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation{
String value();
}
Important Meta-Annotations
@Retention
Defines lifecycle of annotation:
SOURCE
CLASS
RUNTIME
To access annotation using reflection -> use RUNTIME.
@Target
Defines where annotation can be applied:
TYPE
METHOD
FIELD
PARAMETER
CONSTRUCTOR
@Inherited
Allows child class to inherit annotation.
@Documented
Includes annotation in Javadoc.
How Reflection and Annotations Work Together
This is the most important concept.
Annotations provide metadata. Reflection reads that metadata at runtime.
Example:
Class<T> c = Demo.class;
if(c.isAnnotationPresent(MyAnnotation.class)){
MyAnnotation annotation = c.getAnnotation(MyAnnotation.class);
System.out.println(annotation.value());
}
Flow:
JVM loads class.
Annotation metadata is stored.
If retention policy is RUNTIME -> it says available.
Reflection reads it.
Program behavior changes dynamically.
How Spring Boot Uses Reflection and Annotations
Spring uses:
. @Component
. @Service
. @Repository
. @Autowired
. @RestController
Spring:
Scans classpath
Detects annotations
Uses reflection
Create objects
Injects dependencies
Without reflection + annotations -> Spring Framework cannot function.
Internal JVM Understanding
When class is compiled:
Annotation metadata is stored in bytecode.
JVM Keeps it based on retention policy.
Reflection API reads metadata.
Frameworks act accordingly.
This is how:
Dependency Injection works
ORM mapping works
REST APIs are built
AOP Works.
Conclusion
Reflection and Annotations are two of the most powerful features in Java.
Reflection gives Java runtime inspection and dynamic execution capability.
Annotations provide structured metadata to guide behavior. Together they power:
Spring Boot
Hibernate
Testing frameworks
Dependency Injection Containers
Mastering these concepts moves a developer from:
Writing Java code -> Understanding how Java frameworks actually work internally.






