Component Scanning
How Does Spring Find Components?
Spring Boot automatically scans the package and sub-packages under the class annotated with @SpringBootApplication. This is called component scanning.
@SpringBootApplication // Scanning starts from this package
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
// Spring scans: com.example.demo and all sub-packages
That's why the main class must be placed in the root package (for example com.example.demo), not in a sub-package.
Stereotype Annotations
Spring provides several annotations to mark a class as a component:
| Annotation | Purpose | Common Package |
|---|---|---|
@Component |
Generic Spring component | config/, util/ |
@Service |
Business logic layer | service/ |
@Repository |
Data access layer | repository/ |
@Controller |
Web controller (MVC) | controller/ |
@RestController |
REST API controller | controller/ |
@Configuration |
Configuration class | config/ |
Technically, @Service, @Repository, and @Controller are stereotypes of @Component. The only difference is in semantics.
Usage Example
// controller/UserController.java
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping
public List<User> getAll() {
return userService.findAll();
}
}
// service/UserService.java
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> findAll() {
return userRepository.findAll();
}
}
// repository/UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
Base Package Scanning
By default, scanning starts from the package of the @SpringBootApplication class. You can change that:
@SpringBootApplication(scanBasePackages = "com.mycompany")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@ComponentScan
For more control:
@ComponentScan(basePackages = {
"com.mycompany.core",
"com.mycompany.shared"
})
@SpringBootApplication
public class DemoApplication {
}
Why the com.example Package?
When you create a project with Spring Initializr, the default package is com.example.demo. This isn't just any name — com.example is a reserved domain that's safe to use for testing.
For production, replace it with your own domain:
com.skillversitas.api
com.skillversitas.service
com.skillversitas.repository
A Good Package Structure
com.skillversitas.api
├── controller/ → @RestController, @Controller
├── service/ → @Service
├── repository/ → @Repository
├── model/ → POJO / Entity (no annotation needed)
├── dto/ → Data Transfer Object
├── config/ → @Configuration
└── exception/ → Custom exceptions
Classes in the model and dto packages usually don't need stereotype annotations, because they're not Spring components — they're simply defined as plain POJOs.
Verifying Detected Components
Add this to application.properties:
logging.level.org.springframework=DEBUG
Look in the logs for: Bean ...Definition ... for type ...
With an understanding of component scanning, you now know how Spring automatically finds all the components. In the next chapter, we'll dive deep into Dependency Injection — how Spring injects dependencies between components.