Backend development: Java

Sefism.

Chapter 01

Java and Spring Boot essentials

Modern Java features and how Spring Boot wires an application together, from beans to builds.

Spring beans and dependency injection

Also called DI, IoC, Spring Boot

What
Spring creates objects (beans) for classes annotated @Service, @Repository or @RestController and passes their dependencies through the constructor. Spring Boot adds auto-configuration and starters.
Why
Classes ask for what they need instead of building it, so you can swap real implementations for fakes in tests and configure everything in one place.
Java
@Service
class OrderService {
  private final OrderRepository orders;
  private final PaymentClient payments;

  OrderService(OrderRepository orders, PaymentClient payments) {
    this.orders = orders;
    this.payments = payments;
  }
}

Watch out

Field injection with @Autowired on private fields: it hides dependencies and makes plain unit tests awkward.

Records

Also called record, DTO

What
A record is a compact, immutable data class: the compiler writes the constructor, accessors, equals, hashCode and toString. A compact constructor can validate fields.
Why
Ideal for request and response DTOs, events and value objects, with far less boilerplate than a classic class.
Java
public record UserDto(long id, String email, String name) {
  public UserDto {
    Objects.requireNonNull(email, "email");
  }
}

Watch out

Using records as JPA entities: entities need a no-args constructor and mutable state, which records do not have.

Virtual threads

Also called Project Loom

What
Lightweight threads managed by the JVM (Java 21+). Millions can exist, and a blocked virtual thread frees its carrier OS thread while it waits on I/O.
Why
Blocking, easy-to-read code scales like async code for I/O-heavy services. Spring Boot switches its request handling to virtual threads with one property.
YAML
spring:
  threads:
    virtual:
      enabled: true

Watch out

Expecting more throughput when the real limit is a pool of 10 database connections or CPU-bound work.

Exceptions and @RestControllerAdvice

Also called ProblemDetail, @ExceptionHandler

What
A @RestControllerAdvice class maps exceptions thrown anywhere in controllers to HTTP responses. ProblemDetail builds the standard problem JSON body.
Why
One place turns domain errors into consistent status codes and bodies, so controllers stay short and clients see one error shape.
Java
@RestControllerAdvice
class ApiErrors {
  @ExceptionHandler(NotFoundException.class)
  ProblemDetail notFound(NotFoundException e) {
    return ProblemDetail.forStatusAndDetail(
      HttpStatus.NOT_FOUND, e.getMessage());
  }
}

Watch out

Catching Exception and returning its message, which leaks stack details to the client.

Maven and Gradle builds

Also called Maven, Gradle, pom.xml

What
Build tools that download dependencies, compile, run tests and package the app as a runnable JAR. The wrapper scripts (mvnw, gradlew) pin the tool version.
Why
Everyone and every CI run builds the same way. Spring Boot plugins add bootRun and a fat JAR that contains all dependencies.
Shell
./mvnw spring-boot:run
./mvnw test
./mvnw package          # target/app.jar

./gradlew bootRun
./gradlew build

Watch out

Declaring versions for libraries Spring Boot already manages, which breaks its tested version set.

Java basics: types, classes and objects

Also called class, object, equals

What
Java is statically typed. Primitives such as int and boolean hold values, while everything else is an object reached through a reference. Classes define fields and methods, and var infers a local variable's type.
Why
Spring code is classes all the way down, and knowing references, equals versus == and access modifiers prevents the most common beginner bugs.
Java
public class Order {
    private final long id;
    private final int totalPence;

    public Order(long id, int totalPence) {
        this.id = id;
        this.totalPence = totalPence;
    }
    public long id() { return id; }
}
var a = "hi"; var b = new String("hi");
a.equals(b); // true, but a == b is false

Watch out

Comparing strings or boxed numbers with ==, which compares references, not values.

Java collections

Also called List, Map, Set, ArrayList, HashMap

What
The Collections Framework gives the List, Map and Set interfaces with implementations such as ArrayList, HashMap and HashSet, plus streams for filtering and mapping.
Why
Almost every service method moves data through these, and choosing the right one decides both correctness and speed.
Java
List<Order> orders = new ArrayList<>();
Map<Long, Order> byId = new HashMap<>();
for (Order o : orders) byId.put(o.id(), o);

List<Long> ids = orders.stream()
    .filter(o -> o.totalPence() > 5000)
    .map(Order::id)
    .toList();

List<String> fixed = List.of("a", "b"); // immutable

Watch out

Removing items from a list inside a for-each loop, which throws ConcurrentModificationException.

01 · Java and Spring Boot essentials1 / 10