Component Scanning
Let Spring find and register your beans automatically with @ComponentScan and the @Component family of annotations.
Introduction
Writing a @Bean method for every single class in a medium-sized application quickly becomes tedious. Component scanning solves that problem: you mark classes with an annotation, tell Spring which package to look in, and the container finds and registers them on its own.
- How Spring discovers classes on the classpath
- How to mark a class as a component
- How to enable and configure scanning with @ComponentScan
- How to include or exclude specific classes from a scan
How Component Scanning Works
At startup, Spring scans the packages you specify, looking for classes annotated with @Component (or one of the specialized annotations built on top of it, such as @Service or @Repository). For each match, it registers a bean definition automatically, using a camel-cased version of the class name as the default bean name.
Marking a Class with @Component
Any plain class can become a Spring-managed bean simply by adding @Component above the class declaration.
package com.example.app.service;
import org.springframework.stereotype.Component;
@Componentpublic class GreetingService {
public String greet(String name) { return "Hello, " + name + "!"; }}Enabling the Scan
Component scanning does not run by itself; a configuration class has to opt in with @ComponentScan and tell Spring which base package to search.
package com.example.app;
import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;
@Configuration@ComponentScan(basePackages = "com.example.app")public class AppConfig {}ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
GreetingService greetingService = context.getBean(GreetingService.class);System.out.println(greetingService.greet("PrograMinds"));Click Run to see what this code prints.
If you omit basePackages, @ComponentScan defaults to scanning the package that the configuration class itself lives in, plus every sub-package underneath it. This is why placing your main configuration class at the root package of your project is a common convention.
Controlling What Gets Scanned
You can narrow or widen what gets picked up using filters, which is useful for excluding test doubles or legacy classes from a production scan.
@Configuration@ComponentScan( basePackages = "com.example.app", excludeFilters = @ComponentScan.Filter( type = FilterType.REGEX, pattern = "com\\.example\\.app\\.legacy\\..*" ))public class AppConfig {}| Attribute | Purpose |
|---|---|
| basePackages | Which package(s) to scan, including sub-packages |
| basePackageClasses | Type-safe alternative: scan the packages containing these classes |
| includeFilters | Narrow scanning to classes matching extra criteria |
| excludeFilters | Skip classes that would otherwise be picked up |
Common Mistakes
- Placing @Component classes in a package that is outside the scanned base package, so they are silently never registered.
- Adding @ComponentScan without specifying a base package on a configuration class that lives in an unrelated package, missing the intended classes entirely.
- Defining the same bean twice: once via component scanning and again via an explicit @Bean method, causing a naming conflict.
- Forgetting that abstract classes and interfaces cannot be scanned as components; only concrete classes can.
Best Practices
- Put your main configuration or application class at the root package so the default scan naturally covers everything underneath it.
- Keep component scanning to your own application code; use @Bean methods for third-party or externally defined classes.
- Use basePackageClasses instead of string-based basePackages when you want refactor-safe, compile-checked scan targets.
- Reserve exclude filters for genuinely special cases rather than routinely hiding classes from the scan.
Frequently Asked Questions
The class name with its first letter lowercased, so GreetingService becomes greetingService. You can override it by passing a value to @Component, e.g. @Component("myGreetingService").
Usually not. @SpringBootApplication already includes @ComponentScan, scanning the package the main class lives in and everything below it.
Yes, as long as those classes are on the classpath and their package matches (or is nested inside) the scanned base package.
Key Takeaways
- @Component marks a class as eligible for automatic discovery.
- @ComponentScan tells Spring which packages to search for annotated classes.
- Without a specified basePackages, scanning defaults to the configuration class's own package and its sub-packages.
- Filters let you fine-tune exactly which classes are included or excluded.
- Spring Boot enables component scanning automatically through @SpringBootApplication.
Summary
Component scanning removes the busywork of registering every class by hand, letting the container discover your beans as long as they are annotated and sit inside a scanned package. Not every @Component is the same, though — some carry extra meaning about the role a class plays in your application. That is exactly what stereotype annotations cover next.