Interview Prep Zoneby CuriouserLabs

Question 3 of 5 · senior level

Break down @SpringBootApplication. What are the component-scanning implications and common traps?

🎤 Say this first

It's three annotations: @SpringBootConfiguration (a @Configuration, discoverable by tests), @EnableAutoConfiguration, and @ComponentScan rooted at the package of the class — no basePackages default beyond that. Traps follow directly: put the application class in a root package (classes outside its package tree are invisible — the 'my bean isn't found' classic); scanning a too-broad root slows startup and drags in surprises; and library code should never rely on being scanned — libraries register via auto-configuration imports, not component scan.

The full picture

  • Placement rule: com.acme.orders.OrdersApplication scans com.acme.orders.** — a com.acme.shared.PricingService is NOT found. Fix with scanBasePackages or (better) restructure; implicit invisibility is the bug generator.
  • Test hook: @SpringBootTest walks up packages to find @SpringBootConfiguration — why tests magically locate your app class, and why two application classes in one module break test slices.
  • Exclusions: @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) for 'I have the jar but not the infra' cases (e.g., a library dragged in JPA).
  • Scanning cost & hygiene: each scanned class is ASM-read at startup; keep the tree tight, and use @ComponentScan(excludeFilters=…) sparingly — if you're filtering a lot, your packages are wrong.
The invisible-bean trap
com.acme.orders
 └── OrdersApplication.java      // @SpringBootApplication — scan root
com.acme.common
 └── AuditService.java           // @Service … and silently NEVER registered

// NoSuchBeanDefinitionException at startup (if constructor-injected — fail fast!)
// Options:
@SpringBootApplication(scanBasePackages = {"com.acme.orders", "com.acme.common"})
// or: move OrdersApplication up to com.acme
// or (library-grade): ship com.acme.common with its own @AutoConfiguration

🔄 Likely follow-up questions

  • Why does @SpringBootTest find your configuration automatically?
  • What's the difference between scanBasePackages and @Import for pulling in modules?
  • How would Spring Modulith formalize these package boundaries?