<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Day 1: Spring Boot Basics · Learn Spring Boot 4</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/index.html</link><description>The core ideas: beans, configuration, REST controllers, validation, database access, calling other services and testing all of it.</description><generator>Hugo</generator><language>en</language><atom:link href="https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/index.xml" rel="self" type="application/rss+xml"/><item><title>Why Spring Boot?</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/01-why-spring/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/01-why-spring/index.html</guid><description>The problem it solves Plain Java gives you a language, not an application. A service needs an HTTP server, JSON mapping, a connection pool, transactions, config per environment, health checks, metrics and tests. Spring Boot wires all of that from a dependency list and sensible defaults.
@RestController class Api { @GetMapping("/ping") String ping() { return "pong"; } } One dependency and four lines is a running HTTP service.</description></item><item><title>Beans &amp; Dependency Injection</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/02-beans-di/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/02-beans-di/index.html</guid><description>What a bean is A bean is an object the container creates, configures and hands out. You never call new on it yourself.
@Service public class GreetingService { public String greet(String name) { return "Hello, " + name + "!"; } } Stereotype Meaning @Component any bean @Service business logic @Repository data access (adds exception translation) @RestController web endpoint returning data @Configuration class that declares @Bean methods All four of the first are @Component underneath — the name documents intent.</description></item><item><title>Configuration &amp; Profiles</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/03-configuration/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/03-configuration/index.html</guid><description>Where values come from Spring reads many sources and lets later ones win:
command line — --server.port=9000 environment variables — SERVER_PORT=9000 application-{profile}.properties application.properties defaults in code java -jar app.jar --server.port=9000 SERVER_PORT=9000 java -jar app.jar Relaxed binding maps server.port, SERVER_PORT and server-port to the same property.
Reading single values @Component class Mailer { private final String from; Mailer(@Value("${app.mail.from:noreply@example.com}") String from) { this.from = from; } } The part after : is the default.</description></item><item><title>REST Controllers</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/04-rest-controllers/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/04-rest-controllers/index.html</guid><description>Mapping requests @RestController @RequestMapping("/api/books") public class BookController { @GetMapping List&lt;Book&gt; all() { … } @GetMapping("/{id}") Book one(@PathVariable long id) { … } @PostMapping Book create(@RequestBody Book b) { … } @PutMapping("/{id}") Book replace(@PathVariable long id, @RequestBody Book b) { … } @DeleteMapping("/{id}") void delete(@PathVariable long id) { … } } @RestController = @Controller + @ResponseBody: return values are serialized, not resolved as view names.</description></item><item><title>Validation &amp; Error Handling</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/05-validation-errors/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/05-validation-errors/index.html</guid><description>Bean validation Add spring-boot-starter-validation, annotate the DTO, and mark the parameter @Valid.
public record BookRequest( @NotBlank String title, @NotBlank @Size(max = 100) String author, @Min(1450) @Max(2100) int year, @Email String contact) {} @PostMapping BookResponse create(@Valid @RequestBody BookRequest req) { … } A violation throws MethodArgumentNotValidException → 400 before your method runs.</description></item><item><title>Data Access with JPA</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/06-data-jpa/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/06-data-jpa/index.html</guid><description>Setup &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.h2database&lt;/groupId&gt; &lt;artifactId&gt;h2&lt;/artifactId&gt; &lt;scope&gt;runtime&lt;/scope&gt; &lt;/dependency&gt; With H2 on the classpath and no spring.datasource.url, Boot configures an in-memory database. For PostgreSQL:
spring.datasource.url=jdbc:postgresql://localhost:5432/demo spring.datasource.username=demo spring.datasource.password=${DB_PASSWORD} spring.jpa.hibernate.ddl-auto=validate An entity @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String title; private String author; private int year; protected Book() {} // required by JPA public Book(String title, String author, int year) { … } // getters, and setters only where they make sense } Warning Entities are mutable objects tied to a persistence context — not DTOs. Records cannot be entities. Map to a record before returning data from a controller.</description></item><item><title>Calling Other Services</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/07-http-clients/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/07-http-clients/index.html</guid><description>RestClient The synchronous client since Spring 6.1 — fluent, blocking, the default choice in MVC apps.
@Configuration class ClientConfig { @Bean RestClient booksClient(RestClient.Builder builder) { return builder.baseUrl("https://api.example.com").build(); } } Book book = client.get() .uri("/books/{id}", id) .retrieve() .body(Book.class); List&lt;Book&gt; all = client.get() .uri("/books?author={a}", author) .retrieve() .body(new ParameterizedTypeReference&lt;&gt;() {}); Book created = client.post() .uri("/books") .contentType(MediaType.APPLICATION_JSON) .body(new BookRequest("Dune", "Herbert", 1965)) .retrieve() .body(Book.class); Handling failures:</description></item><item><title>Testing</title><link>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/08-testing/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://learn-spring-boot-4.pages.dev/02-spring-boot-basics/08-testing/index.html</guid><description>The starter spring-boot-starter-test is in every generated project and brings JUnit 5, AssertJ, Mockito, JSONassert and the Spring test support.
./mvnw test Plain unit tests Constructor injection means most classes need no Spring at all.
class GreetingServiceTest { private final GreetingService service = new GreetingService(); @Test void greetsByName() { assertThat(service.greet("Ann")).isEqualTo("Hello, Ann!"); } } Fast, and where the bulk of your tests should live.</description></item></channel></rss>