Prev Next

Spring / Spring Boot 4 Basics Interview Questions

1. What is Spring Boot 4 and when was it released? 2. What is the complete modularisation of Spring Boot 4 and why does it matter? 3. What is the Java version baseline in Spring Boot 4 and what Java features does it unlock? 4. What is Jakarta EE 11 and what changes does it bring in Spring Boot 4? 5. How does Spring Boot 4 auto-configuration work and what is the new @AutoConfiguration annotation? 6. What is native API versioning in Spring Boot 4 and how do you use it? 7. What are JSpecify nullability annotations in Spring Boot 4 and why are they important? 8. What changed with Jackson in Spring Boot 4 and what are the migration considerations? 9. What are @Retryable and @ConcurrencyLimit in Spring Boot 4 and how do they work? 10. What are HTTP Service Clients in Spring Boot 4 and how do you define them? 11. What are the key breaking changes removed in Spring Boot 4 that were deprecated in Boot 3? 12. How does Spring Boot 4 handle dependency injection and what are the core stereotypes? 13. What is Spring Boot's application.properties / application.yml and how does configuration work? 14. What are Spring Boot profiles and how do you use them for environment-specific configuration? 15. How does Spring Boot 4 testing work with @SpringBootTest and test slices? 16. What is Spring Boot Actuator and what does it provide in Boot 4? 17. How does Spring Boot 4 handle data access with Spring Data JPA? 18. What is Spring Security in Spring Boot 4 and what are the key Boot 4 changes? 19. What is the Spring Boot starter parent (POM) and how do you set up a Spring Boot 4 project? 20. What is @SpringBootApplication and what does it combine? 21. How do you build REST APIs with Spring Boot 4 using @RestController? 22. How does Bean Validation work with Spring Boot 4? 23. What is Spring Boot's embedded server and how do you configure it? 24. What is Spring Boot's transaction management with @Transactional? 25. What is Spring Boot's caching abstraction and how do you use it? 26. What is Spring Boot's observability stack in Boot 4 with Micrometer and OpenTelemetry? 27. How does Spring Boot 4 support GraalVM native images? 28. What is Spring WebFlux and reactive programming in Spring Boot 4? 29. What is Spring Boot's exception handling with @RestControllerAdvice? 30. How do you use Spring Data MongoDB and other NoSQL stores in Spring Boot 4? 31. How does Spring Boot 4 handle async processing with @Async? 32. What is Spring Boot's externalized configuration with @Value and @ConfigurationProperties? 33. What is Spring Boot's messaging support with Kafka in Boot 4? 34. How do you schedule tasks in Spring Boot 4 with @Scheduled? 35. What is Spring AI and how does it integrate with Spring Boot 4? 36. How does Spring Boot 4 handle logging configuration? 37. What is Spring Boot 4 migration from Boot 3: complete checklist and common pitfalls? 38. What is Spring Boot DevTools and how does it improve development productivity? 39. How does Spring Boot 4 support containerised deployments with Docker? 40. What is the Spring Boot 4 vs Spring Boot 3 comparison and what are the key takeaways?
Could not find what you were looking for? send us the question and we would be happy to answer your question.

1. What is Spring Boot 4 and when was it released?

Spring Boot 4.0 was released on November 20, 2025, making it the most structurally significant Spring release since the move to Jakarta EE in Spring Boot 3.0 (2022). Spring Boot 4.1 followed on June 10, 2026 and is the current recommended version for new projects.

Spring Boot 4 is described by the Spring team as the beginning of a new generation -- not an incremental update but a genuine architectural shift built on top of Spring Framework 7 and Jakarta EE 11.

Spring Boot 4 at a glance
PropertyDetail
GA releaseNovember 20, 2025 (4.0.0)
Latest stable4.1.0 (June 10, 2026)
Underlying frameworkSpring Framework 7
Jakarta EE baselineJakarta EE 11 (Servlet 6.1, Persistence 3.2, Validation 3.1)
Minimum JavaJava 17
First-class Java supportJava 25
Minimum KotlinKotlin 2.2
Recommended for new projectsSpring Boot 4.1

Key headlines:

  • Complete modularisation into 70+ focused JARs
  • Native API versioning in Spring MVC and WebFlux
  • JSpecify null safety across the entire portfolio
  • Jackson 3 is the new JSON library (Jackson 2 removed)
  • JUnit 4 removed entirely
  • Undertow removed (no Servlet 6.1 support)
  • Built-in retry and concurrency limits via @Retryable and @ConcurrencyLimit
When was Spring Boot 4.0 released as GA?
Which underlying framework version does Spring Boot 4 build on?

2. What is the complete modularisation of Spring Boot 4 and why does it matter?

One of the most architecturally significant changes in Spring Boot 4 is the complete modularisation of the codebase into 70+ focused JAR modules. Previously, the two monolithic JARs -- spring-boot-autoconfigure and spring-boot-test-autoconfigure -- contained auto-configuration for every supported technology regardless of what your project actually used.

Why it matters:

  • Smaller application footprint -- you only include modules for technologies you actually use
  • Faster builds and startup times -- less classpath scanning and fewer classes to load
  • Better GraalVM native images -- smaller reachability surface means smaller native binaries
  • Cleaner IDE auto-complete -- no longer suggests classes from libraries you haven't included
  • Clearer dependency management -- easier to reason about what is on the classpath and why
Starter naming changes (examples)
Spring Boot 3Spring Boot 4What it contains
spring-boot-starter-webspring-boot-starter-webmvcSpring MVC + Tomcat
spring-boot-starter-webspring-boot-starter-webfluxWebFlux (if reactive)
spring-boot-autoconfigure (monolith)70+ focused modulesOne module per technology
spring-boot-test-autoconfigure (monolith)spring-boot-starter-webmvc-test etc.Test slices per technology
<!-- Spring Boot 3 (monolithic starter) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot 4 (modular starters) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jackson</artifactId>
</dependency>

<!-- For gradual migration: classic starters bridge the gap -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-classic</artifactId>  <!-- bundles old behaviour -->
</dependency>

How many focused JAR modules does Spring Boot 4 modularise into?
What is the purpose of spring-boot-starter-classic in Spring Boot 4?

3. What is the Java version baseline in Spring Boot 4 and what Java features does it unlock?

Spring Boot 4 maintains Java 17 as the minimum baseline while adding first-class support for Java 25. The decision to keep Java 17 as the minimum was deliberate -- as Spring Framework project lead Juergen Hoeller stated, "the current industry consensus is clearly around a Java 17 baseline."

Java compatibility in Spring Boot 4
Java versionSupport levelNotable features
Java 17Minimum requiredText blocks, records, sealed classes, pattern matching preview
Java 21Strongly recommendedVirtual threads (stable), structured concurrency (preview), sequenced collections
Java 25First-class, testedAOT compilation improvements, GraalVM native optimisations, vector API incubator
Java 26Supported in Boot 4.1Structured concurrency (preview), further platform improvements
# application.properties -- enable virtual threads (Java 21+)
spring.threads.virtual.enabled=true
# When enabled, Spring Boot optimises internal task executors
# to use lightweight virtual threads instead of platform threads
# Making blocking code perform like reactive code without complexity

# GraalVM native image in Spring Boot 4 requires:
# GraalVM native-image version 25 or later
# Build native image:
# ./mvnw -Pnative native:compile
# ./gradlew nativeCompile

Virtual threads and Spring Boot 4: with spring.threads.virtual.enabled=true, the framework automatically switches internal Tomcat thread pools, Spring MVC request handling, and @Async executors to use Java virtual threads. This delivers near-reactive throughput for blocking I/O code without requiring reactive programming paradigms.

What is the minimum Java version required by Spring Boot 4?
What does setting spring.threads.virtual.enabled=true do in Spring Boot 4?

4. What is Jakarta EE 11 and what changes does it bring in Spring Boot 4?

Spring Boot 4 moves the Jakarta EE baseline from version 9/10 (used in Boot 3.x) to Jakarta EE 11. This brings updated specifications for persistence, validation, servlets, and WebSockets.

Jakarta EE 11 specification versions in Spring Boot 4
SpecificationVersionKey changes
Jakarta Servlet6.1Required by Spring Boot 4; Undertow incompatible (removed)
Jakarta Persistence (JPA)3.2Detached entities no longer silently reassociated; stricter persistence context rules
Jakarta Bean Validation3.1Improved constraint validation and messaging
Jakarta WebSocket2.2Updated WebSocket API
Hibernate ORM7.1Managed version; stricter detached entity behaviour
// All javax.* imports from Spring Boot 2.x are gone in Boot 4
// They must be jakarta.* (this was also true in Boot 3 but Boot 4 enforces it)

// WRONG (will not compile in Boot 4):
import javax.persistence.Entity;
import javax.validation.constraints.NotNull;
import javax.servlet.http.HttpServletRequest;

// CORRECT:
import jakarta.persistence.Entity;
import jakarta.validation.constraints.NotNull;
import jakarta.servlet.http.HttpServletRequest;

// The OpenRewrite recipe handles automated migration:
// Migrate_To_Jakarta_EE_10 recipe covers remaining javax.* -> jakarta.*

// Hibernate 7.1 breaking change: detached entities
// Boot 3: silently reassociated (lenient)
// Boot 4: throws exception if you try to persist a detached entity without explicit merge
@Transactional
public void updateOrder(Order detachedOrder) {
    // Boot 3: orderRepo.save(detachedOrder) might silently merge
    // Boot 4: be explicit:
    orderRepo.save(entityManager.merge(detachedOrder));
}

Critical breaking change: Undertow has been removed entirely from Spring Boot 4 because it is not yet compatible with Servlet 6.1. Any application using Undertow as its embedded container must migrate to Tomcat 11 or Jetty 12.1 before upgrading to Spring Boot 4.

Why was Undertow removed from Spring Boot 4?
What Hibernate ORM version does Spring Boot 4 manage, and what is its key breaking change?

5. How does Spring Boot 4 auto-configuration work and what is the new @AutoConfiguration annotation?

Spring Boot's auto-configuration mechanism has been refined in version 4. The core concept remains: Spring Boot detects libraries on your classpath and automatically configures beans accordingly -- but the implementation is now spread across 70+ modules rather than a single monolithic JAR.

// Spring Boot 4 auto-configuration mechanics:

// 1. Conditional annotations still drive auto-configuration:
@AutoConfiguration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public DataSource dataSource(DataSourceProperties props) {
        return props.initializeDataSourceBuilder().build();
    }
}

// 2. Registration is now in META-INF/spring/
//    org.springframework.boot.autoconfigure.AutoConfiguration.imports
//    (replaces META-INF/spring.factories from Spring Boot 2)

// 3. @SpringBootApplication still enables component scanning
//    and auto-configuration:
@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

// 4. Exclude specific auto-configuration:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class NoDbApp { ... }

// 5. Conditional annotations reference:
// @ConditionalOnClass    - class is on classpath
// @ConditionalOnMissingBean - no bean of this type
// @ConditionalOnProperty - property is set
// @ConditionalOnWebApplication - is a web app
// @ConditionalOnExpression  - SpEL expression is true

Key change from Boot 3: the @AutoConfiguration annotation (introduced in Boot 2.7) is now the standard approach. It replaces the older pattern of annotating auto-configuration classes with plain @Configuration plus a @ConditionalOn*. The @AutoConfiguration annotation also sets proxyBeanMethods=false by default for better performance in Boot 4's modular world.

Where does Spring Boot 4 register auto-configuration classes? (replacing the old spring.factories mechanism)
What does @ConditionalOnMissingBean do in a Spring Boot auto-configuration class?

6. What is native API versioning in Spring Boot 4 and how do you use it?

API versioning has historically been one of the most DIY aspects of Spring development -- teams built custom URL paths, header filters, or RequestCondition hacks. Spring Framework 7 (and Spring Boot 4) makes API versioning a first-class feature with native annotation-based support in both Spring MVC and WebFlux.

Supported versioning strategies
StrategyExampleConfiguration
Path-basedGET /api/v1/orders, GET /api/v2/ordersspring.mvc.apiversion.use-path=true
Header-basedX-API-Version: 1spring.mvc.apiversion.use-header=X-API-Version
Query parameterGET /orders?version=1spring.mvc.apiversion.use-param=version
Media type (Accept header)Accept: application/json;version=1spring.mvc.apiversion.use-media-type=true
// Spring Boot 3: manual versioning (repetitive and fragile)
@RestController
@RequestMapping("/api/v1/products")
public class ProductControllerV1 { ... }

@RestController
@RequestMapping("/api/v2/products")
public class ProductControllerV2 { ... }

// Spring Boot 4: native versioning
@RestController
@RequestMapping("/api/products")
public class ProductController {

    @GetMapping(path = "/{id}", version = "1.0")
    public ProductV1 getProductV1(@PathVariable String id) {
        return productService.findV1(id);
    }

    @GetMapping(path = "/{id}", version = "2.0")
    public ProductV2 getProductV2(@PathVariable String id) {
        return productService.findV2(id);
    }
}

// Configuration in application.properties:
# Header-based versioning:
spring.mvc.apiversion.use-header=X-API-Version
spring.mvc.apiversion.default=1
# Request: GET /api/products/123 with header X-API-Version: 2
# Routes to: getProductV2

// Deprecation handling (RFC 9745 compliant):
@GetMapping(path = "/{id}", version = "1.0", deprecated = true)
public ProductV1 getProductV1(@PathVariable String id) {
    // Spring automatically adds Deprecation response header
    return productService.findV1(id);
}

RFC 9745 compliance: Spring Boot 4 automatically adds the Deprecation HTTP response header when a versioned endpoint is marked as deprecated, giving API consumers programmatic notification of deprecation without custom filter code.

In Spring Boot 4, what annotation attribute enables native API versioning on a @GetMapping?
What HTTP response header does Spring Boot 4 automatically add for deprecated versioned endpoints?

7. What are JSpecify nullability annotations in Spring Boot 4 and why are they important?

Spring Boot 4 adopts JSpecify annotations (@Nullable, @NonNull, @NullMarked) portfolio-wide, deprecating Spring's own org.springframework.lang annotations. JSpecify is a collaborative standard backed by Google, JetBrains, Broadcom (Spring), Uber, Oracle, and OpenJDK.

JSpecify annotations
AnnotationPackageMeaning
@NonNullorg.jspecify.annotationsThe element is never null; tooling enforces this contract
@Nullableorg.jspecify.annotationsThe element may be null; callers must handle null
@NullMarkedorg.jspecify.annotationsApplied at package/class level: all unannotated types are non-null by default
@NullUnmarkedorg.jspecify.annotationsOpts a scope back out of null-marked assumptions
// package-info.java: declare the whole package as null-safe
@NullMarked
package com.example.service;

import org.jspecify.annotations.NullMarked;

// Service class: unannotated types are non-null by default
@Service
public class OrderService {

    // Non-null by default (from @NullMarked)
    public Order createOrder(String productId, int quantity) {
        return new Order(productId, quantity);
    }

    // Explicitly mark where null is possible:
    public @Nullable Order findOrder(@Nullable String orderId) {
        if (orderId == null) return null;
        return orderRepository.findById(orderId).orElse(null);
    }
}

// Maven dependency:
<dependency>
    <groupId>org.jspecify</groupId>
    <artifactId>jspecify</artifactId>
    <!-- Version managed by Spring Boot 4 BOM -->
</dependency>

// Kotlin benefit: JSpecify annotations are automatically
// translated into Kotlin nullability by Kotlin 2.2 compiler
// val order: Order? = service.findOrder(null)  <- correct type
// val order: Order  = service.createOrder("p1", 2) <- non-null inferred

Tool support: IntelliJ IDEA 2025.3 ships first-class JSpecify support with full data-flow analysis. Build-time null checking via NullAway (requires JDK 21+) catches nullability violations at compile time. Previously fragmented null annotation libraries (Spring's own, JetBrains', FindBugs) are being consolidated around JSpecify.

Which organisation consortium backs the JSpecify null annotation standard?
What does @NullMarked at the package level accomplish in Spring Boot 4?

8. What changed with Jackson in Spring Boot 4 and what are the migration considerations?

Spring Boot 4 migrates from Jackson 2 to Jackson 3 as the primary JSON library. This is one of the highest-risk breaking changes for teams upgrading, because several serialisation behaviours change silently -- no compiler error, no deprecation warning, just different JSON output.

Jackson 2 vs Jackson 3 breaking changes
ChangeJackson 2 (Boot 3)Jackson 3 (Boot 4)
Package namespacecom.fasterxml.jacksontools.jackson
Group IDcom.fasterxml.jackson.coretools.jackson
Date serialisationTimestamps (epoch millis) by defaultISO-8601 strings by default (WRITE_DATES_AS_TIMESTAMPS=false)
Property orderingInsertion order by defaultAlphabetical by default (SORT_PROPERTIES_ALPHABETICALLY=true)
Null handlingConfigurableDefault changed; review null serialisation tests
// Jackson 3: package migration
// Old (Jackson 2 / Spring Boot 3):
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;

// New (Jackson 3 / Spring Boot 4):
import tools.jackson.databind.ObjectMapper;
import tools.jackson.annotation.JsonProperty;

// Date serialisation change:
// Jackson 2 default: {"createdAt": 1732099200000}
// Jackson 3 default: {"createdAt": "2025-11-20T10:00:00Z"}

// If your API clients expect timestamps, configure explicitly:
@Configuration
public class JacksonConfig {
    @Bean
    public Jackson3BuilderCustomizer timestampCustomizer() {
        return builder -> builder
            .featuresToEnable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS);
    }
}

// Automated migration using OpenRewrite:
// Run this recipe to handle package renames:
// org.openrewrite.java.jackson.UpgradeJackson_2_3
// mvn rewrite:run -Drewrite.activeRecipes=org.openrewrite.java.jackson.UpgradeJackson_2_3

// Property ordering change:
// Jackson 2: {"name":"Alice","id":"1","email":"a@b.com"}
// Jackson 3: {"email":"a@b.com","id":"1","name":"Alice"} <- alphabetical!
// Fix tests that compare exact JSON strings character by character

What silent breaking change in Jackson 3 is most likely to cause production incidents after migrating from Spring Boot 3?
What is the new Jackson 3 package namespace that replaces com.fasterxml.jackson?

9. What are @Retryable and @ConcurrencyLimit in Spring Boot 4 and how do they work?

Spring Boot 4 (via Spring Framework 7) brings built-in resilience patterns directly into the Spring context. Previously, retry required the separate spring-retry dependency plus @EnableRetry. Spring Boot 4 ships these capabilities as first-class features.

// Spring Boot 3 (required separate dependency + @EnableRetry):
// pom.xml: spring-retry dependency
// Config class: @EnableRetry
@Service
public class StockService {
    @Retryable(value = {NetworkException.class}, maxAttempts = 2)
    public void updateStock() { ... }
}

// Spring Boot 4: works out of the box with spring-boot-starter-resilience
// No @EnableRetry needed!
@Service
public class StockService {

    // Retry with exponential backoff and jitter
    @Retryable(
        includes  = NetworkException.class,  // exception types to retry on
        maxRetries = 3,                       // number of retry attempts
        backoff    = @Backoff(
            delay      = 500,                // initial delay in ms
            multiplier = 2.0,                // exponential multiplier
            random     = true                // add jitter
        )
    )
    public Order fetchOrderFromRemote(String orderId) {
        return remoteService.fetch(orderId); // automatically retried on NetworkException
    }

    // Bulkhead pattern: limit concurrent callers
    @ConcurrencyLimit(limit = 5)  // max 5 concurrent executions
    public void processPayment(Payment payment) {
        // Only 5 threads can execute this simultaneously
        // 6th caller blocks until one slot frees up
        paymentGateway.process(payment);
    }

    // Combining both:
    @Retryable(includes = NetworkException.class, maxRetries = 3)
    @ConcurrencyLimit(limit = 10)
    public void updateStock() {
        externalInventoryApi.update();
    }
}

@ConcurrencyLimit implements the Bulkhead pattern from resilience engineering. It is particularly valuable with virtual threads (Java 21+), where it prevents a burst of cheap virtual threads from overwhelming a downstream service with simultaneous requests.

What is the key improvement of @Retryable in Spring Boot 4 compared to Spring Boot 3?
What design pattern does @ConcurrencyLimit implement?

10. What are HTTP Service Clients in Spring Boot 4 and how do you define them?

HTTP Service Clients (also called declarative HTTP clients) allow you to define REST client interfaces using annotations, similar to Feign clients but built natively into Spring. Spring Boot 4 adds auto-configuration for @HttpExchange interfaces, making it easy to create and inject HTTP clients as Spring beans.

// Define a declarative HTTP client interface:
public interface ProductClient {

    @GetExchange("/api/products/{id}")
    ProductDto getProduct(@PathVariable String id);

    @GetExchange("/api/products")
    List<ProductDto> getAllProducts(
        @RequestParam int page,
        @RequestParam int size
    );

    @PostExchange("/api/products")
    ProductDto createProduct(@RequestBody CreateProductRequest request);

    @DeleteExchange("/api/products/{id}")
    void deleteProduct(@PathVariable String id);
}

// Spring Boot 4: auto-configuration via spring.http.clients.*
# application.properties:
spring.http.clients.product.base-url=https://products-api.example.com
spring.http.clients.product.connect-timeout=5s
spring.http.clients.product.read-timeout=10s

// Use it like any other Spring bean:
@Service
@RequiredArgsConstructor
public class OrderService {

    private final ProductClient productClient;  // injected automatically

    public Order createOrder(String productId, int qty) {
        ProductDto product = productClient.getProduct(productId);
        // ...
        return new Order(product, qty);
    }
}

// Manual configuration (without auto-config):
@Configuration
public class ClientConfig {
    @Bean
    public ProductClient productClient(RestClient.Builder builder) {
        return HttpServiceProxyFactory
            .builderFor(RestClientAdapter.create(
                builder.baseUrl("https://products-api.example.com").build()
            ))
            .build()
            .createClient(ProductClient.class);
    }
}

What is the purpose of HTTP Service Clients (@HttpExchange interfaces) in Spring Boot 4?
What Spring Boot 4 property namespace configures HTTP Service Client beans?

11. What are the key breaking changes removed in Spring Boot 4 that were deprecated in Boot 3?

Spring Boot 4 follows a strict deprecation policy: everything deprecated in Spring Boot 3.x is removed in 4.0 with no fallback. This is why the recommended migration path is to first upgrade to Boot 3.5 and fix all deprecation warnings before touching Boot 4.

Key removals in Spring Boot 4
What was removedCategoryReplacement
JUnit 4 supportTestingUse JUnit 5 (Jupiter) -- Boot 3 already required it
Undertow embedded serverWebTomcat 11 or Jetty 12.1
spring-boot-starter-web (monolithic)Modularisationspring-boot-starter-webmvc or spring-boot-starter-webflux
spring-boot-autoconfigure (monolith JAR)Modularisation70+ individual technology modules
javax.annotation / javax.inject supportJakarta EEjakarta.annotation / jakarta.inject
RestTemplate (discouraged)HTTP ClientRestClient or HTTP Service Client (@HttpExchange)
Old Actuator property prefixesObservabilityUpdated management.* property paths
AntPathMatcher for HTTP mappings (deprecated)MVCPathPatternParser (PathPattern-based matching)
spring.jackson2.* propertiesJSONspring.jackson.* (Jackson 3 config)
# WRONG (Boot 3 style, removed in Boot 4):
# spring.jackson2.serialization.write-dates-as-timestamps=false

# CORRECT (Boot 4):
spring.jackson.serialization.write-dates-as-timestamps=false

// Migration script check: find deprecated patterns
// Run OpenRewrite to automate many changes:
// mvn rewrite:run \
//   -Drewrite.activeRecipes=\
//     org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5,\
//     org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0

// RestTemplate to RestClient migration:
// Spring Boot 3 (discouraged):
RestTemplate rt = new RestTemplate();
String result = rt.getForObject("http://api/data", String.class);

// Spring Boot 4 (recommended):
RestClient client = RestClient.create();
String result = client
    .get()
    .uri("http://api/data")
    .retrieve()
    .body(String.class);

What is the recommended migration path before upgrading from Spring Boot 3.x to Spring Boot 4?
What replaced RestTemplate as the recommended synchronous HTTP client in Spring Boot 4?

12. How does Spring Boot 4 handle dependency injection and what are the core stereotypes?

Spring Boot 4 retains the same core dependency injection (DI) model as all previous Spring versions. The DI container, stereotype annotations, and bean lifecycle are unchanged -- Spring Boot 4's changes are at the infrastructure and ecosystem level, not the DI model itself.

Spring DI stereotype annotations
AnnotationUse caseSpecialisation of
@ComponentGeneric Spring-managed component(base)
@ServiceBusiness logic layer@Component
@RepositoryData access layer; translates persistence exceptions@Component
@ControllerSpring MVC controller (returns view names)@Component
@RestControllerREST API controller (returns response body)@Controller + @ResponseBody
@ConfigurationBean factory class@Component
// Constructor injection (recommended in Spring Boot 4)
@Service
public class OrderService {

    private final OrderRepository repo;
    private final ProductClient    client;
    private final EventPublisher   events;

    // Spring Boot 4 recommends constructor injection:
    // - Makes dependencies explicit
    // - Enables final fields (immutability)
    // - No @Autowired annotation needed on single-constructor classes
    public OrderService(
            OrderRepository repo,
            ProductClient   client,
            EventPublisher  events) {
        this.repo   = repo;
        this.client = client;
        this.events = events;
    }

    // With Lombok @RequiredArgsConstructor:
    // @Service
    // @RequiredArgsConstructor
    // public class OrderService {
    //     private final OrderRepository repo;
    //     private final ProductClient client;
    //     ...
    // }
}

// @Primary: preferred bean when multiple implementations exist
@Service
@Primary
public class DefaultOrderService implements OrderService { ... }

// @Qualifier: inject specific implementation by name
@Autowired
@Qualifier("premiumOrderService")
private OrderService orderService;

Which type of dependency injection is recommended in Spring Boot 4?
What is the difference between @Repository and @Component in Spring Boot 4?

13. What is Spring Boot's application.properties / application.yml and how does configuration work?

Spring Boot externalises application configuration through application.properties or application.yml files, environment variables, system properties, and more. The configuration property source hierarchy determines which value wins when the same key appears in multiple places.

Configuration property source priority (highest first)
PrioritySource
1 (highest)Command-line arguments (--server.port=8081)
2SPRING_APPLICATION_JSON environment variable
3OS environment variables
4application-{profile}.properties/yml (active profile)
5application.properties / application.yml
6 (lowest)@PropertySource annotations on @Configuration classes
# application.yml (YAML format - preferred for complex config)
server:
  port: 8080
  servlet:
    context-path: /api

spring:
  application:
    name: order-service
  datasource:
    url: jdbc:postgresql://localhost:5432/orders
    username: ${DB_USER}         # reference env variable
    password: ${DB_PASSWORD}
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false

# Bind to a typed configuration class:
# application.yml:
app:
  order:
    max-items: 50
    allowed-currencies: [USD, EUR, GBP]

// @ConfigurationProperties class:
@ConfigurationProperties(prefix = "app.order")
@Validated  // enables Bean Validation on the properties
public record OrderProperties(
    @Min(1) @Max(1000) int maxItems,
    @NotEmpty List<String> allowedCurrencies
) {}

// Register:
@SpringBootApplication
@EnableConfigurationProperties(OrderProperties.class)
public class App { ... }

// Inject:
@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderProperties props;
}

Which configuration source has the highest priority in Spring Boot 4?
What does @ConfigurationProperties do in Spring Boot 4?

14. What are Spring Boot profiles and how do you use them for environment-specific configuration?

Profiles allow different configuration to be activated based on the deployment environment (dev, test, staging, prod). Spring Boot supports profile-specific property files, conditional bean registration, and profile activation via environment variables.

# src/main/resources/application.yml (base config, always loaded)
spring:
  application:
    name: order-service

# src/main/resources/application-dev.yml (loaded only in "dev" profile)
spring:
  datasource:
    url: jdbc:h2:mem:devdb
    driver-class-name: org.h2.Driver
logging:
  level:
    root: DEBUG

# src/main/resources/application-prod.yml (loaded only in "prod" profile)
spring:
  datasource:
    url: jdbc:postgresql://prod-db:5432/orders
    username: ${DB_USER}
    password: ${DB_PASSWORD}
logging:
  level:
    root: WARN

# Activate a profile:
# 1. Environment variable:
export SPRING_PROFILES_ACTIVE=prod
# 2. JVM argument:
-Dspring.profiles.active=prod
# 3. application.properties:
# spring.profiles.active=dev

// Profile-conditional bean registration:
@Configuration
public class CacheConfig {

    @Bean
    @Profile("dev")     // Only in dev: simple in-memory cache
    public CacheManager devCache() {
        return new ConcurrentMapCacheManager();
    }

    @Bean
    @Profile("prod")    // Only in prod: Redis cache
    public CacheManager prodCache(RedisConnectionFactory factory) {
        return RedisCacheManager.create(factory);
    }
}

// Multi-profile documents in single yml file (using --- separator):
# application.yml:
spring:
  config:
    activate:
      on-profile: test
  datasource:
    url: jdbc:h2:mem:testdb

What file naming convention does Spring Boot use for profile-specific configuration?
How do you activate a Spring Boot profile via environment variable in a production deployment?

15. How does Spring Boot 4 testing work with @SpringBootTest and test slices?

Spring Boot 4 provides a rich testing support framework. @SpringBootTest loads the full application context for integration tests, while test slice annotations load only a subset of the context for focused, faster unit tests.

Spring Boot 4 test slice annotations
AnnotationLoadsUse case
@SpringBootTestFull application contextEnd-to-end integration tests
@WebMvcTestOnly MVC layer (controllers, filters)Test controllers without starting a server or database
@DataJpaTestOnly JPA/database layerTest repositories; uses in-memory H2 by default
@DataMongoTestOnly MongoDB layerTest MongoDB repositories
@RestClientTestOnly REST client componentsTest HTTP Service Clients
@JsonTestOnly JSON serialisation componentsTest Jackson serialisation/deserialisation
@WebFluxTestOnly WebFlux layerTest reactive controllers
// Integration test: full context
@SpringBootTest
@AutoConfigureMockMvc
class OrderControllerIntegrationTest {

    @Autowired MockMvc mockMvc;
    @Autowired ObjectMapper objectMapper;

    @Test
    void createOrder_returns201() throws Exception {
        mockMvc.perform(post("/api/orders")
            .contentType(MediaType.APPLICATION_JSON)
            .content(objectMapper.writeValueAsString(
                new CreateOrderRequest("product-1", 2))))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.id").isNotEmpty());
    }
}

// Slice test: only MVC layer (no database)
@WebMvcTest(OrderController.class)
class OrderControllerTest {

    @Autowired MockMvc mockMvc;
    @MockBean   OrderService service;  // mock the service

    @Test
    void getOrder_returns200() throws Exception {
        when(service.find("O-1")).thenReturn(new OrderDto("O-1", "PENDING"));
        mockMvc.perform(get("/api/orders/O-1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.status").value("PENDING"));
    }
}

// Spring Boot 4: RestTestClient replaces the choice between
// MockMvc and WebTestClient for most scenarios
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class OrderApiTest {
    @Autowired RestTestClient client;  // new in Spring Boot 4

    @Test
    void getOrders() {
        client.get().uri("/api/orders")
            .exchange()
            .expectStatus().isOk()
            .expectBodyList(OrderDto.class).hasSize(0);
    }
}

What is the advantage of using @WebMvcTest over @SpringBootTest for controller tests?
What new test client does Spring Boot 4 introduce that replaces the choice between MockMvc and WebTestClient?

16. What is Spring Boot Actuator and what does it provide in Boot 4?

Spring Boot Actuator adds production-ready monitoring and management endpoints to any Spring Boot application. In Boot 4, the observability story has been tightened around OpenTelemetry with dedicated configuration properties.

Key Actuator endpoints
EndpointHTTPWhat it shows
/actuator/healthGETApplication health status (UP/DOWN) and component health details
/actuator/infoGETApplication information (version, description, git commit)
/actuator/metricsGETMicrometer metrics (JVM, HTTP, database, custom)
/actuator/metrics/{name}GETIndividual metric with tags
/actuator/envGETAll environment properties and their sources
/actuator/beansGETAll Spring beans in the context
/actuator/mappingsGETAll @RequestMapping routes
/actuator/loggersGET/POSTGet and change log levels at runtime
/actuator/threaddumpGETJVM thread dump
/actuator/httptraceGETLast 100 HTTP request/response traces
# application.yml: Actuator configuration in Boot 4
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,loggers  # expose specific endpoints
        # include: "*"  # expose all (not recommended in production)
  endpoint:
    health:
      show-details: when-authorized
  opentelemetry:            # Boot 4: new OTel-specific config namespace
    resource-attributes:
      service.name: order-service
      service.version: "2.1.0"
  tracing:
    sampling:
      probability: 1.0  # 100% sampling in dev; reduce in prod

# Custom health indicator:
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        try {
            jdbcTemplate.queryForObject("SELECT 1", Integer.class);
            return Health.up()
                .withDetail("database", "reachable")
                .build();
        } catch (Exception e) {
            return Health.down()
                .withDetail("error", e.getMessage())
                .build();
        }
    }
}

What does the /actuator/health endpoint return in Spring Boot 4?
What new Actuator configuration namespace does Spring Boot 4 introduce for OpenTelemetry?

17. How does Spring Boot 4 handle data access with Spring Data JPA?

Spring Boot 4 auto-configures Spring Data JPA when spring-boot-starter-data-jpa (or its modular equivalent) is on the classpath. With Hibernate 7.1 as the managed ORM and Jakarta Persistence 3.2, there are some important behavioural changes from Boot 3.

// Entity class (Jakarta Persistence 3.2)
import jakarta.persistence.*;  // NOT javax.persistence in Boot 4

@Entity
@Table(name = "orders")
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String productId;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;

    // Constructors, getters, setters...
}

// Repository interface: Spring Data handles implementation
public interface OrderRepository extends JpaRepository<Order, Long> {

    // Method name query derivation:
    List<Order> findByStatus(OrderStatus status);
    List<Order> findByProductIdAndStatus(String productId, OrderStatus status);
    Optional<Order> findFirstByProductIdOrderByCreatedAtDesc(String productId);

    // JPQL query:
    @Query("SELECT o FROM Order o WHERE o.status = :status AND o.total > :minTotal")
    List<Order> findHighValueByStatus(
        @Param("status") OrderStatus status,
        @Param("minTotal") BigDecimal minTotal
    );

    // Native SQL query:
    @Query(value = "SELECT * FROM orders WHERE status = ?1", nativeQuery = true)
    List<Order> findByStatusNative(String status);
}

# application.yml JPA configuration:
spring:
  jpa:
    hibernate:
      ddl-auto: validate     # validate, update, create, create-drop, none
    show-sql: false
    properties:
      hibernate:
        format_sql: true
        dialect: org.hibernate.dialect.PostgreSQLDialect

What import package must you use for JPA annotations in Spring Boot 4?
What does spring.jpa.hibernate.ddl-auto=validate do at startup?

18. What is Spring Security in Spring Boot 4 and what are the key Boot 4 changes?

Spring Boot 4 ships with Spring Security 7, which introduces multi-factor authentication (MFA) and important changes to default security configurations -- particularly CSRF protection defaults that can silently break REST APIs.

// Spring Boot 4 / Spring Security 7: SecurityFilterChain
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            // REST APIs: disable CSRF (Spring Security 7 default changed!)
            // Boot 3: CSRF enabled by default; REST APIs often disabled it
            // Boot 4 / Security 7: review CSRF defaults -- new SameSite-based protection
            .csrf(csrf -> csrf
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            )
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/actuator/health", "/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)  // for JWT/OAuth2
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt
                    .decoder(JwtDecoders.fromIssuerLocation(issuerUri))
                )
            );
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

// Spring Security 7: Multi-Factor Authentication
// MFA is now a first-class concept in the security model
// Configure in SecurityFilterChain with mfa() DSL
// Previously required custom implementations

Key Spring Security 7 change for Boot 4: Spring Security 7 changes some CSRF and session management defaults. Teams migrating from Boot 3 should review their SecurityFilterChain configurations carefully -- previously-passing REST API tests may fail if CSRF defaults behave differently.

What notable feature does Spring Security 7 (included in Spring Boot 4) introduce as a first-class concept?
Why might a REST API's integration tests start failing after upgrading to Spring Boot 4 / Spring Security 7?

19. What is the Spring Boot starter parent (POM) and how do you set up a Spring Boot 4 project?

The spring-boot-starter-parent POM sets sensible defaults for Maven builds: Java version, encoding, plugin versions, and dependency management via the Spring Boot BOM. It is the recommended way to start a Spring Boot project.

<!-- Maven: spring-boot-starter-parent -->
<project>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>4.1.0</version>  <!-- Spring Boot 4.1 (current) -->
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>order-service</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <java.version>17</java.version>  <!-- minimum for Boot 4 -->
    </properties>

    <dependencies>
        <!-- Spring Boot 4 modular starters -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>  <!-- includes JUnit 5 (Jupiter only in Boot 4) -->
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- builds executable JAR with embedded Tomcat -->
            </plugin>
        </plugins>
    </build>
</project>

What does using spring-boot-starter-parent as the Maven parent POM provide?
What does the spring-boot-maven-plugin produce when you run mvn package?

20. What is @SpringBootApplication and what does it combine?

@SpringBootApplication is a composed annotation that is the standard entry point for Spring Boot applications. It combines three key annotations that together enable auto-configuration, component scanning, and configuration capabilities.

// @SpringBootApplication = @SpringBootConfiguration
//                          + @EnableAutoConfiguration
//                          + @ComponentScan

@SpringBootApplication  // the one annotation to rule them all
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

// What each constituent annotation does:

// @SpringBootConfiguration: marks this as a Spring configuration class
// (specialisation of @Configuration)

// @EnableAutoConfiguration: tells Spring Boot to scan the classpath
// and auto-configure beans based on what is found
// e.g., finds spring-boot-starter-data-jpa -> auto-configures DataSource

// @ComponentScan: scans the current package and sub-packages
// for @Component, @Service, @Repository, @Controller, etc.
// Default: scans the package of the annotated class

// Customisations:
@SpringBootApplication(
    // exclude specific auto-configurations:
    exclude = {DataSourceAutoConfiguration.class},
    // scan additional packages:
    scanBasePackages = {"com.example.orders", "com.example.shared"}
)
public class App { ... }

// SpringApplication customisation in Boot 4:
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        var app = new SpringApplication(App.class);
        app.setBannerMode(Banner.Mode.OFF);  // disable ASCII art banner
        app.setLazyInitialization(true);     // lazy init for faster startup
        app.run(args);
    }
}

What three annotations does @SpringBootApplication combine?
What does @EnableAutoConfiguration do in Spring Boot 4?

21. How do you build REST APIs with Spring Boot 4 using @RestController?

Building REST APIs in Spring Boot 4 uses the same @RestController + @RequestMapping model as previous versions, but with native API versioning, improved validation integration, and better null safety via JSpecify.

import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
import org.jspecify.annotations.Nullable;

@RestController
@RequestMapping("/api/orders")
@Validated
public class OrderController {

    private final OrderService service;

    public OrderController(OrderService service) {
        this.service = service;
    }

    // GET all with pagination
    @GetMapping
    public Page<OrderDto> listOrders(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        return service.findAll(PageRequest.of(page, size));
    }

    // GET by ID
    @GetMapping("/{id}")
    public ResponseEntity<OrderDto> getOrder(@PathVariable String id) {
        return service.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }

    // POST: create new order
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public OrderDto createOrder(@Valid @RequestBody CreateOrderRequest request) {
        return service.create(request);
    }

    // PUT: full update
    @PutMapping("/{id}")
    public OrderDto updateOrder(
            @PathVariable String id,
            @Valid @RequestBody UpdateOrderRequest request) {
        return service.update(id, request);
    }

    // DELETE
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteOrder(@PathVariable String id) {
        service.delete(id);
    }

    // Native API versioning (Spring Boot 4):
    @GetMapping(path = "/{id}", version = "2.0")
    public OrderDtoV2 getOrderV2(@PathVariable String id) {
        return service.findByIdV2(id);
    }

    // Global exception handler:
    @ExceptionHandler(OrderNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorResponse handleNotFound(OrderNotFoundException ex) {
        return new ErrorResponse("ORDER_NOT_FOUND", ex.getMessage());
    }
}

What annotation combines @Controller and @ResponseBody to return JSON directly from handler methods?
What does @ResponseStatus(HttpStatus.CREATED) on a POST handler method do?

22. How does Bean Validation work with Spring Boot 4?

Spring Boot 4 auto-configures Jakarta Bean Validation 3.1 when spring-boot-starter-validation is on the classpath. Validation annotations on request bodies, path variables, and method parameters are enforced automatically.

// DTO with validation constraints:
public record CreateOrderRequest(
    @NotBlank(message = "Product ID is required")
    String productId,

    @Min(value = 1, message = "Quantity must be at least 1")
    @Max(value = 100, message = "Quantity cannot exceed 100")
    int quantity,

    @Email(message = "Invalid email address")
    @NotNull
    String customerEmail,

    @NotNull
    @Valid   // cascade validation into nested object
    AddressRequest shippingAddress
) {}

public record AddressRequest(
    @NotBlank String line1,
    @Nullable String line2,
    @NotBlank @Size(min=5, max=10) String postcode
) {}

// Controller: @Valid triggers validation before method body:
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public OrderDto createOrder(@Valid @RequestBody CreateOrderRequest request) {
    return service.create(request);
}

// Handle validation errors globally:
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String, String> handleValidation(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new LinkedHashMap<>();
        ex.getBindingResult().getFieldErrors()
            .forEach(err -> errors.put(err.getField(), err.getDefaultMessage()));
        return errors;
    }
}

// Service-level validation with @Validated:
@Service
@Validated  // enables method-level validation
public class OrderService {
    public Order getOrder(@NotBlank String id) {
        return repo.findById(id).orElseThrow();
    }
}

What annotation on a @RequestBody parameter triggers Bean Validation before the method body executes?
What exception is thrown when a @Valid @RequestBody fails Bean Validation in Spring Boot 4?

23. What is Spring Boot's embedded server and how do you configure it?

Spring Boot 4 ships with embedded web servers that start as part of the application JAR -- no external application server is needed. The supported embedded servers in Boot 4 are Tomcat 11 and Jetty 12.1 (Undertow was removed).

Embedded server options in Spring Boot 4
ServerStarterNotes
Tomcat 11spring-boot-starter-webmvc (default)Default; Servlet 6.1 compatible; most widely used
Jetty 12.1Exclude Tomcat, add jetty starterServlet 6.1 compatible; good for low-memory environments
UndertowREMOVED in Spring Boot 4Not compatible with Servlet 6.1
# Tomcat (default): no special configuration needed
# application.yml Tomcat tuning:
server:
  port: 8080
  servlet:
    context-path: /api
  tomcat:
    max-threads: 200
    min-spare-threads: 10
    connection-timeout: 20s
    keep-alive-timeout: 60s

# Switch from Tomcat to Jetty:
<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

# SSL / HTTPS configuration:
server:
  port: 8443
  ssl:
    enabled: true
    key-store: classpath:keystore.p12
    key-store-password: ${SSL_KEYSTORE_PASSWORD}
    key-store-type: PKCS12
    key-alias: my-app

# Virtual threads with Tomcat (Java 21+):
spring:
  threads:
    virtual:
      enabled: true
# Tomcat automatically uses virtual thread executor

Which embedded server was removed in Spring Boot 4 and why?
What does setting spring.threads.virtual.enabled=true do in Spring Boot 4 with an embedded Tomcat?

24. What is Spring Boot's transaction management with @Transactional?

Spring Boot 4 auto-configures transaction management when a data source is on the classpath. The @Transactional annotation declaratively wraps methods in a database transaction, with Spring AOP managing commit and rollback.

// Service with transaction management:
@Service
public class OrderService {

    private final OrderRepository orderRepo;
    private final InventoryRepository inventoryRepo;
    private final EventPublisher events;

    // Default: propagation=REQUIRED, isolation=DEFAULT, rollbackFor=RuntimeException
    @Transactional
    public Order placeOrder(CreateOrderRequest request) {
        // All operations in one transaction:
        Order order = orderRepo.save(new Order(request));
        inventoryRepo.reserveStock(request.productId(), request.quantity());
        events.publish(new OrderPlacedEvent(order.getId()));
        return order;
        // Commits on successful return
        // Rolls back on RuntimeException
    }

    // Read-only transaction (performance optimisation):
    @Transactional(readOnly = true)
    public Optional<Order> findById(String id) {
        return orderRepo.findById(id);
        // Hibernate skips dirty checking for read-only transactions
    }

    // Custom rollback rules:
    @Transactional(rollbackFor = {BusinessException.class, IOException.class})
    public void processPayment(String orderId) throws IOException {
        // Rolls back on checked IOException too
    }

    // Propagation types:
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void auditLog(String message) {
        // Always runs in its own NEW transaction,
        // suspending any existing outer transaction
        auditRepo.save(new AuditEntry(message));
    }
}

Key @Transactional propagation values
PropagationBehaviour
REQUIRED (default)Join existing transaction; create new if none
REQUIRES_NEWAlways create a new transaction; suspend existing
SUPPORTSJoin existing if present; run non-transactional if none
NOT_SUPPORTEDRun non-transactional; suspend existing
NEVERMust run non-transactionally; error if transaction exists
MANDATORYMust join existing; error if no transaction exists
What is the default rollback behaviour of @Transactional in Spring Boot 4?
What does @Transactional(readOnly = true) optimise in Spring Boot 4 with Hibernate?

25. What is Spring Boot's caching abstraction and how do you use it?

Spring Boot 4 provides a caching abstraction that decouples application code from specific cache implementations. Using @EnableCaching and method-level annotations, you can cache method results and evict them declaratively.

// Enable caching:
@SpringBootApplication
@EnableCaching
public class App { ... }

// Service with caching:
@Service
public class ProductService {

    // Cache the result by productId:
    @Cacheable(value = "products", key = "#productId")
    public ProductDto findById(String productId) {
        return productRepo.findById(productId)  // only called on cache miss
            .map(this::toDto)
            .orElseThrow();
    }

    // Update the cache after saving:
    @CachePut(value = "products", key = "#result.id")
    public ProductDto save(Product product) {
        Product saved = productRepo.save(product);
        return toDto(saved);  // returns updated value AND updates cache
    }

    // Evict from cache on delete:
    @CacheEvict(value = "products", key = "#productId")
    public void delete(String productId) {
        productRepo.deleteById(productId);
    }

    // Evict all cache entries:
    @CacheEvict(value = "products", allEntries = true)
    public void clearAll() { }
}

# Configuring the cache provider in application.yml:
# Simple (in-memory, default when no other cache is configured):
spring:
  cache:
    type: simple

# Redis cache:
spring:
  cache:
    type: redis
    redis:
      time-to-live: 600s
  data:
    redis:
      host: localhost
      port: 6379

# Caffeine (high-performance in-memory):
spring:
  cache:
    type: caffeine
    caffeine:
      spec: maximumSize=1000,expireAfterWrite=300s

What is the difference between @Cacheable and @CachePut in Spring Boot 4?
What annotation enables Spring Boot's caching abstraction?

26. What is Spring Boot's observability stack in Boot 4 with Micrometer and OpenTelemetry?

Spring Boot 4 builds observability around Micrometer (metrics), Micrometer Tracing (distributed tracing), and OpenTelemetry (standard telemetry export). The management.opentelemetry.* property namespace is new in Boot 4.

Observability pillars in Spring Boot 4
PillarLibraryWhat it tracks
MetricsMicrometerHTTP request rates, JVM heap, GC, custom counters/gauges
TracingMicrometer Tracing + OTelDistributed request traces across services
LoggingSLF4J + Logback/Log4j2Structured application logs
HealthSpring Boot ActuatorComponent health and readiness
// Custom metrics with Micrometer:
@Service
public class OrderService {

    private final Counter orderCounter;
    private final Timer   orderTimer;

    public OrderService(MeterRegistry registry) {
        this.orderCounter = Counter.builder("orders.created")
            .description("Total orders created")
            .tag("environment", "prod")
            .register(registry);
        this.orderTimer = Timer.builder("orders.processing.time")
            .description("Time to process order")
            .register(registry);
    }

    public Order placeOrder(CreateOrderRequest request) {
        return orderTimer.record(() -> {
            Order order = doCreateOrder(request);
            orderCounter.increment();
            return order;
        });
    }
}

# application.yml: OpenTelemetry configuration (Boot 4)
management:
  opentelemetry:
    resource-attributes:
      service.name: order-service
      service.version: "2.1.0"
      deployment.environment: production
  tracing:
    sampling:
      probability: 0.1   # 10% sampling in production
  metrics:
    export:
      prometheus:
        enabled: true     # expose /actuator/prometheus

# Export traces to Jaeger / Zipkin / OTel Collector:
management.otlp.tracing.endpoint=http://otel-collector:4317/v1/traces

What new property namespace does Spring Boot 4 introduce for OpenTelemetry resource attribute configuration?
What does Micrometer provide in the Spring Boot 4 observability stack?

27. How does Spring Boot 4 support GraalVM native images?

Spring Boot 4 has first-class support for compiling applications to GraalVM native images -- ahead-of-time compiled binaries that start in milliseconds and use a fraction of the heap compared to JVM-based deployments. Boot 4 requires GraalVM native-image 25 or later.

# Requirements for native image in Spring Boot 4:
# 1. GraalVM native-image 25 (or later)
# 2. java.version >= 17
# 3. spring-boot-starter-parent as parent (or spring AOT plugin)

# Build native image with Maven:
./mvnw -Pnative native:compile
# Output: target/order-service (native binary)

# Build native image with Gradle:
./gradlew nativeCompile
# Output: build/native/nativeCompile/order-service

# Build Docker image with native binary (Buildpacks):
./mvnw spring-boot:build-image -Pnative
# Creates a container image using Cloud Native Buildpacks

// Native image hints for reflection (when AOT analysis misses something):
@ImportRuntimeHints(MyRuntimeHints.class)
@SpringBootApplication
public class App { ... }

public class MyRuntimeHints implements RuntimeHintsRegistrar {
    @Override
    public void registerHints(RuntimeHints hints, ClassLoader cl) {
        // Register class for reflection:
        hints.reflection()
            .registerType(MyDynamicClass.class,
                MemberCategory.INVOKE_DECLARED_METHODS);
        // Register resource file:
        hints.resources().registerPattern("templates/*.html");
    }
}

# Native image startup comparison:
# JVM mode:    ~2-4 seconds startup, ~256MB heap
# Native mode: ~50-100ms startup,    ~50MB memory
# Trade-off:   Build time 5-10 minutes; no JIT optimisation at runtime

What GraalVM native-image version is required by Spring Boot 4?
What is a key trade-off of GraalVM native images compared to standard JVM deployment?

28. What is Spring WebFlux and reactive programming in Spring Boot 4?

Spring WebFlux is Spring's reactive web framework, built on Project Reactor. It is an alternative to Spring MVC for building non-blocking, asynchronous web applications. Spring Boot 4 supports both Spring MVC (servlet-based) and WebFlux (reactive) in the same framework.

Spring MVC vs Spring WebFlux
AspectSpring MVCSpring WebFlux
Programming modelImperative / blockingReactive / non-blocking
Thread modelOne thread per request (or virtual threads)Event loop; fewer threads handle more connections
Return typesObject, ResponseEntityMono, Flux
PersistenceSpring Data JPA (blocking)Spring Data R2DBC (reactive)
Best forTraditional CRUD, simple blocking I/OHigh concurrency, streaming, SSE, WebSocket
// WebFlux reactive controller:
@RestController
@RequestMapping("/api/orders")
public class OrderReactiveController {

    private final OrderReactiveService service;

    // Mono<T>: 0 or 1 item (like Optional)
    @GetMapping("/{id}")
    public Mono<ResponseEntity<OrderDto>> getOrder(@PathVariable String id) {
        return service.findById(id)
            .map(ResponseEntity::ok)
            .defaultIfEmpty(ResponseEntity.notFound().build());
    }

    // Flux<T>: 0 to N items (like Stream)
    @GetMapping
    public Flux<OrderDto> listOrders() {
        return service.findAll();
    }

    // Server-Sent Events (SSE) streaming:
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<OrderDto> streamOrders() {
        return service.streamNewOrders()  // infinite stream of new orders
            .delayElements(Duration.ofSeconds(1));
    }

    // R2DBC (reactive database):
    // Replace JpaRepository with ReactiveCrudRepository
}

// Starter for WebFlux:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
// WebFlux native API versioning (Boot 4):
@GetMapping(path = "/{id}", version = "2.0")
public Mono<OrderDtoV2> getOrderV2(@PathVariable String id) {
    return service.findByIdV2(id);
}

What are the two Project Reactor types used as return types in Spring WebFlux?
What reactive database driver replaces Spring Data JPA when using Spring WebFlux?

29. What is Spring Boot's exception handling with @RestControllerAdvice?

@RestControllerAdvice provides a centralised, global exception handling mechanism for all controllers. It replaces the need to put @ExceptionHandler methods in every controller class.

// Centralised exception handler:
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    // Handle custom domain exception:
    @ExceptionHandler(OrderNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorResponse handleNotFound(OrderNotFoundException ex) {
        return new ErrorResponse(
            "ORDER_NOT_FOUND",
            ex.getMessage(),
            Instant.now()
        );
    }

    // Handle Bean Validation failures:
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ValidationErrorResponse handleValidation(MethodArgumentNotValidException ex) {
        Map<String, String> fieldErrors = ex.getBindingResult()
            .getFieldErrors()
            .stream()
            .collect(Collectors.toMap(
                FieldError::getField,
                FieldError::getDefaultMessage,
                (a, b) -> a  // keep first on duplicate key
            ));
        return new ValidationErrorResponse("VALIDATION_FAILED", fieldErrors);
    }

    // Handle illegal argument:
    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleIllegalArg(IllegalArgumentException ex) {
        return new ErrorResponse("INVALID_REQUEST", ex.getMessage(), Instant.now());
    }

    // Catch-all for unexpected exceptions:
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResponse handleGeneral(Exception ex, HttpServletRequest request) {
        log.error("Unhandled exception for {}: {}", request.getRequestURI(), ex.getMessage(), ex);
        return new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred", Instant.now());
    }
}

public record ErrorResponse(String code, String message, Instant timestamp) {}

What is the difference between @ControllerAdvice and @RestControllerAdvice in Spring Boot 4?
In a @RestControllerAdvice class, what does placing @ExceptionHandler(OrderNotFoundException.class) on a method do?

30. How do you use Spring Data MongoDB and other NoSQL stores in Spring Boot 4?

Spring Boot 4 auto-configures connections to MongoDB, Redis, Cassandra, Elasticsearch, and other NoSQL stores when their starters are on the classpath. The programming model mirrors Spring Data JPA but without SQL.

// MongoDB entity:
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "products")  // MongoDB collection name
public record Product(
    @Id String id,            // MongoDB ObjectId
    String name,
    BigDecimal price,
    String category,
    Instant createdAt
) {}

// MongoDB repository:
public interface ProductRepository
        extends MongoRepository<Product, String> {

    List<Product> findByCategory(String category);
    List<Product> findByPriceLessThan(BigDecimal maxPrice);

    // MongoDB query annotation:
    @Query("{ \"category\": ?0, \"price\": { \"$lt\": ?1 } }")
    List<Product> findByCategoryAndMaxPrice(String category, BigDecimal maxPrice);
}

# application.yml: MongoDB connection:
spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017/products-db
      # or:
      host: localhost
      port: 27017
      database: products-db
      username: ${MONGO_USER}
      password: ${MONGO_PASS}

# application.yml: Redis connection:
spring:
  data:
    redis:
      host: localhost
      port: 6379
      password: ${REDIS_PASS}
      timeout: 2s

// Redis template usage:
@Service
public class SessionService {
    private final RedisTemplate<String, Object> redisTemplate;
    public void store(String key, Object value, Duration ttl) {
        redisTemplate.opsForValue().set(key, value, ttl);
    }
}

What annotation marks a class as a MongoDB document in Spring Boot 4?
What interface would you extend to create a MongoDB repository in Spring Boot 4?

31. How does Spring Boot 4 handle async processing with @Async?

@Async makes a method execute in a separate thread asynchronously, returning a CompletableFuture (or void) immediately while processing continues in the background. Spring Boot 4 automatically uses virtual threads when enabled.

// Enable async processing:
@SpringBootApplication
@EnableAsync
public class App { ... }

// Async service:
@Service
public class EmailService {

    // Fire-and-forget (no return value):
    @Async
    public void sendWelcomeEmail(String email) {
        // Runs in separate thread; caller continues immediately
        emailGateway.send(email, "Welcome!", buildWelcomeBody(email));
    }

    // Async with result:
    @Async
    public CompletableFuture<EmailStats> getEmailStats(String userId) {
        EmailStats stats = emailGateway.fetchStats(userId);  // slow I/O
        return CompletableFuture.completedFuture(stats);
    }
}

// Caller:
@Service
public class RegistrationService {

    public User register(RegisterRequest req) {
        User user = userRepo.save(new User(req));
        emailService.sendWelcomeEmail(user.email()); // returns immediately
        return user;  // registration complete; email sends in background
    }

    // Parallel async calls:
    public DashboardData loadDashboard(String userId) throws Exception {
        CompletableFuture<OrderStats>  orders  = orderService.getStats(userId);
        CompletableFuture<EmailStats>  emails  = emailService.getEmailStats(userId);
        CompletableFuture<PaymentInfo> payment = paymentService.getInfo(userId);

        // Wait for all 3 to complete (run in parallel)
        CompletableFuture.allOf(orders, emails, payment).join();
        return new DashboardData(orders.get(), emails.get(), payment.get());
    }
}

# Custom async executor thread pool:
spring:
  task:
    execution:
      pool:
        core-size: 5
        max-size: 20
        queue-capacity: 100
      thread-name-prefix: async-

What does @EnableAsync do in Spring Boot 4?
What return type should an @Async method use to allow the caller to wait for the result?

32. What is Spring Boot's externalized configuration with @Value and @ConfigurationProperties?

Spring Boot 4 provides two ways to inject configuration values into beans: @Value for simple individual values and @ConfigurationProperties for structured, type-safe groups of related properties.

# application.yml:
app:
  payment:
    gateway-url: https://payment.example.com/api
    timeout-seconds: 30
    retry-attempts: 3
    supported-currencies: [USD, EUR, GBP, JPY]

api:
  rate-limit: 1000

// Method 1: @Value for simple individual values
@Service
public class RateLimiter {

    @Value("${api.rate-limit}")
    private int rateLimit;

    @Value("${api.rate-limit:500}")  // default value if not configured
    private int rateLimitWithDefault;

    @Value("${MISSING_PROP:#{null}}")  // null default
    private String optionalProp;

    @Value("${spring.application.name}")
    private String appName;
}

// Method 2: @ConfigurationProperties for grouped values (recommended)
@ConfigurationProperties(prefix = "app.payment")
@Validated
public record PaymentProperties(
    @NotBlank URL gatewayUrl,
    @Positive int timeoutSeconds,
    @Min(1) @Max(10) int retryAttempts,
    @NotEmpty List<String> supportedCurrencies
) {}

// Register and inject:
@EnableConfigurationProperties(PaymentProperties.class)
@SpringBootApplication
public class App { ... }

@Service
@RequiredArgsConstructor
public class PaymentService {
    private final PaymentProperties config;  // type-safe injection
    public void processPayment(String currency) {
        if (!config.supportedCurrencies().contains(currency)) {
            throw new UnsupportedCurrencyException(currency);
        }
    }
}

What is the advantage of @ConfigurationProperties over @Value for grouped configuration?
What syntax does @Value use to provide a default value if the property is not configured?

33. What is Spring Boot's messaging support with Kafka in Boot 4?

Spring Boot 4 ships with Spring for Apache Kafka 4.0, which introduces Share Consumer support for Kafka Queues -- allowing multiple consumers in a group to share records from the same partition rather than partitions being locked to single consumers.

// Producer:
@Service
public class OrderEventProducer {

    private final KafkaTemplate<String, OrderEvent> kafkaTemplate;

    public void publishOrderCreated(Order order) {
        OrderEvent event = new OrderEvent(order.id(), "ORDER_CREATED", Instant.now());
        kafkaTemplate.send("orders-topic", order.id(), event);
    }
}

// Consumer:
@Service
public class OrderEventConsumer {

    @KafkaListener(
        topics       = "orders-topic",
        groupId      = "order-processing-group",
        concurrency  = "3"  // 3 consumer threads
    )
    public void handleOrderEvent(
            @Payload OrderEvent event,
            @Header(KafkaHeaders.RECEIVED_TOPIC) String topic,
            Acknowledgment ack) {
        try {
            processEvent(event);
            ack.acknowledge();  // manual acknowledgement
        } catch (Exception e) {
            log.error("Failed to process event: {}", event, e);
            // send to DLT (dead letter topic)
        }
    }
}

# application.yml: Kafka configuration
spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      group-id: order-service
      auto-offset-reset: earliest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      properties:
        spring.json.trusted.packages: "com.example.events"
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer

What new Kafka feature does Spring for Apache Kafka 4.0 (in Spring Boot 4) introduce?
What annotation marks a method as a Kafka message listener in Spring Boot 4?

34. How do you schedule tasks in Spring Boot 4 with @Scheduled?

Spring Boot 4 provides task scheduling via @EnableScheduling and @Scheduled annotations. In Boot 4, the auto-configuration for task scheduling supports multiple TaskDecorator beans, enabling better observability and context propagation.

// Enable scheduling:
@SpringBootApplication
@EnableScheduling
public class App { ... }

@Service
public class ReportScheduler {

    // Fixed rate: every 60 seconds (interval from start of last execution)
    @Scheduled(fixedRate = 60_000)
    public void generateHourlyMetrics() {
        metricsService.compute();
    }

    // Fixed delay: 30 seconds AFTER last execution completes
    @Scheduled(fixedDelay = 30_000)
    public void cleanExpiredSessions() {
        sessionService.evictExpired();
    }

    // Cron expression: every day at 2:30 AM
    @Scheduled(cron = "0 30 2 * * *")
    public void dailyReport() {
        reportService.generateDailyReport();
    }

    // Cron with zone:
    @Scheduled(cron = "0 0 8 * * MON-FRI", zone = "Europe/London")
    public void morningDigest() {
        digestService.send();
    }

    // Initial delay: wait 5s after startup before first run
    @Scheduled(initialDelay = 5_000, fixedRate = 60_000)
    public void warmUpCache() {
        cacheService.preload();
    }
}

# Cron syntax: second minute hour day-of-month month day-of-week
# "0 */5 * * * *"  = every 5 minutes
# "0 0 * * * *"    = every hour on the hour
# "0 0 9-17 * * MON-FRI" = every hour 9am-5pm Mon-Fri

# Spring Boot 4: multiple TaskDecorator beans supported
# (propagates MDC logging context and security context to scheduled threads)
@Bean
public TaskDecorator mdcTaskDecorator() {
    return runnable -> () -> {
        MDC.put("task", "scheduled");
        try { runnable.run(); } finally { MDC.clear(); }
    };
}

What is the difference between fixedRate and fixedDelay in @Scheduled?
What Spring Boot 4 improvement to task scheduling auto-configuration aids distributed tracing?

35. What is Spring AI and how does it integrate with Spring Boot 4?

Spring AI is a first-class Spring ecosystem project that reached 1.0 GA in May 2025 and is now on a 2.x development track. It provides a model-agnostic abstraction layer for integrating LLMs, vector stores, and AI pipelines into Spring Boot 4 applications.

Spring AI core concepts
ConceptDescription
ChatModelAbstraction over LLM providers (OpenAI, Gemini, Anthropic, Mistral, Ollama, etc.)
EmbeddingModelGenerates vector embeddings from text
VectorStoreAuto-configured integration with 10+ vector databases (pgvector, Pinecone, Chroma, Weaviate, etc.)
ChatClientFluent API for building prompt chains, advisors, and tool calling
Tool callingLLMs can invoke Spring beans as tools (@Tool annotation)
MCP supportModel Context Protocol server integration
RAG pipelinesQuestionAnswerAdvisor for retrieval-augmented generation
// Spring AI: ChatClient in Spring Boot 4
@Service
public class CustomerSupportService {

    private final ChatClient chatClient;

    public CustomerSupportService(ChatClient.Builder builder,
                                  VectorStore vectorStore) {
        this.chatClient = builder
            .defaultSystem("You are a helpful customer support agent.")
            .defaultAdvisors(
                // RAG: retrieve relevant documents before answering
                new QuestionAnswerAdvisor(vectorStore),
                new MessageChatMemoryAdvisor(new InMemoryChatMemory())
            )
            .build();
    }

    public String answer(String question) {
        return chatClient.prompt()
            .user(question)
            .call()
            .content();
    }
}

// Tool calling: LLM can call Spring beans as tools
@Service
public class OrderTools {
    @Tool(description = "Get the current status of an order by its ID")
    public String getOrderStatus(String orderId) {
        return orderService.findById(orderId).status().name();
    }
}

# application.yml: Spring AI OpenAI configuration
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o-mini
          temperature: 0.7

What is the primary advantage of Spring AI's ChatModel abstraction over calling LLM APIs directly?
What does the @Tool annotation do in Spring AI when used on a Spring bean method?

36. How does Spring Boot 4 handle logging configuration?

Spring Boot 4 auto-configures Logback as the default logging framework (with SLF4J as the facade). Log4j2 and JUL are also supported. Boot 4 enhances structured logging for production observability.

# Logging configuration in application.yml:
logging:
  level:
    root: INFO                         # global default level
    com.example.service: DEBUG         # package-specific level
    org.springframework.security: WARN # reduce security noise
    org.hibernate.SQL: DEBUG           # log SQL statements
    org.hibernate.orm.jdbc.bind: TRACE # log SQL parameters
  file:
    name: /var/log/order-service/app.log
  logback:
    rollingpolicy:
      max-file-size: 100MB
      max-history: 30
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
    file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%X{traceId},%X{spanId}] - %msg%n"

// Structured logging (JSON) for production / log aggregation:
logging:
  structured:
    format:
      console: ecs      # Elastic Common Schema
      file: logstash    # Logstash JSON format
# Output: machine-readable JSON logs for ELK stack

// Using SLF4J in application code:
@Service
public class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);
    // Or with Lombok:
    // @Slf4j
    // public class OrderService {

    public Order createOrder(CreateOrderRequest req) {
        log.debug("Creating order for product: {}", req.productId());
        Order order = repo.save(new Order(req));
        log.info("Order created successfully: id={}, product={}", order.id(), order.productId());
        return order;
    }
}

// Change log level at runtime via Actuator:
// POST /actuator/loggers/com.example.service
// Body: {"configuredLevel": "DEBUG"}

What is the default logging framework auto-configured by Spring Boot 4?
How do you change a package log level at runtime without restarting a Spring Boot 4 application?

37. What is Spring Boot 4 migration from Boot 3: complete checklist and common pitfalls?

Migrating to Spring Boot 4 requires addressing several categories of change. Here is a practical checklist with the most common pitfalls teams encounter.

Spring Boot 4 migration checklist
CategoryActionCommon pitfall
Pre-migrationUpgrade to Spring Boot 3.5 and fix ALL deprecation warningsDeprecations from 3.x are hard-deleted in 4.0 -- skipping this step guarantees breakage
JavaConfirm Java 17 minimum; recommend Java 21 for virtual threadsUsing Java 11 will fail at startup
KotlinUpgrade to Kotlin 2.2 if using KotlinKotlin null-safety compilation failures from JSpecify annotations
DependenciesUpdate BOM version to 4.x.x; rename starters (webmvc, webflux)Old spring-boot-starter-web still resolves but triggers a deprecation
JacksonMigrate from com.fasterxml.jackson to tools.jackson; audit JSON testsSilent date format and property ordering changes break JSON contracts
ServerRemove Undertow dependency; migrate to Tomcat 11 or Jetty 12.1Application fails to start if Undertow is still on classpath
PersistenceReview Hibernate 7.1 detached entity behaviourLenient reassociation silently broken; explicit merge required
SecurityReview Spring Security 7 CSRF defaultsREST API tests fail silently after CSRF default change
javax.* importsRun OpenRewrite Migrate_To_Jakarta_EE_10 recipeAny remaining javax.* imports cause ClassNotFoundException at runtime
TestingReplace JUnit 4 tests (removed); update MockMvc to RestTestClientJUnit 4 is gone; vintage engine not included in spring-boot-starter-test
# Maven: run OpenRewrite migration recipes
mvn rewrite:run \
  -Drewrite.activeRecipes=\
    org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5,\
    org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0,\
    org.openrewrite.java.jackson.UpgradeJackson_2_3

# What OpenRewrite handles automatically:
#  - Package renames (javax -> jakarta)
#  - Jackson package renames (com.fasterxml -> tools.jackson)
#  - Deprecated API replacements
#  - Configuration property renames
#
# What OpenRewrite CANNOT handle:
#  - Jackson date serialisation default change
#  - JSON property ordering default change
#  - Hibernate detached entity behaviour
#  - Spring Security CSRF default changes
#  (these require manual review of integration tests)

What does OpenRewrite's UpgradeJackson_2_3 recipe handle automatically?
Why do Kotlin developers often have the most compilation failures when migrating to Spring Boot 4?

38. What is Spring Boot DevTools and how does it improve development productivity?

Spring Boot DevTools accelerates development by providing automatic application restart, LiveReload, and property overrides for development environments. It is available only on the development classpath and has no effect in production.

<!-- Add DevTools (automatically excluded from production builds): -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>  <!-- excluded from fat JAR / image -->
</dependency>

# What DevTools provides:
# 1. Automatic restart: detects classpath changes and restarts the app
#    (much faster than cold start -- uses two ClassLoaders)
# 2. LiveReload: refreshes browser on static resource changes
# 3. Property overrides for development:
#    - Disables caching (Thymeleaf, Jackson)
#    - Enables H2 console
#    - Sets DEBUG logging for web and SQL

# application.yml (DevTools default overrides in dev):
# spring.thymeleaf.cache=false         (disabled by DevTools)
# spring.jackson.serialization.indent_output=true
# logging.level.web=DEBUG
# spring.h2.console.enabled=true

# DevTools remote restart (for Docker/remote dev):
spring:
  devtools:
    remote:
      secret: ${DEVTOOLS_SECRET}
      # Enable in IDE to push class changes to running remote container

# Disable specific DevTools features:
spring:
  devtools:
    restart:
      enabled: false    # disable auto-restart
    livereload:
      enabled: false    # disable LiveReload server
    additional-exclude: "static/**,public/**"  # dont restart on these changes

How does Spring Boot DevTools auto-restart work faster than a cold application start?
How does Spring Boot ensure DevTools is excluded from production deployments?

39. How does Spring Boot 4 support containerised deployments with Docker?

Spring Boot 4 has first-class container support via Cloud Native Buildpacks (CNB), Layered JARs, and GraalVM native image Docker images. The Spring Boot Maven/Gradle plugins can produce optimised Docker images without a Dockerfile.

# Option 1: Buildpacks (recommended -- no Dockerfile needed)
# Maven:
./mvnw spring-boot:build-image
# Produces: docker.io/library/order-service:1.0.0

# With custom image name and registry:
./mvnw spring-boot:build-image \
  -Dspring-boot.build-image.imageName=gcr.io/my-project/order-service:1.0.0

# Native image with Buildpacks:
./mvnw spring-boot:build-image -Pnative

# Option 2: Traditional Dockerfile with Layered JAR
# First, enable layered JAR:
<configuration>
    <layers>
        <enabled>true</enabled>
    </layers>
</configuration>

# Dockerfile (multi-stage, layered JAR):
FROM eclipse-temurin:17-jre AS builder
WORKDIR /app
COPY target/*.jar app.jar
RUN java -Djarmode=tools -jar app.jar extract --layers --launcher

FROM eclipse-temurin:17-jre
WORKDIR /app
# Copy layers in order of least-to-most frequently changed:
COPY --from=builder /app/extracted/dependencies ./
COPY --from=builder /app/extracted/spring-boot-loader ./
COPY --from=builder /app/extracted/snapshot-dependencies ./
COPY --from=builder /app/extracted/application ./
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

# Docker Compose for local development:
# compose.yml (Spring Boot 4 auto-detects compose.yml):
services:
  postgres:
    image: postgres:17
    environment:
      POSTGRES_DB: orders
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
    ports: ["5432:5432"]
  redis:
    image: redis:8
    ports: ["6379:6379"]
# spring.docker.compose.enabled=true (default) auto-starts compose services

What advantage does using Cloud Native Buildpacks (spring-boot:build-image) have over writing a Dockerfile?
What does jarmode=tools in a Spring Boot 4 layered JAR Dockerfile allow?

40. What is the Spring Boot 4 vs Spring Boot 3 comparison and what are the key takeaways?

Understanding the differences between Spring Boot 3 and Spring Boot 4 is the most common interview question for teams evaluating or migrating to Boot 4. Here is a structured comparison of every major dimension.

Spring Boot 3 vs Spring Boot 4 comprehensive comparison
DimensionSpring Boot 3.xSpring Boot 4.x
Release dateNovember 2022 (3.0), ongoingNovember 20, 2025 (4.0)
Spring FrameworkSpring Framework 6Spring Framework 7
Jakarta EEJakarta EE 9 / 10Jakarta EE 11 (Servlet 6.1)
Minimum JavaJava 17Java 17 (same)
Best JavaJava 21Java 25
Kotlin minimumKotlin 1.7+Kotlin 2.2
ModularisationMonolithic spring-boot-autoconfigure JAR70+ focused technology modules
API versioningDIY (custom paths, filters, conditions)Native: @GetMapping(version="2.0")
JSON libraryJackson 2 (com.fasterxml.jackson)Jackson 3 (tools.jackson)
Null safetyspring.lang annotationsJSpecify portfolio-wide
Embedded serversTomcat 10, Jetty 11, Undertow 2Tomcat 11, Jetty 12.1 (Undertow REMOVED)
Retry/resilienceExternal spring-retry + @EnableRetryBuilt-in @Retryable + @ConcurrencyLimit
HTTP clientsRestTemplate (legacy), WebClientRestClient, HTTP Service Clients (@HttpExchange)
Test clientMockMvc or WebTestClientRestTestClient (unified)
JUnit 4Supported via Vintage engineREMOVED
Spring SecuritySpring Security 6Spring Security 7 (MFA built-in)
KafkaSpring Kafka 3.xSpring Kafka 4.0 (Share Consumer)
GraalVMnative-image 23+native-image 25+
Spring AINot includedProduction-ready 1.x; heading to 2.x
What is the single most impactful structural change in Spring Boot 4 compared to Boot 3?
Which combination of changes in Spring Boot 4 is most likely to cause silent test failures during migration?
«
»

Comments & Discussions