Home/Learn/Spring Boot/@ComponentScan & Stereotypes

@ComponentScan & Stereotypes

Beginner
Configuration

@ComponentScan instructs Spring to detect @Component, @Service, @Repository, and @Controller classes and register them as beans automatically.

Overview

@ComponentScan tells Spring which packages to scan for classes annotated with stereotype annotations. The four core stereotypes are: @Component (generic), @Service (business logic layer), @Repository (data access layer, adds exception translation), and @Controller/@RestController (web layer). @SpringBootApplication includes @ComponentScan pointed at the main class's package, so everything in the same package tree is auto-discovered. You can restrict or expand the scan with basePackages, includeFilters, and excludeFilters.

Stereotype Annotations

@Service, @Repository, and @Controller are all meta-annotated with @Component — they are specialisations that carry semantic meaning and enable targeted AOP or exception translation.

Java — four stereotype annotations
// @Component — generic bean; no additional semantics
@Component
public class PasswordEncoder { ... }

// @Service — marks business logic / service layer
// No technical difference from @Component, but signals intent
@Service
public class OrderService {
    public Order placeOrder(PlaceOrderRequest req) { ... }
}

// @Repository — data access layer
// Spring wraps methods to translate JDBC/JPA exceptions to DataAccessException
@Repository
public class JdbcOrderRepository {
    public Optional<Order> findById(Long id) { ... }
    // SQLException thrown here → auto-translated to DataAccessException
}

// @Controller — web layer (Spring MVC)
@Controller
public class OrderViewController { ... }

// @RestController — web layer for REST APIs (@Controller + @ResponseBody)
@RestController
public class OrderApiController { ... }

Customising @ComponentScan

By default, @SpringBootApplication scans the package of the main class. Use basePackages to scan additional packages, or includeFilters/excludeFilters to fine-tune what gets picked up.

Java — customising @ComponentScan
// Explicit base packages (multi-module project)
@SpringBootApplication
@ComponentScan(basePackages = {
    "com.example.orders",
    "com.example.shared",
    "com.example.infrastructure"
})
public class OrderServiceApp { ... }

// Exclude specific classes or packages
@ComponentScan(
    basePackages = "com.example",
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.REGEX,
        pattern = "com\.example\.legacy\..*"
    )
)

// Include only classes annotated with a custom annotation
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
public @interface EventHandler {}

@ComponentScan(
    basePackages = "com.example",
    includeFilters = @ComponentScan.Filter(
        type = FilterType.ANNOTATION, classes = EventHandler.class
    ),
    useDefaultFilters = false  // only scan for @EventHandler
)

Bean Naming & Conflict Resolution

Bean name defaults to the simple class name with a lowercase first letter. Override with @Component("customName"). Conflicts occur when two beans have the same name — the last definition wins in @ComponentScan (or throws a conflict exception in strict mode).

Java — bean naming and @Qualifier
// Default name: "orderService"
@Service
public class OrderService { ... }

// Custom name: "legacyOrderService"
@Service("legacyOrderService")
public class LegacyOrderService { ... }

// Inject by name when multiple beans of the same type exist
@Service
public class OrderFacade {
    private final OrderService orderService;        // primary
    private final OrderService legacyOrderService;  // secondary

    public OrderFacade(
            @Qualifier("orderService") OrderService orderService,
            @Qualifier("legacyOrderService") OrderService legacyOrderService) {
        this.orderService = orderService;
        this.legacyOrderService = legacyOrderService;
    }
}

// Or mark one as @Primary for default injection
@Service
@Primary
public class OrderService { ... }

Key Points to Remember

  • 1@SpringBootApplication includes @ComponentScan rooted at the main class's package.
  • 2@Service, @Repository, @Controller are semantic aliases for @Component.
  • 3@Repository adds PersistenceExceptionTranslationPostProcessor — translates DB exceptions.
  • 4basePackages restricts scanning; includeFilters/excludeFilters fine-tune discovery.
  • 5Default bean name = simple class name with lowercase first letter.
  • 6Use @Qualifier to disambiguate when multiple beans of the same type exist.

Interview Questions

Sign in to ask Aria
1

What is the difference between @Component, @Service, and @Repository?

EasyInfosys
2

What does @Repository add beyond @Component?

MediumAmazon
3

How does @SpringBootApplication enable component scanning?

EasyTCS
4

How would you exclude a package from component scanning?

MediumGoogle
5

What happens when two beans of the same type are found during autowiring?

MediumNetflix

Ask Aria about @ComponentScan & Stereotypes

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…