DevNotes
Support
Spring Boot · Chapter 01

How Spring Understands Annotations

What happens inside Spring when it sees an annotation — ApplicationContext, component scanning, BeanDefinitions, bean creation and dependency injection.

◷ 5 min read§ 16 sections? 7 interview questions{ } 11 code examples

#Introduction

Before learning @Component or @Autowired, you need to answer one question:

#What is an Annotation?

An annotation is metadata — information about information.

Java
@Component
public class UserService {
}

@Component does not execute any code. It simply tells Spring: "This class should become a Spring Bean."

Think of annotations as sticky notes attached to your code. The sticky note on UserService says: register me inside the Spring container.

#Who Reads These Annotations?

The Java compiler stores (runtime-retained) annotations inside the .class file:

UserService.java
UserService.class

The annotation is now part of the compiled class metadata. Spring reads that metadata while starting the application.

#Spring Startup Flow

Java
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

When this executes:

main()
SpringApplication.run()
Create ApplicationContext
Start Spring container
Scan packages
Find classes
Read annotations
Create beans
Dependency injection
Application ready
This entire sequence happens before your REST API handles the first request

#Step 1 — Spring Starts

Java
SpringApplication.run(App.class, args);

Internally, Spring creates an ApplicationContext. Think of it as a giant warehouse:

Contents
BeansConfigurationsPropertiesControllersServicesRepositories
ApplicationContext — every managed object lives inside this container

#Step 2 — Component Scan Starts

Spring now scans packages. Suppose your project is:

  • com.demo
    • DemoApplication
    • controller
      • UserController
    • service
      • UserService
    • repository
      • UserRepository

Spring recursively visits every class under the base package.

#Step 3 — Reading the Class

Suppose Spring finds:

Java
@Service
public class UserService {
}

It reads the class metadata — not the object, just metadata. Conceptually it checks:

Java
if (class.hasAnnotation(Service.class)) {
    // register it
}

With plain Java Reflection, that would look like:

Java
Class<?> clazz = UserService.class;
boolean result = clazz.isAnnotationPresent(Service.class);
Output
true

Spring now knows: this class should become a bean.

#Step 4 — BeanDefinition

Spring does not immediately create the object. Instead it creates a BeanDefinition — a blueprint.

  • BeanDefinition
    • Bean nameuserService
    • ClassUserService.class
    • Scopesingleton
    • Constructor + dependencies
    • Lazy? Primary?
BeanDefinition

No object yet — only metadata.

#Step 5 — Bean Creation

Later, Spring begins creating objects — equivalent to new UserService(), but instead of your code calling new, the container creates the object:

Spring container
new UserService()
Store object
Now the object becomes a Spring Bean

#Step 6 — Dependency Injection

Java
@Service
public class UserService {

    @Autowired
    private UserRepository repository;
}

Spring creates the UserRepository bean, then the UserService bean, and then injects repository → the UserRepository object.

How it is injected depends on how the bean is defined:

  • Field injection (as above): Spring sets the private field directly via Reflection.
  • Setter injection: Spring calls userService.setRepository(repository).
  • Constructor injection: Spring passes the repository into the constructor.

#Complete Startup Picture

main()
SpringApplication.run()
ApplicationContext
Component scan
Read class metadata
Found @Component
Create BeanDefinition
Instantiate object
Inject dependencies
Bean ready
Application ready

#What Happens If There Is No Annotation?

Java
public class UserService {
}

During scanning:

UserService
No @Component
Ignored

Spring never creates it, so this fails:

Java
@Autowired
private UserService service;
Output
NoSuchBeanDefinitionException: No qualifying bean of type 'UserService' available

…because the object doesn't exist in the Spring container.

#How Does Spring Scan Packages?

If @SpringBootApplication is in com.demo, Spring scans com.demo.* — controller, service, repository, config, security and everything below.

But not org.example or com.other, unless you explicitly configure component scanning.

#Why Do We Need a Spring Container?

Without Spring, you manually create every object:

Java
UserRepository repository = new UserRepository();
UserService service = new UserService(repository);
UserController controller = new UserController(service);

With Spring:

Java
@RestController
class UserController {

    @Autowired
    UserService service;
}

Spring creates and wires everything automatically.

#Common Interview Questions

Q1What is an annotation?

Metadata that provides instructions to the compiler, runtime or frameworks like Spring without changing the business logic.

Q2Does @Component execute code?

No. It is metadata. Spring reads it during startup and uses it to register a bean.

Q3How does Spring detect annotations?

During component scanning, Spring reads class metadata (using optimized metadata readers and reflection) and checks for known annotations such as @Component, @Service and @Repository.

Q4What is a BeanDefinition?

Metadata that describes how Spring should create and manage a bean, including its class, scope, constructor arguments, dependencies and lifecycle settings.

Q5Does Spring create beans immediately after scanning?

Not necessarily. Spring first registers bean definitions. Bean instantiation happens later during context initialization (singletons are created eagerly at the end of startup), or on first use for lazy beans.

Q6Why is @SpringBootApplication usually placed in the root package?

Because component scanning starts from the package containing the main application class and recursively scans its subpackages. Placing it at the root ensures all application components are discovered.

#Key Takeaways

  • Annotations are metadata, not executable code.
  • Spring starts by creating an ApplicationContext.
  • Component scanning discovers candidate classes.
  • Spring registers BeanDefinition objects before creating bean instances.
  • The container instantiates beans and performs dependency injection.
  • Classes without recognized stereotype annotations (or another registration mechanism) are not managed by Spring.