Component Scanning & Stereotypes
Component Scanning & Stereotypes
In the previous lessons you registered beans explicitly — either in a @Configuration class with @Bean methods or in an XML file. That works well when you own every bean definition and want full visibility. In real applications, however, you may have dozens or hundreds of classes. Declaring each one manually quickly becomes tedious and error-prone. Component scanning is Spring's answer: you annotate your classes and let the container discover them automatically.
How Component Scanning Works
When the Spring container starts with component scanning enabled, it walks the classpath — starting from one or more base packages — looking for classes that carry specific annotations. Any class it finds is registered as a bean definition automatically, as if you had written a @Bean method for it yourself.
You enable scanning on a configuration class with @ComponentScan:
@SpringBootApplication already includes @ComponentScan rooted at the package of the annotated class. In a Boot project you rarely write @ComponentScan explicitly — but knowing what it does is essential for diagnosing scan failures.
@Component — The Base Stereotype
@Component is the root annotation. Any class annotated with it is a candidate for auto-detection. By default the bean name is the simple class name with the first letter lower-cased:
This class is now a singleton bean named emailValidator. Any other bean can declare a dependency on it, and Spring will inject the same instance everywhere.
The Stereotype Annotations — Semantic Layers
Spring ships three specialised annotations that all extend @Component:
@Service— marks a class as belonging to the business / service layer. It holds business logic, orchestrates calls to repositories, and may apply transaction boundaries.@Repository— marks a class as a data-access object (DAO). It talks to a database or external store. Spring additionally wraps it with anAOPadvisor that translates data-access exceptions into Spring's unifiedDataAccessExceptionhierarchy.@Controller— marks a class as a web MVC controller. Spring MVC's dispatcher servlet scans for these to map HTTP requests to handler methods. (For REST APIs you use@RestController, which adds@ResponseBody.)
@Repository, request mapping for @Controller), and makes package organisation immediately readable.
A Realistic Three-Layer Example
Here is a simple order-processing slice that shows all three stereotypes working together. Spring wires the dependency chain automatically.
Notice that no @Bean method exists for any of these three classes. Spring discovers them, resolves the dependency chain (OrderController → OrderService → OrderRepository), and wires everything automatically.
Controlling the Bean Name
By default the bean name is the uncapitalised simple class name (orderService, orderRepository). You can override it:
Custom names are useful when you have multiple implementations of the same interface and need to qualify injection points — something you will tackle formally in Lesson 8 on qualifiers.
Filtering What Gets Scanned
@ComponentScan accepts includeFilters and excludeFilters so you can fine-tune what the scanner picks up:
This pattern is common in multi-context applications where the root context holds services and repositories while the web context holds controllers.
@Repository and Exception Translation
One concrete, functional difference between @Repository and plain @Component is persistence exception translation. Spring applies a post-processor (PersistenceExceptionTranslationPostProcessor) to every @Repository bean. If a method throws a low-level, vendor-specific exception (e.g. a Hibernate ConstraintViolationException or a JDBC SQLException), the proxy wraps it in the appropriate Spring DataAccessException subclass. Your service layer stays decoupled from the persistence technology.
@Repository classes. Exception translation and the single-responsibility principle both demand that your DAO classes deal only with data access. Business rules belong in @Service beans.
Summary
Component scanning removes the boilerplate of explicit bean registration. Annotate your classes with the right stereotype — @Component for generic helpers, @Service for business logic, @Repository for data access, @Controller or @RestController for web endpoints — and @ComponentScan handles discovery. The semantic choice of stereotype is not cosmetic: it drives AOP, exception translation, and the readability of your architecture. In the next lesson you will boot a full ApplicationContext and interact with the beans you have just learned to declare.