Observability
Cheat Sheets
Home
Hub
Spring Core
Cheat Sheets
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
Mid-Level
Senior
Core stereotypes & DI
Annotation Role Notes
@ComponentGeneric Spring bean Scanned in base package
@ServiceBusiness logic Semantic alias of @Component
@RepositoryPersistence Translates persistence exceptions
@ConfigurationJava config class Contains @Bean methods
@BeanFactory method bean Explicit registration
@AutowiredInject dependency Prefer constructor injection
@Qualifier("name")Pick bean when multiple With constructor param
@PrimaryDefault when ambiguous On one implementation
@Value("${key}")Inject property Default: ${key:default}
@Profile("dev")Conditional bean Activate via spring.profiles.active
@Service
class OrderService {
private final OrderRepository orders;
OrderService(OrderRepository orders) { this.orders = orders; }
}
Bean scopes
Scope Lifecycle
singleton (default)One instance per container
prototypeNew instance per injection/getBean
request / sessionWeb-aware; one per HTTP request/session
REST controller annotations
Annotation Purpose
@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
Annotation Constraint
@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
API Example
Repository interface OrderRepo extends JpaRepository<Order, Long>
Query methods findByStatusAndCreatedAtAfter(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
Pagination Page<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
Property Purpose
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
Starter Brings
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
@Transactional — propagation & isolation
Propagation Behavior
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
Option Typical 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
Concept Snippet / note
SecurityFilterChain @Bean SecurityFilterChain filterChain(HttpSecurity http)
Authorize .authorizeHttpRequests(a -> a.requestMatchers("/public/**").permitAll().anyRequest().authenticated())
Stateless JWT .sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
CSRF Disable 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
Annotation Effect
@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
Annotation Purpose
@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
Annotation Loads Speed
@WebMvcTestControllers + MVC; mock services ⚡ fastest web
@DataJpaTestJPA + embedded DB; tx rollback ⚡ fast persistence
@JsonTestJackson only ⚡ fast serialization
@RestClientTestRestTemplate/WebClient + mock server Fast client
@SpringBootTestFull context Slow — 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
Matcher Example
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
Mechanism Use
@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
Problem Fix
N+1 queries @EntityGraph, JOIN FETCH, @BatchSize
LazyInitializationException Fetch in tx; DTO projection; @Transactional on read
Dirty reads in long tx Short transactions; readOnly for queries
equals/hashCode on entities Business key or ID only — not collections
Spring Batch — job essentials
Concept Notes
Chunk step .chunk(size, txManager).reader().processor().writer()
JobParameters Unique params per run; RunIdIncrementer
Skip / retry .faultTolerant().skipLimit().retryLimit()
@StepScopeBeans using jobParameters
Disable auto-run spring.batch.job.enabled=false
Senior / Architect Cheat Sheet
AOP proxies, WebFlux, observability, production tuning, architecture decisions. Chapters: AOP , WebFlux , Observability , Batch .
senior
Copy sheet
AOP — JDK vs CGLIB proxy
JDK dynamic proxy CGLIB subclass
Requires Interface Concrete class (non-final)
Used when Bean implements interface(s) No interface or forced CGLIB
Self-invocation Internal 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
Operator Use
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 WebFlux Choose MVC (+ vthreads)
Streaming SSE / NDJSON CRUD + JPA
Backpressure end-to-end Team knows blocking stack
R2DBC / reactive drivers throughout Java 21 spring.threads.virtual.enabled=true
High fan-out slow I/O composition Complex ORM graphs
Observability — Micrometer meters
Meter API
Counter registry.counter("orders.created", "channel", "web").increment()
Timer registry.timer("checkout").record(() -> { ... })
Gauge registry.gauge("queue.size", atomicInteger)
DistributionSummary registry.summary("payload.bytes").record(n)
Prometheus GET /actuator/prometheus
Tag rule Low cardinality only — no userId/orderId in labels
Distributed tracing (Boot 3)
Item Detail
API Micrometer Tracing (replaces Sleuth)
Brave bridge Zipkin export — management.zipkin.tracing.endpoint
OTel bridge management.otlp.tracing.endpoint
Sampling management.tracing.sampling.probability: 0.1
Propagation W3C traceparent header
Baggage management.tracing.baggage.remote-fields — small, no PII
Logs MDC traceId / spanId correlation
Logging & MDC production
Practice Implementation
Structured JSON logstash-logback-encoder in prod profile
MDC fields requestId, userId, traceId
Async appender AsyncAppender — don't block request thread
Config file logback-spring.xml + <springProfile>
Levels INFO prod; DEBUG per-package temporarily
Kubernetes health & shutdown
Endpoint / config Purpose
/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)
Custom HealthIndicator for DB, Redis, partners
Testcontainers & integration
Pattern Snippet
Static container static @Container PostgreSQLContainer
Properties @DynamicPropertySource or @ServiceConnection (Boot 3.1+)
WireMock @WireMockTest — stub external HTTP
Context cache Same slice config reuses context — avoid unique @MockBean sets
@DirtiesContextUse sparingly — busts cache, slow CI
Spring Batch — parallelism & ops
Feature When
Partitioning Large table — split ID ranges across workers
Chunk size Tune 100–500; align with JDBC batch
JobRepository BATCH_* tables — backup & archive old runs
Restart Failed job resumes from last committed chunk
Schedule @Scheduled or K8s CronJob — not on startup
Auto-configuration debugging
Action Command / flag
Conditions report --debug or logging.level.org.springframework.boot.autoconfigure=DEBUG
Exclude auto-config @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
Startup timeline spring-boot-starter-actuator + startup endpoint (Boot 2.4+)
Bean override Define your own @Bean — @ConditionalOnMissingBean backs off
Interview rapid-fire
Question One-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