Course topics

By WebNest Studio Engineering Team

Spring Framework Tutorial

Component Scanning with @ComponentScan

Component scanning is the mechanism Spring uses to automatically discover classes annotated with stereotype annotations (@Component, @Service, @Repository, @Controller) and register them as beans, without you having to declare each one manually with a @Bean method. Instead of writing explicit bean definitions for every class, you annotate the classes themselves and tell Spring which packages to scan.

This "convention over configuration" approach is what makes modern Spring applications concise. The @ComponentScan annotation, usually placed on a @Configuration class, drives this discovery process, and choosing the right base package(s) is important both for correctness (finding all the beans you actually need) and for startup performance (not scanning far more of the classpath than necessary).

How @ComponentScan Works

When the container starts, @ComponentScan tells Spring to walk the specified package(s) and their sub-packages, looking for classes annotated with @Component or any annotation that is itself meta-annotated with @Component (which is how @Service, @Repository, and @Controller are recognized). Each matching class is registered as a bean definition, and its scope, dependencies, and lifecycle are then managed exactly like any other bean.

Specifying Base Packages

Without arguments, @ComponentScan scans the package of the class it's declared on, plus all sub-packages. In many small projects this is exactly what's wanted, since the main configuration/application class often sits at the root of the project's package tree — which is precisely why Spring Boot's @SpringBootApplication (which includes @ComponentScan) works "automatically" as long as your classes live under the main class's package.

  • @ComponentScan — scans the current package and sub-packages by default.
  • @ComponentScan("com.webnest.app") — scans a single named base package explicitly.
  • @ComponentScan(basePackages = {"com.webnest.service", "com.webnest.repository"}) — scans multiple explicit base packages.
  • @ComponentScan(basePackageClasses = OrderService.class) — a type-safe alternative that scans the package containing that class, refactor-safe against package renames.

Common Pitfalls with Package Placement

If a @Component-annotated class lives outside the scanned base package(s), Spring simply never finds it — no error is thrown, the bean is just silently absent from the context, and any attempt to @Autowired it elsewhere fails with a "NoSuchBeanDefinitionException" or a similar wiring failure. This is one of the most common real-world Spring bugs, especially after refactoring package structures.

Example

Explicit multi-package component scanning

Java
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;

// com.webnest.service.PricingService
@Service
class PricingService {
    double applyTax(double amount) {
        return amount * 1.08;
    }
}

@Configuration
@ComponentScan(basePackages = {"com.webnest.service", "com.webnest.repository"})
class AppConfig { }

public class ScanDemo {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        PricingService pricing = context.getBean(PricingService.class);
        System.out.println(pricing.applyTax(100.0));
    }
}
Output
108.0

Common Mistakes

  • Placing a @Component/@Service/@Repository class in a package outside the scanned base packages, resulting in a silent missing-bean error at injection time rather than at the class declaration.
  • Scanning an overly broad base package (e.g. the entire "com" root) which slows startup and can accidentally pick up unrelated or test-only components.
  • Forgetting that @ComponentScan with no arguments only scans the package of the annotated class and its sub-packages, not the whole project.
  • Relying on @ComponentScan while also expecting classes annotated only with plain @Bean-producing methods elsewhere to be picked up automatically — @Bean methods still require their @Configuration class to be scanned or explicitly registered.

Exercise

A teammate is about to make this mistake: Placing a @Component/@Service/@Repository class in a package outside the scanned base packages, resulting in a silent missing-bean error at injection time rather than at the class declaration. Use How @ComponentScan Works to review the decision. Write a corrected implementation or design sketch that follows @ComponentScan automatically discovers and registers classes carrying stereotype annotations as beans., then name one edge case you would check.

Show hints
  • Start with How @ComponentScan Works and compare your approach with Explicit multi-package component scanning. Identify the decision or behavior the lesson recommends.
  • Walk through your scenario step by step. Confirm that it follows @ComponentScan automatically discovers and registers classes carrying stereotype annotations as beans. and that it would catch the failure described by Placing a @Component/@Service/@Repository class in a package outside the scanned base packages, resulting in a silent missing-bean error at injection time rather than at the class declaration..

Quick quiz

1. Which choice best describes the recommended approach in Component Scanning with @ComponentScan?

  • A. Placing a @Component/@Service/@Repository class in a package outside the scanned base packages, resulting in a silent missing-bean error at injection time rather than at the class declaration.
  • B. Scanning an overly broad base package (e.g. the entire "com" root) which slows startup and can accidentally pick up unrelated or test-only components.
  • C. @ComponentScan automatically discovers and registers classes carrying stereotype annotations as beans.
Show answer

C. This is the recommended approach: @ComponentScan automatically discovers and registers classes carrying stereotype annotations as beans. Avoid: Placing a @Component/@Service/@Repository class in a package outside the scanned base packages, resulting in a silent missing-bean error at injection time rather than at the class declaration.

Interview questions

Why does this principle matter in Component Scanning with @ComponentScan: @ComponentScan automatically discovers and registers classes carrying stereotype annotations as beans.

Show answer

@ComponentScan automatically discovers and registers classes carrying stereotype annotations as beans. Apply this in How @ComponentScan Works; the example Explicit multi-package component scanning shows one way to do it. Avoid Placing a @Component/@Service/@Repository class in a package outside the scanned base packages, resulting in a silent missing-bean error at injection time rather than at the class declaration. and explain how your implementation or design prevents that failure.

Key Points to Remember

  • @ComponentScan automatically discovers and registers classes carrying stereotype annotations as beans.
  • By default it scans the package of the annotated class and everything beneath it.
  • basePackages (strings) and basePackageClasses (type-safe) let you target specific package trees explicitly.
  • A component outside the scanned packages is silently skipped — no compile or startup error, just a missing bean.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

These examples need a JDK project with their libraries on your computer, so they can be copied but not run here. Codelab runs Python, FastAPI backends with SQLite, plain Java 17 and HTML/CSS/JavaScript.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering