beginner~2h

Core Annotations & Auto-Configuration

Four annotations do almost identical things mechanically, and picking the wrong one is a code-smell, not a bug. This module is why they're different, and how Boot decides what to wire up without you asking.

Learning objectives

  • Beginner: Use @Service, @Repository, and @RestController by their intended role consistently across a small project, even though they're all mechanically @Component.
  • Intermediate: Recognize when auto-configuration has silently provided a bean you didn't define, by checking what starters are on the classpath rather than assuming "it just works."
  • Advanced: Deliberately override one piece of Boot's auto-configuration (e.g. a custom DataSource) and understand exactly why your bean takes precedence, via @ConditionalOnMissingBean's semantics.

◆ The problem

Mechanically, @Component, @Service, @Repository, and @Controller all do the exact same thing — register the class as a bean. If that's true, why do four different annotations exist instead of one?

Each stereotype annotation is @Component underneath, but signals the class's architectural role to both human readers and Spring itself — and some carry extra behavior beyond plain registration.

AnnotationRoleExtra behavior
@ComponentGeneric, unspecified roleNone beyond bean registration.
@ServiceBusiness logic layerNone beyond bean registration — purely a semantic signal for readability.
@RepositoryData access layerEnables automatic translation of database-specific exceptions into Spring's unified DataAccessException hierarchy.
@Controller / @RestControllerWeb layerRegisters the class with the DispatcherServlet 's request mapping so its methods can handle HTTP requests (Module 06).

▲ Pitfall

Using generic @Component everywhere "because it works" throws away real information — @Repository 's exception translation specifically is easy to lose without noticing, since the code still compiles and mostly works, it just leaks raw JDBC/Hibernate exceptions instead of Spring's consistent exception types.

@ComponentScan tells the container which packages to scan for stereotype-annotated classes. Spring Boot's @SpringBootApplication defaults this to the package containing your main class and everything beneath it — which is precisely why the conventional advice is "put your main class in the root package of your application": anything outside that subtree won't be found unless you configure @ComponentScan explicitly.

// Roughly equivalent to writing all three yourself: @Configuration @EnableAutoConfiguration @ComponentScan public class DemoApplication { }
ComponentJob
@ConfigurationMarks this class as itself a source of bean definitions.
@EnableAutoConfigurationTurns on Boot's auto-configuration mechanism (§04.4).
@ComponentScanScans for stereotype-annotated beans (§04.2).

💻 Code example

// Roughly equivalent to writing all three yourself: @Configuration @EnableAutoConfiguration @ComponentScan public class DemoApplication { }

◆ Under the hood

Auto-configuration works through classes conditionally registered based on what's actually present — annotated with conditions like @ConditionalOnClass (only apply if a specific class is on the classpath) and @ConditionalOnMissingBean (only apply if you haven't already defined your own bean of that type). This is why adding spring-boot-starter-data-jpa (Module 05) alone gets you a working DataSource and EntityManager with zero manual configuration — Boot detected the JPA and JDBC driver classes on the classpath and auto-configured beans for them — but defining your own DataSource bean explicitly silently takes precedence over Boot's default, because of that @ConditionalOnMissingBean guard.

This conditional design is what makes auto-configuration additive rather than restrictive: it fills in sensible defaults only where you haven't already made a decision yourself.

✓ Quick recap

What extra behavior does @Repository add beyond plain bean registration? Automatic translation of database-specific exceptions into Spring's unified DataAccessException hierarchy. What three annotations does @SpringBootApplication combine? @Configuration, @EnableAutoConfiguration, and @ComponentScan. Why does defining your own DataSource bean override Boot's auto-configured one? Auto-configuration classes are commonly guarded by @ConditionalOnMissingBean, so they only apply when you haven't already provided your own.

Want a visual for this concept?

Generate a diagram tailored to “Core Annotations & Auto-Configuration” — the AI picks whichever visual (flowchart, comparison, sequence, etc.) best fits.

Sign in to generate a visual →

Practice quiz

Next Step

Continue to Properties, Profiles & Starters← Back to all Spring Boot chapters