Skip to content
Unverified — AI-generated content. Help verify this page

Spring Boot Cheat Sheet

A complete quick reference for Spring Boot 3.x with Java 21. Covers every annotation, configuration property, testing shortcut, and CLI command you need in daily development.

Core Annotations

Application Setup

AnnotationPurpose
@SpringBootApplicationEntry point. Combines @Configuration + @EnableAutoConfiguration + @ComponentScan
@EnableAutoConfigurationEnable Spring Boot auto-configuration
@ComponentScanScan for Spring components in current package and sub-packages
@SpringBootConfigurationVariant of @Configuration for Spring Boot

Stereotype Annotations

AnnotationPurposeSpecial Behavior
@ComponentGeneric Spring beanNone
@ServiceBusiness logic beanNone (semantic only)
@RepositoryData access beanException translation
@ControllerWeb MVC controllerView resolution
@RestControllerREST API controller= @Controller + @ResponseBody
@ConfigurationBean definition classProxied for singleton beans

Dependency Injection

AnnotationPurpose
@AutowiredInject dependency (optional with single constructor)
@Qualifier("name")Disambiguate between multiple beans
@PrimaryPreferred bean when multiple candidates
@Value("${key}")Inject property value
@LazyDelay bean initialization until first use

Bean Definition

AnnotationPurpose
@BeanDeclare a bean in @Configuration class
@Scope("prototype")Set bean scope (singleton/prototype/request/session)
@Profile("dev")Activate bean only in specific profile
@ConditionalOnPropertyCreate bean only if property is set
@ConditionalOnClassCreate bean only if class exists on classpath
@ConditionalOnMissingBeanCreate bean only if no other bean of that type exists
@ConfigurationPropertiesBind properties to a POJO/record

Lifecycle

AnnotationPurpose
@PostConstructRun after dependency injection
@PreDestroyRun before bean destruction
@EventListenerHandle application events
@TransactionalEventListenerHandle events after transaction commit
@Order(1)Set bean initialization order

Web Annotations

Request Mapping

AnnotationHTTP Method
@RequestMappingAny (configurable)
@GetMappingGET
@PostMappingPOST
@PutMappingPUT
@PatchMappingPATCH
@DeleteMappingDELETE

Request Parameters

AnnotationSourceExample
@PathVariableURL path/users/{id}
@RequestParamQuery string?name=foo&page=0
@RequestBodyRequest bodyJSON payload
@RequestHeaderHTTP headerAuthorization
@CookieValueCookieSession cookie
@MatrixVariableMatrix params/cars;color=red

Response

AnnotationPurpose
@ResponseBodySerialize return value to response body
@ResponseStatus(HttpStatus.CREATED)Set HTTP status code
@CrossOriginEnable CORS on controller/method
@ExceptionHandlerHandle specific exception in controller
@ControllerAdviceGlobal exception handler
@RestControllerAdvice= @ControllerAdvice + @ResponseBody

Validation Annotations

AnnotationValidates
@ValidCascading validation on @RequestBody or nested objects
@ValidatedEnables validation on path vars / request params; supports groups
@NotNullNot null
@NotBlankNot null, not empty, not whitespace (String)
@NotEmptyNot null, not empty (String/Collection)
@Size(min, max)String length or collection size
@Min(value)Numeric >= value
@Max(value)Numeric <= value
@Positive> 0
@PositiveOrZero>= 0
@EmailValid email format
@Pattern(regexp)Matches regex
@Past / @FutureDate before/after now
@DecimalMin / @DecimalMaxBigDecimal range
@Digits(integer, fraction)Number precision

JPA Annotations

Entity Mapping

AnnotationPurpose
@EntityJPA entity class
@Table(name = "...")Database table name
@IdPrimary key
@GeneratedValueAuto-generated ID (UUID, IDENTITY, SEQUENCE)
@ColumnColumn mapping (name, nullable, unique, length)
@Enumerated(EnumType.STRING)Enum stored as string
@LobLarge object (BLOB/CLOB)
@TemporalDate/time precision
@VersionOptimistic locking
@CreationTimestampAuto-set on insert
@UpdateTimestampAuto-set on update
@TransientNot persisted

Relationships

AnnotationCardinalityDefault Fetch
@OneToOne1:1EAGER
@OneToMany1:NLAZY
@ManyToOneN:1EAGER (change to LAZY!)
@ManyToManyM:NLAZY
@JoinColumnForeign key column
@JoinTableJoin table for M:N

Repository

AnnotationPurpose
@Query("JPQL")Custom JPQL query
@Query(nativeQuery = true)Native SQL query
@ModifyingFor UPDATE/DELETE queries
@EntityGraphEager fetch specific associations
@Lock(LockModeType.PESSIMISTIC_WRITE)Pessimistic locking

Security Annotations

AnnotationPurpose
@EnableWebSecurityEnable Spring Security
@EnableMethodSecurityEnable @PreAuthorize/@PostAuthorize
@PreAuthorize("expression")Check before method execution
@PostAuthorize("expression")Check after method execution
@Secured("ROLE_ADMIN")Role-based access (simpler)
@RolesAllowed("ADMIN")Jakarta annotation for role check
@AuthenticationPrincipalInject current user
@WithMockUserTest with fake user

Testing Annotations

AnnotationLoadsSpeed
@SpringBootTestFull contextSlow
@WebMvcTest(Controller.class)Web sliceFast
@DataJpaTestJPA sliceMedium
@JsonTestJackson onlyFast
@WebFluxTestWebFlux sliceFast
@RestClientTestRestTemplateFast
AnnotationPurpose
@MockBeanReplace bean with Mockito mock
@SpyBeanWrap bean with Mockito spy
@ActiveProfiles("test")Activate test profile
@DynamicPropertySourceSet properties from Testcontainers
@Sql("/data.sql")Run SQL before test
@TransactionalRollback after each test
@TestcontainersEnable Testcontainers
@ContainerMark Testcontainer field

Caching Annotations

AnnotationPurpose
@EnableCachingEnable cache abstraction
@Cacheable(value, key)Cache method result
@CacheEvict(value, key)Remove from cache
@CachePut(value, key)Always execute, update cache
@Caching(...)Combine multiple cache operations
@CacheConfig(cacheNames)Class-level cache defaults

Async & Scheduling

AnnotationPurpose
@EnableAsyncEnable @Async support
@AsyncRun method in background thread
@Async("executorName")Use specific thread pool
@EnableSchedulingEnable @Scheduled support
@Scheduled(fixedRate = 5000)Run every 5 seconds
@Scheduled(cron = "0 0 2 * * *")Run at 2 AM daily

Common Configuration

application.yml Template

yaml
spring:
  application:
    name: my-app
  profiles:
    active: ${SPRING_PROFILES_ACTIVE:dev}

  # Database
  datasource:
    url: jdbc:postgresql://${DB_HOST:localhost}:5432/${DB_NAME:myapp}
    username: ${DB_USERNAME:postgres}
    password: ${DB_PASSWORD:postgres}
    hikari:
      maximum-pool-size: ${HIKARI_MAX_POOL:10}
      minimum-idle: 5
      connection-timeout: 30000
      leak-detection-threshold: 60000

  # JPA
  jpa:
    hibernate:
      ddl-auto: validate
    open-in-view: false
    properties:
      hibernate:
        default_batch_fetch_size: 25
        format_sql: true
        jdbc.batch_size: 25
        order_inserts: true
        order_updates: true

  # Jackson
  jackson:
    default-property-inclusion: non_null
    serialization:
      write-dates-as-timestamps: false

  # Flyway
  flyway:
    enabled: true
    locations: classpath:db/migration
    clean-disabled: true

# Server
server:
  port: ${SERVER_PORT:8080}
  shutdown: graceful
  error:
    include-message: always
    include-binding-errors: always

# Actuator
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: when_authorized
      probes:
        enabled: true

# Logging
logging:
  level:
    root: WARN
    com.example: INFO
    org.hibernate.SQL: ${SQL_LOG_LEVEL:WARN}
  pattern:
    console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"

Maven Commands

bash
# Run application
./mvnw spring-boot:run

# Run with profile
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev

# Run tests
./mvnw test

# Skip tests
./mvnw package -DskipTests

# Build JAR
./mvnw clean package

# Build native image
./mvnw -Pnative native:compile

# Build Docker image (Buildpacks)
./mvnw spring-boot:build-image

# Build Docker image (JIB)
./mvnw jib:dockerBuild

# Dependency tree
./mvnw dependency:tree

# Check for dependency updates
./mvnw versions:display-dependency-updates

# Generate project from Initializr
curl https://start.spring.io/starter.tgz \
  -d type=maven-project -d language=java \
  -d bootVersion=3.4.3 -d javaVersion=21 \
  -d dependencies=web,data-jpa,postgresql,validation,actuator,lombok \
  -d groupId=com.example -d artifactId=my-app | tar -xzvf -

Gradle Commands

bash
# Run application
./gradlew bootRun

# Run with profile
SPRING_PROFILES_ACTIVE=dev ./gradlew bootRun

# Run tests
./gradlew test

# Build JAR
./gradlew bootJar

# Build native image
./gradlew nativeCompile

# Build Docker image
./gradlew bootBuildImage

# Dependency report
./gradlew dependencies --configuration runtimeClasspath

Actuator Endpoints

bash
# Health check
curl http://localhost:8080/actuator/health

# Application info
curl http://localhost:8080/actuator/info

# List all metrics
curl http://localhost:8080/actuator/metrics

# Specific metric
curl http://localhost:8080/actuator/metrics/jvm.memory.used

# Prometheus format
curl http://localhost:8080/actuator/prometheus

# View log levels
curl http://localhost:8080/actuator/loggers/com.example

# Change log level at runtime
curl -X POST http://localhost:8080/actuator/loggers/com.example \
     -H 'Content-Type: application/json' -d '{"configuredLevel":"DEBUG"}'

# Environment properties
curl http://localhost:8080/actuator/env

HTTP Status Code Quick Reference

CodeConstantWhen to Use
200OKSuccessful GET, PUT, PATCH
201CREATEDSuccessful POST (resource created)
204NO_CONTENTSuccessful DELETE
400BAD_REQUESTValidation errors, malformed request
401UNAUTHORIZEDAuthentication required
403FORBIDDENAuthenticated but not authorized
404NOT_FOUNDResource does not exist
409CONFLICTDuplicate resource (e.g., duplicate email)
422UNPROCESSABLE_ENTITYBusiness rule violation
429TOO_MANY_REQUESTSRate limit exceeded
500INTERNAL_SERVER_ERRORUnexpected server error
502BAD_GATEWAYExternal service error
503SERVICE_UNAVAILABLEService temporarily down

Common Spring Boot Starters

StarterIncludes
spring-boot-starter-webSpring MVC, Tomcat, Jackson
spring-boot-starter-data-jpaHibernate, HikariCP, Spring Data JPA
spring-boot-starter-securitySpring Security
spring-boot-starter-validationHibernate Validator
spring-boot-starter-actuatorHealth, metrics, info endpoints
spring-boot-starter-cacheCaching abstraction
spring-boot-starter-mailEmail sending
spring-boot-starter-webfluxReactive web (Netty)
spring-boot-starter-data-redisRedis client
spring-boot-starter-oauth2-resource-serverJWT validation
spring-boot-starter-oauth2-clientOAuth2 login
spring-boot-starter-testJUnit 5, Mockito, MockMvc, AssertJ
spring-boot-starter-hateoasHATEOAS links
spring-boot-starter-batchBatch processing

Quick Patterns

Constructor Injection (Lombok)

java
@Service
@RequiredArgsConstructor  // Generates constructor for final fields
public class OrderService {
    private final OrderRepository orderRepository;
    private final PaymentGateway paymentGateway;
}

Record DTO with Validation

java
public record CreateUserRequest(
        @NotBlank @Email String email,
        @NotBlank @Size(min = 8) String password,
        @NotBlank String firstName
) {}

Paginated Endpoint

java
@GetMapping
public Page<ProductResponse> list(
        @PageableDefault(size = 20, sort = "createdAt",
                direction = Sort.Direction.DESC) Pageable pageable) {
    return productService.findAll(pageable);
}

Global Exception Handler (Minimal)

java
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ProblemDetail handleNotFound(ResourceNotFoundException ex) {
        return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ProblemDetail handleAll(Exception ex) {
        return ProblemDetail.forStatusAndDetail(
                HttpStatus.INTERNAL_SERVER_ERROR, "An unexpected error occurred");
    }
}

Further Reading


Test Yourself
  1. What annotation combines @Controller and @ResponseBody?@RestController

  2. How do you inject a property value from application.yml into a field?@Value("${property.key}")

  3. What annotation activates a bean only in a specific profile?@Profile("dev")

  4. What is the default fetch type for @ManyToOne in JPA, and why is it problematic? EAGER -- it loads the related entity on every query, causing N+1 problems. Change to fetch = FetchType.LAZY.

  5. What test slice annotation loads only the web layer for a specific controller?@WebMvcTest(Controller.class)

  6. How do you change the log level of a package at runtime via Actuator?curl -X POST .../actuator/loggers/com.example -H 'Content-Type: application/json' -d '{"configuredLevel":"DEBUG"}'

  7. What annotation makes a bean initialize only after another specific bean exists?@ConditionalOnMissingBean (creates only if no other bean of that type exists).

  8. What HTTP status should a successful POST that creates a resource return?201 CREATED

  9. How do you build a Docker image from a Spring Boot project using Buildpacks?./mvnw spring-boot:build-image

  10. What annotation enables method-level security like @PreAuthorize?@EnableMethodSecurity

Common Gotchas

  • spring.jpa.open-in-view=true (default). It keeps the Hibernate session open during the entire HTTP request, which hides lazy loading issues in development but causes performance problems in production. Set it to false.
  • @ManyToOne defaults to EAGER fetch. Every time you load an entity, JPA also loads the related entity. Always set fetch = FetchType.LAZY on @ManyToOne.
  • Using @Autowired on fields instead of constructor injection. Field injection makes testing harder and hides dependencies. Use @RequiredArgsConstructor with final fields.
  • ddl-auto=update in production. Hibernate's schema auto-update can drop columns or create wrong indexes. Use validate in production with Flyway or Liquibase for migrations.

One-Liner Summary

Spring Boot is an opinionated Java framework that auto-configures everything -- master annotations, profiles, Actuator, and test slices to build production-ready APIs with minimal boilerplate.

"What I cannot create, I do not understand." — Richard Feynman