@SpringBootApplication Annotation

It’s a convenience meta-annotation that combines three core Spring annotations:

  • @SpringBootConfiguration → specialization of @Configuration (declares bean definitions).
  • @EnableAutoConfiguration → turns on auto-configuration (wires beans based on classpath, properties, and conditions).
  • @ComponentScan → scans the package of the annotated class and its sub-packages for components (@Component, @Service, @Repository, @Controller, etc.).

So, this:

@SpringBootApplication
public class App {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

is roughly equivalent to:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

Key attributes you’ll actually use

@SpringBootApplication re-exports some attributes from its composed annotations (via @AliasFor), so you can configure them in one place:

  • scanBasePackages / scanBasePackageClasses (from @ComponentScan)
    Control what packages to scan.

    @SpringBootApplication(scanBasePackages = "com.example.myapp")
    
  • exclude / excludeName (from @EnableAutoConfiguration)
    Turn off specific auto-configs.

    @SpringBootApplication(
        exclude = {org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class}
    )
    

    (Alternatively, via property: spring.autoconfigure.exclude=...)

  • proxyBeanMethods (bubbled from @Configuration)
    When false, Spring doesn’t create CGLIB proxies for the config class → slightly faster startup, but don’t call one @Bean method from another expecting inter-bean references.

    @SpringBootApplication(proxyBeanMethods = false)
    

How auto-configuration actually works (in brief)

  • Boot imports a curated list of @AutoConfiguration classes (Boot 3.x uses META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports).
  • Each auto-config is guarded by conditions like @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty, etc.
  • You can customize behavior via properties (e.g., application.properties), or by defining your own beans to override defaults.

Best practices & gotchas

  • Package placement matters: put your @SpringBootApplication class at the root package of your project so @ComponentScan picks everything up.
  • Prefer properties over exclusions when possible; exclusions are a blunt tool.
  • Library code shouldn’t use @SpringBootApplication; keep it in the application’s entry module.
  • If you set proxyBeanMethods=false, avoid calling @Bean methods inside the same config class expecting them to return managed singletons (they’ll be plain method calls).

Tiny examples

Custom scan + exclude one auto-config

@SpringBootApplication(
  scanBasePackages = {"com.example.api", "com.example.core"},
  exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class}
)
public class App {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

Lean startup (no config proxies)

@SpringBootApplication(proxyBeanMethods = false)
public class App { /* ... */ }
Back to blog

Leave a comment