Skillversitas

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.