Skip to content

Spring Boot — cheat sheet

Mandatory. Source: roadmap.md section "Spring Boot > Basics".

Maven

  • Library vs framework: a library is code you call; a framework calls your code (inversion of control) and dictates the overall structure of your app.
  • Package/dependency: external code your project relies on.
  • Package/dependency manager: tool that declares, downloads, and resolves versions (including transitive dependencies) for you. The two main ones for Java: Maven and Gradle.
  • pom.xml: Maven's project file — dependencies, plugins, build config, metadata.
    • Add a dependency: add a <dependency> block (groupId/artifactId/version).
    • Remove one: delete that block.
    • After changing it: reload/re-import the Maven project in IntelliJ (the little Maven refresh icon, or right-click pom.xml → Maven → Reload Project).

Serving HTML / Thymeleaf

  • Templating engine (Thymeleaf): lets you embed dynamic (server-side) data into HTML before it's sent to the browser — useful for SSR pages without a separate frontend app.
  • Static assets (CSS/JS/images) go in resources/static; templates go in resources/templates.

Dependency injection & Spring basics

  • DI in plain Java: a pattern where an object's dependencies are handed to it from outside (usually via constructor) instead of it creating them itself. Improves testability (swap real implementations for mocks) and decoupling.
  • Spring's basic idea: a container manages your objects' lifecycle and wires their dependencies together for you, based on annotations/config, instead of you doing new everywhere.
    • Bean: an object instantiated/managed/wired by the Spring container.
    • Application Context: the IoC container itself — holds all beans and their dependency graph, built at startup.
  • Constructor injection: Spring sees a class is a bean, inspects its constructor, and automatically supplies the other beans it needs as arguments.
  • @Autowired: tells Spring "inject this dependency here". Not required for constructor injection if there's exactly one constructor (implicit since Spring 4.3). Can also go on fields or setters, though field injection is generally discouraged (hides dependencies, harder to unit test without Spring).

REST controller, in-memory repo

  • @RestController: combines @Controller + @ResponseBody — methods return data that gets serialized straight to JSON, no view/template involved.
    • Lombok: annotation processor that generates boilerplate (getters/setters, constructors, equals/hashCode/toString) at compile time (@Data, @Getter, ...).
    • @GetMapping / @PostMapping: map HTTP GET/POST to a controller method.
  • @Repository: marks a data-access-layer bean; also enables Spring's DB exception translation.
    • findAll / findById / deleteById / save mirror the shape of Spring Data's own repository interfaces — good to have written them by hand once.
    • @PathVariable: pulls a value out of the URL path (/posts/{id}) into a parameter.
    • @PutMapping / @DeleteMapping: map PUT/DELETE for update/delete endpoints.

Layered architecture & MVC

  • Layers, top to bottom, with an example method each:
    • Presentation/Controller — handles HTTP in/out. E.g. PostController.getPost(id).
    • Service — business logic/rules. E.g. PostService.allPublished().
    • Repository/Data access — talks to the DB. E.g. PostRepository.save(post).
    • Model/Domain — the data structures themselves. E.g. the Post class.
  • MVC:
    • Model — the data/state, e.g. the Post entity.
    • View — what gets rendered, e.g. a Thymeleaf template or a JSON response body.
    • Controller — handles input and coordinates Model and View, e.g. a @Controller method returning a ModelAndView.
    • @Component: the generic "this is a Spring-managed bean" stereotype.
    • @Controller / @Service / @Repository: specializations of @Component that communicate intent and add layer-specific behavior (@Controller handles web requests/views, @Repository adds DB exception translation). Functionally all beans, semantically different roles.
    • MVC maps onto the layered architecture: Controller = presentation layer, Service = business layer, Model + Repository = data layer.

Service layer

  • Example: PostService.allPublished() — filters posts where !isDraft && publishedDate.isBefore(now), sorted descending by publishedDate.
  • Why put this in a service instead of the controller or repository: keeps business logic out of the controller (which should stay thin/HTTP-focused) and out of the repository (which should stay a dumb persistence layer) — separation of concerns.

Monolith vs microservices

  • Monolith: the whole app (all features/layers) is built and deployed as one unit. Simpler to develop, deploy, and debug early on.
  • Microservices: the app is split into small, independently deployable services that talk over the network (HTTP/messaging), usually each owning its own data store. Scales and deploys independently, at the cost of operational complexity (network calls, distributed data, service discovery, etc.).