Cheat Sheets

Three dense quick references by persona—core annotations and REST for juniors, security and testing for mid-level, and production tuning for seniors. Use Copy sheet for plain text, persona filters to focus one level, or print (Cmd/Ctrl+P).

junior mid senior

Junior Cheat Sheet

Stereotypes, DI, REST, validation, JPA basics, properties. Chapters: IoC & DI, Web MVC, Spring Data.

junior

Core stereotypes & DI

AnnotationRoleNotes
@ComponentGeneric Spring beanScanned in base package
@ServiceBusiness logicSemantic alias of @Component
@RepositoryPersistenceTranslates persistence exceptions
@ConfigurationJava config classContains @Bean methods
@BeanFactory method beanExplicit registration
@AutowiredInject dependencyPrefer constructor injection
@Qualifier("name")Pick bean when multipleWith constructor param
@PrimaryDefault when ambiguousOn one implementation
@Value("${key}")Inject propertyDefault: ${key:default}
@Profile("dev")Conditional beanActivate via spring.profiles.active
@Service
class OrderService {
  private final OrderRepository orders;
  OrderService(OrderRepository orders) { this.orders = orders; }
}

Bean scopes

ScopeLifecycle
singleton (default)One instance per container
prototypeNew instance per injection/getBean
request / sessionWeb-aware; one per HTTP request/session

REST controller annotations

AnnotationPurpose
@RestController@Controller + @ResponseBody on class
@RequestMapping("/api")Base path (class or method)
@GetMapping / @PostMappingHTTP verb shortcuts
@PutMapping / @PatchMapping / @DeleteMappingUpdate / partial / delete
@PathVariableURI segment: /orders/{id}
@RequestParamQuery: ?page=0&size=20
@RequestBodyDeserialize JSON body
@ResponseStatus(HttpStatus.CREATED)Override default status
ResponseEntity<T>Status + headers + body
@RestController
@RequestMapping("/api/orders")
class OrderController {
  @GetMapping("/{id}")
  OrderDto get(@PathVariable Long id) { return service.find(id); }

  @PostMapping
  @ResponseStatus(HttpStatus.CREATED)
  OrderDto create(@Valid @RequestBody CreateOrderRequest req) {
    return service.create(req);
  }
}

Validation

AnnotationConstraint
@Valid / @ValidatedTrigger validation on object/param
@NotNull / @NotBlank / @NotEmptyPresence
@Size(min, max)String/collection length
@Min / @MaxNumeric bounds
@Email / @PatternFormat
@Positive / @PositiveOrZeroSign (Bean Validation 2.0+)

Spring Data JPA — essentials

APIExample
Repositoryinterface OrderRepo extends JpaRepository<Order, Long>
Query methodsfindByStatusAndCreatedAtAfter(String s, Instant t)
@QueryJPQL: @Query("SELECT o FROM Order o WHERE o.status = :s")
@Entity / @IdJPA mapping; @GeneratedValue for IDs
@TransactionalTransactional boundary on service methods
PaginationPage<Order> findByStatus(String s, Pageable p)
@Transactional(readOnly = true)
public Order findById(Long id) {
  return repo.findById(id).orElseThrow(() -> new OrderNotFoundException(id));
}

application.properties / YAML

PropertyPurpose
spring.application.nameService name in logs/metrics
server.portHTTP port (default 8080)
spring.datasource.urlJDBC URL
spring.jpa.hibernate.ddl-autovalidate prod; update dev only
spring.profiles.activeActive profile(s)
logging.level.com.acmePackage log level

Boot starter cheat map

StarterBrings
spring-boot-starter-webMVC, Tomcat, Jackson
spring-boot-starter-data-jpaJPA, Hibernate, JDBC
spring-boot-starter-validationBean Validation
spring-boot-starter-testJUnit 5, Mockito, AssertJ, MockMvc
spring-boot-starter-actuatorHealth, metrics endpoints

Mid-Level Cheat Sheet

Transactions, security, caching, async, testing slices, Boot config. Chapters: Security, Caching, Testing, Boot Internals.

mid

@Transactional — propagation & isolation

PropagationBehavior
REQUIRED (default)Join existing or create new
REQUIRES_NEWSuspend current; always new tx
NESTEDSavepoint within outer tx (JDBC)
SUPPORTSJoin if exists; non-tx otherwise
NOT_SUPPORTEDSuspend tx; run non-transactional
MANDATORYMust have tx; else exception
NEVERMust not have tx
OptionTypical use
readOnly = trueQueries; Hibernate skip dirty check
rollbackFor = Exception.classRollback on checked exceptions
timeout = 30Seconds before tx timeout
isolation = READ_COMMITTEDRare override; DB default usually fine
// Self-invocation bypasses proxy — call from another bean
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void audit(Order order) { auditRepo.save(...); }

Spring Security — filter chain

ConceptSnippet / note
SecurityFilterChain@Bean SecurityFilterChain filterChain(HttpSecurity http)
Authorize.authorizeHttpRequests(a -> a.requestMatchers("/public/**").permitAll().anyRequest().authenticated())
Stateless JWT.sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
CSRFDisable for stateless APIs: .csrf(csrf -> csrf.disable())
@PreAuthorize@PreAuthorize("hasRole('ADMIN')") — enable method security
@EnableMethodSecurityReplaces deprecated @EnableGlobalMethodSecurity
Test@WithMockUser(roles = "ADMIN") on MockMvc tests

Caching annotations

AnnotationEffect
@EnableCachingActivate cache abstraction
@Cacheable("products")Cache return value; skip method on hit
@CachePutAlways run method; update cache
@CacheEvictRemove entries (key or allEntries)
@CachingMultiple cache ops on one method
keySpEL: key = "#id" or "#root.methodName"
unlessSpEL: don't cache if true — unless = "#result == null"
@Cacheable(value = "orders", key = "#id")
public Order findById(Long id) { return repo.findById(id).orElseThrow(); }

@CacheEvict(value = "orders", key = "#order.id")
public void update(Order order) { repo.save(order); }

Async, scheduling & events

AnnotationPurpose
@EnableAsyncEnable @Async methods
@AsyncRun on task executor thread pool
@EnableSchedulingEnable @Scheduled
@Scheduled(cron = "0 0 * * * *")Cron (6-field with seconds in Spring)
@Scheduled(fixedDelay = 5000)Delay after previous completion
ApplicationEventPublisherPublish domain events
@EventListenerHandle event; @Async for async handler
@TransactionalEventListenerAfter commit / rollback phase

Test slices — pick the right one

AnnotationLoadsSpeed
@WebMvcTestControllers + MVC; mock services⚡ fastest web
@DataJpaTestJPA + embedded DB; tx rollback⚡ fast persistence
@JsonTestJackson only⚡ fast serialization
@RestClientTestRestTemplate/WebClient + mock serverFast client
@SpringBootTestFull contextSlow — few tests
@MockBeanReplace bean in test context
@SpyBeanWrap real bean; partial mock
@WebMvcTest(OrderController.class)
class OrderControllerTest {
  @Autowired MockMvc mockMvc;
  @MockBean OrderService orders;

  @Test void get() throws Exception {
    when(orders.find(1L)).thenReturn(dto);
    mockMvc.perform(get("/api/orders/1"))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.id").value(1));
  }
}

MockMvc matchers

MatcherExample
status().andExpect(status().isCreated())
jsonPath().andExpect(jsonPath("$.items", hasSize(3)))
content().andExpect(content().contentType(APPLICATION_JSON))
header().andExpect(header().exists("Location"))
andDo(print())Debug request/response

Spring Boot — config & conditions

MechanismUse
@ConditionalOnPropertyFeature flag beans
@ConditionalOnClassAuto-config when class present
@ConfigurationPropertiesType-safe config prefix binding
@RefreshScopeCloud: rebind on config refresh
spring.config.importImport optional config trees
Actuator/actuator/health, /actuator/info, /actuator/metrics

JPA pitfalls — quick fixes

ProblemFix
N+1 queries@EntityGraph, JOIN FETCH, @BatchSize
LazyInitializationExceptionFetch in tx; DTO projection; @Transactional on read
Dirty reads in long txShort transactions; readOnly for queries
equals/hashCode on entitiesBusiness key or ID only — not collections

Spring Batch — job essentials

ConceptNotes
Chunk step.chunk(size, txManager).reader().processor().writer()
JobParametersUnique params per run; RunIdIncrementer
Skip / retry.faultTolerant().skipLimit().retryLimit()
@StepScopeBeans using jobParameters
Disable auto-runspring.batch.job.enabled=false

Senior / Architect Cheat Sheet

AOP proxies, WebFlux, observability, production tuning, architecture decisions. Chapters: AOP, WebFlux, Observability, Batch.

senior

AOP — JDK vs CGLIB proxy

JDK dynamic proxyCGLIB subclass
RequiresInterfaceConcrete class (non-final)
Used whenBean implements interface(s)No interface or forced CGLIB
Self-invocationInternal this.method() bypasses proxy — inject self or split bean
Annotations on proxy@Transactional, @Cacheable, @Async need proxy call
@Aspect @Component
class TimingAspect {
  @Around("@annotation(Timed)")
  Object time(ProceedingJoinPoint pjp) throws Throwable {
    long start = System.nanoTime();
    try { return pjp.proceed(); }
    finally { log.info("{} took {}ms", pjp.getSignature(), (nanoTime()-start)/1e6); }
  }
}

WebFlux & Reactor — operator map

OperatorUse
Mono<T> / Flux<T>0–1 / 0–N async publisher
mapSync 1:1 transform
flatMapAsync 1:N — DB/HTTP calls
zip / merge / concatCombine streams
onErrorResume / retryWhenRecovery
timeout / cacheDeadline / memoize
subscribeOn(boundedElastic)Blocking offload — never on event loop
block()Tests/CLI only — not in controllers
@GetMapping("/{id}")
Mono<OrderDto> get(@PathVariable Long id) {
  return orders.findById(id).map(OrderDto::from);
}

// WebClient
client.get().uri("/rates").retrieve().bodyToMono(Rate.class)
    .timeout(Duration.ofSeconds(2))
    .retryWhen(Retry.backoff(3, Duration.ofMillis(100)));

WebFlux vs MVC + virtual threads

Choose WebFluxChoose MVC (+ vthreads)
Streaming SSE / NDJSONCRUD + JPA
Backpressure end-to-endTeam knows blocking stack
R2DBC / reactive drivers throughoutJava 21 spring.threads.virtual.enabled=true
High fan-out slow I/O compositionComplex ORM graphs

Observability — Micrometer meters

MeterAPI
Counterregistry.counter("orders.created", "channel", "web").increment()
Timerregistry.timer("checkout").record(() -> { ... })
Gaugeregistry.gauge("queue.size", atomicInteger)
DistributionSummaryregistry.summary("payload.bytes").record(n)
PrometheusGET /actuator/prometheus
Tag ruleLow cardinality only — no userId/orderId in labels

Distributed tracing (Boot 3)

ItemDetail
APIMicrometer Tracing (replaces Sleuth)
Brave bridgeZipkin export — management.zipkin.tracing.endpoint
OTel bridgemanagement.otlp.tracing.endpoint
Samplingmanagement.tracing.sampling.probability: 0.1
PropagationW3C traceparent header
Baggagemanagement.tracing.baggage.remote-fields — small, no PII
LogsMDC traceId / spanId correlation

Logging & MDC production

PracticeImplementation
Structured JSONlogstash-logback-encoder in prod profile
MDC fieldsrequestId, userId, traceId
Async appenderAsyncAppender — don't block request thread
Config filelogback-spring.xml + <springProfile>
LevelsINFO prod; DEBUG per-package temporarily

Kubernetes health & shutdown

Endpoint / configPurpose
/actuator/health/livenessRestart if broken
/actuator/health/readinessRemove from load balancer
management.endpoint.health.probes.enabledEnable K8s probe URLs
server.shutdown: gracefulDrain in-flight requests
spring.lifecycle.timeout-per-shutdown-phaseMax drain time (e.g. 30s)
CustomHealthIndicator for DB, Redis, partners

Testcontainers & integration

PatternSnippet
Static containerstatic @Container PostgreSQLContainer
Properties@DynamicPropertySource or @ServiceConnection (Boot 3.1+)
WireMock@WireMockTest — stub external HTTP
Context cacheSame slice config reuses context — avoid unique @MockBean sets
@DirtiesContextUse sparingly — busts cache, slow CI

Spring Batch — parallelism & ops

FeatureWhen
PartitioningLarge table — split ID ranges across workers
Chunk sizeTune 100–500; align with JDBC batch
JobRepositoryBATCH_* tables — backup & archive old runs
RestartFailed job resumes from last committed chunk
Schedule@Scheduled or K8s CronJob — not on startup

Auto-configuration debugging

ActionCommand / flag
Conditions report--debug or logging.level.org.springframework.boot.autoconfigure=DEBUG
Exclude auto-config@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
Startup timelinespring-boot-starter-actuator + startup endpoint (Boot 2.4+)
Bean overrideDefine your own @Bean — @ConditionalOnMissingBean backs off

Interview rapid-fire

QuestionOne-line answer
IoC vs DI?IoC: container controls creation; DI: dependencies injected from outside
Constructor vs field injection?Constructor: immutable, testable, required deps explicit
@Transactional on private method?No effect — proxy can't intercept
@WebMvcTest vs full Boot test?Slice: MVC only + mocks — faster, focused
Reactive vs virtual threads?Reactive: programming model + backpressure; vthreads: scale blocking code
Liveness vs readiness?Liveness: restart; readiness: stop traffic
High-cardinality metrics?Explodes time series — use logs/traces for per-entity detail