Why this matters
- Knowing what each meta-annotation does lets you troubleshoot startup issues — like beans not being found or unwanted auto-config loading.
- Boot-specific annotations (
@ConditionalOn*,@ConfigurationProperties) are the vocabulary for custom starters and library integration. - Interview questions often ask what
@SpringBootApplicationactually contains.
Decomposing @SpringBootApplication
@SpringBootApplication
public class BookStoreApplication { ... }
Expands to three annotations:
@SpringBootConfiguration // alias for @Configuration
@EnableAutoConfiguration // load auto-config classes from META-INF
@ComponentScan // scan current package and below
Each serves a distinct purpose in the startup sequence.
Core bootstrap annotations
@SpringBootConfiguration— Marks the class as a source of@Beandefinitions; typically only on the main class.@EnableAutoConfiguration— ImportsAutoConfigurationImportSelectorwhich loads conditional config fromMETA-INF/spring/.@ComponentScan— Discovers@Component,@Service,@Repository,@Controllerin the package tree.
Customising the scan root
@SpringBootApplication(scanBasePackages = "com.example.bookstore")
public class BookStoreApplication { ... }
Exclude specific auto-configurations:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class BookStoreApplication { ... }
Useful when running BookStore without a database in a specific profile.
@Configuration and @Bean
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean<RequestLoggingFilter> loggingFilter() {
FilterRegistrationBean<RequestLoggingFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new RequestLoggingFilter());
bean.addUrlPatterns("/api/*");
return bean;
}
}
@Configuration classes are processed at startup. @Bean methods register return values in the container. By default, @Bean methods are proxied so repeated calls return the same singleton.
Conditional annotations preview
Boot's auto-config relies on conditions you can use in your own config:
@Configuration
@ConditionalOnProperty(name = "bookstore.cache.enabled", havingValue = "true")
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("books", "authors");
}
}
The CacheManager bean exists only when the property is true. The auto-configuration module covers the full @ConditionalOn* family.
@ConfigurationProperties
@ConfigurationProperties(prefix = "bookstore")
@Validated
public record BookStoreProperties(
@NotNull Pricing pricing,
@NotNull Catalog catalog
) {
public record Pricing(String serviceUrl, int timeoutMs) {}
public record Catalog(int pageSize) {}
}
Enable with @EnableConfigurationProperties(BookStoreProperties.class) or @ConfigurationPropertiesScan.
Web layer annotations
@RestController
@RequestMapping("/api/books")
public class BookController {
@GetMapping("/{id}")
public BookResponse get(@PathVariable Long id) { ... }
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public BookResponse create(@RequestBody @Valid CreateBookRequest request) { ... }
}
| Annotation | Purpose |
|---|---|
| @GetMapping | Map HTTP GET |
| @PostMapping | Map HTTP POST |
| @PathVariable | Bind URI template variable |
| @RequestBody | Deserialize request body |
| @RequestParam | Bind query parameter |
| @ResponseStatus | Set HTTP status on response |
@GetMapping
PurposeMap HTTP GET@PostMapping
PurposeMap HTTP POST@PathVariable
PurposeBind URI template variable@RequestBody
PurposeDeserialize request body@RequestParam
PurposeBind query parameter@ResponseStatus
PurposeSet HTTP status on response
Transaction and caching annotations
@Service
public class BookService {
@Cacheable("books")
public Book findById(Long id) { ... }
@Transactional
public Book updatePrice(Long id, BigDecimal price) { ... }
}
@Transactional starts a transaction boundary. @Cacheable stores return values in the configured cache — both are AOP proxies applied by Spring.
Testing annotations
@WebMvcTest(BookController.class)
class BookControllerTest {
@Autowired MockMvc mockMvc;
@MockBean BookService bookService;
}
@WebMvcTest loads only the web layer. @MockBean replaces a container bean with a Mockito mock.
Quick recall
Everything you need if you only revisit this box.
@SpringBootApplicationcombines configuration, auto-config, and component scanning.@Configuration+@Beanregister objects the container cannot discover via scanning.@ConditionalOnPropertyand related annotations gate bean creation on environment state.@ConfigurationPropertiesbinds typed config fromapplication.yml.- Web annotations (
@GetMapping,@PathVariable) map HTTP to Java methods. @Transactionaland@Cacheableare declarative cross-cutting concerns applied via proxies.
Test yourself
Answer these before moving on — recall is what makes it stick.