Preparing for a Spring Boot interview requires knowing more than the basics. You need to understand how a Spring Boot application works in modern backend systems.
Spring Boot is a key part of the Spring framework ecosystem and is widely used in Java backend development. Spring Boot simplifies application development by providing auto-configuration, dependency management, and production-ready features.
This guide is designed to help you practice core fundamentals and tackle real-world scenarios. Whether you are preparing for your first Spring Boot interview or advancing into intermediate and senior roles, this guide provides both conceptual and practical knowledge.
Practice over 60 common Spring Boot interview questions and answers.
Learn key topics including configurations, data access, JPA, security, performance and architecture.
Follow the Spring Boot roadmap for structured learning.
Use the AI Tutor for better insights.
Preparing for a Spring Boot interview goes beyond memorizing answers. Here are some useful tips to help you ace your Spring Boot interview:
Have a strong grasp of foundational topics like basic Spring Boot annotations, dependency management, Spring-managed components, Spring Boot auto-configuration, REST controllers, Spring Boot actuator, Spring Data Java Persistence API (JPA) basics, and exception handling.
Go beyond surface-level knowledge and explore what happens under the hood to gain mastery.
Think through the questions, visualize or reference a scenario, and guide interviewers through your thought process.
Stay updated on recent changes and features in the ecosystem.
You can either use these flashcards or jump to the questions list section below to see them in a list format.
Why should you choose Spring Boot over the Spring framework?
You should choose Spring Boot when you want a faster setup, auto-configuration, and embedded servers with minimal configuration. Here is how Spring Boot compares to the Spring framework:
Manual XML/Java config
Requires external server
Production readiness
Has built-in support
If you prefer to see the questions in a list format, you can find them below.
The key components of Spring Boot are:
Spring Boot Starters : Pre-configured dependency bundles that simplify Maven/Gradle setup.
Auto-Configuration : Automatically configures beans based on classpath and properties.
Spring Boot Actuator : Provides production-ready monitoring endpoints.
Spring Boot CLI : Command-line tool for rapid prototyping.
Embedded Server : Allows applications to run without an external server setup.
@SpringBootApplication is a meta-annotation that combines three core annotations:
@Configuration : Marks the class as a source of bean definitions.
@EnableAutoConfiguration : Indicates that Boot should start adding beans based on classpath settings.
@ComponentScan : Tells Spring to look for the @Component , @Service , @Controller and @Repository classes in the current package and sub-packages.
The Spring Boot flow architecture encapsulates how a request moves through a Spring Boot application from entry point to response generation.
In a simple Spring Boot application, the flow typically follows these steps:
The application starts from the public static void main method.
The SpringApplication.run () method bootstraps the Spring context.
Spring Boot automatically configures the beans using auto configuration.
The embedded Tomcat server starts.
The DispatcherServlet receives the HTTP request.
The request flows through Controller -> Service layer -> Data access layer.
A JSON response is returned.
The Spring Boot CLI (Command Line Interface) is a tool that lets you quickly create and run a Spring Boot application with simple commands. The Spring Boot command line interface is useful for rapid prototyping, quick demos, or testing Spring components.
Spring Boot DevTools is a development-only tool that improves developer productivity in Spring Boot applications. It provides:
Automatic restart functionality whenever code changes are detected
A LiveReload support that automatically refreshes the browser when resources change
With Spring Boot DevTools, you get a better local development experience and a faster backend development workflow.
The Inversion of Control (IoC) container manages the lifecycle of Java objects (also called Beans). It makes your code loosely coupled and easier to test. Instead of a manual class instantiation, Spring, through the IoC, can automatically manage the instantiation and injection of beans.
A Spring Boot Starter is a pre-configured dependency bundle that groups commonly used libraries for a specific functionality. Instead of manually adding multiple dependencies, you add a single starter that automatically includes the required libraries.
Dependency Injection is a design pattern in which a class receives its required dependencies from an IoC container rather than creating them itself.
The main differences between IoC and Dependency Injection are:
Dependency Injection
Mechanism to implement IoC
Guiding principle of delegating control
How dependencies are provided
Who controls object creation and flow
One way to implement IoC
Can be achieved using DI, service locator, template method, events, etc
In Spring Boot apps, the application properties file serves as the central location for external configuration and environment properties. Its purpose is to define application-specific settings such as database URLs, server ports, credentials, and logging levels, without modifying your Java code.
Externalized configuration allows you to separate configuration from application code so that the same application can run in different environments without modification. Spring Boot supports other externalized configuration sources, such as environment variables, command-line arguments, profile-specific files, and cloud config servers.
Auto-configuration is a feature that automatically configures your application based on the Spring Boot dependencies on your classpath, existing beans in the Spring context, and configuration properties. Internally, Spring Boot checks conditions inside each specific auto-configuration class to decide whether certain beans should be created.
You can see details of auto-configurations by running your application with the --debug flag.
In Spring Boot, the server is embedded directly inside the application. When you include spring-boot-starter-web , Spring Boot automatically provides an embedded server such as Tomcat. This makes the application self-contained, easier to deploy, and compatible with cloud and microservice-based architectures.
@Controller is used for traditional webpages. @RestController is a modern annotation in Spring Boot that combines @Controller and @ResponseBody .
@Controller returns a View/HTML. @RestController returns JSON or XML data directly in the HTTP response body.
The default web server port is 8080 . You can change it by setting server.port in application.properties or application.yml , or by passing it as a command-line argument when starting the application.
Spring Initializr is generally the fastest way to get a Spring Boot project up and running quickly. It comes with a pre-configured setup and robust Spring Boot dependency management.
@RequestMapping is the general Spring Boot annotation used to map HTTP requests to controller methods. @GetMapping is a specialized annotation in Spring Boot used to map GET requests.
Use @GetMapping for simple GET requests, and @RequestMapping when you need more flexibility, such as supporting multiple HTTP methods.
Spring Boot Actuator provides production-ready observability features. It helps you monitor, manage, and gain insights into your application while it’s running. You have access to Spring Boot Actuator endpoints such as /health , /metrics , and /info that allow you to monitor the health and performance of your application once deployed.
Objects created with new are outside Spring’s control and cannot benefit from features such as dependency injection and lifecycle callbacks.
The DispatcherServlet is the central entry point for all HTTP requests in a Spring MVC application. It receives and delegates request processing to the appropriate components.
The DispatcherServlet:
Captures the request.
Finds UserController.getUserById() via HandlerMapping .
Invokes it via HandlerAdapter .
Converts the returned object to JSON using HttpMessageConverter .
Sends response to the client.
Component scanning is the process by which Spring automatically detects and registers beans in the application context by scanning your classpath for classes annotated with stereotypes like @Component , @Service , @Repository , and @Contr o ller.
This process helps remove boilerplate configuration, keeps bean management within your Spring Boot project, and makes your code modular and maintainable.
Spring Boot dependency management uses BOM (Bill of Materials) provided through spring-boot-starter-parent. This BOM defines compatible versions for common libraries, so you don’t need to specify versions in your pom.xml. This ensures compatibility between libraries, prevents version conflicts, simplifies project setup, and reduces maintenance overhead.
The CommandLineRunner is a functional interface in Spring Boot that allows you to run code after the Spring application context has fully loaded, but just before the application starts handling requests.
This is particularly useful in:
Seeding initial data into the database
Running startup tasks such as scheduling jobs or initializing caches
In Spring Boot framework, properties are loaded in a defined priority order. When multiple sources define the same property, the one with higher priority overrides the others. More specific and external sources override less specific and internal ones.
For example, when the dev profile is active in your Spring Boot project, application-dev.properties overrides overlapping properties defined in application.properties.
In Spring Boot, both @Primary and @Qualifier are used to resolve ambiguity when multiple beans of the same type exist in the application context. These Spring Boot annotations help Spring decide which bean to inject when multiple beans of the same type exist.
There are some differences between @Primary and @Qualifier :
Selects a specific bean
Applied at the bean definition
Applied at the injection point
Used when no qualifier is provided
In Spring Boot, global exception handling involves managing application errors in a central place rather than handling them separately in each controller. Using global exceptional handling with @RestControllerAdvice with @ExceptionHandler eliminates the need to write try-catch blocks in every controller. Use @ResponseEntityExceptionHandler for customized error responses.
Singleton beans do not automatically guarantee thread safety. With singleton beans, there is only one instance per IoC container, but multiple threads can access it simultaneously. States determine the safety of beans. If the spring bean has a mutable state, concurrent access can lead to race conditions or inconsistent behavior.
DelegatingFilterProxy acts as a bridge between the Servlet container and a Spring-managed filter bean. When a client sends an HTTP request, the container invokes DelegatingFilterProxy, which retrieves the FilterChainProxy bean. It is the FilterChainProxy bean that executes the full Spring Security filter chain, consisting of authentication, authorization, CSRF, and session management filters.
Version control : Every schema change is written as a versioned migration script and is committed to source control.
Predictability : Flyway executes explicitly written SQL and runs migrations in a well-defined order.
Safer production deployments : Flyway uses a fail-fast mechanism where, if a migration fails, the application startup fails too.
Environment properties consistency : Flyway ensures all environment properties apply the same migrations, version ordering, and schema state.
Complex changes and data migrations : Flyway supports data migrations, index creation, constraint updates, and performance tuning changes
Soft delete in Spring Data JPA means marking a row as deleted without actually removing it. This enables better data recovery, audit/history retention, regulatory compliance, and improved debugging. You can implement soft delete by using the deleted flag or a deletedAt timestamp column.
Self-injection is a process in which a Spring bean injects a reference to itself through the Spring container instead of calling methods directly using this . By calling self.method() , the call goes through the proxy, and the Spring Boot annotations are triggered correctly.
Self-injection is used to address the proxy pitfall, where calling a method on this bypasses Spring proxies and prevents the introduction of annotations such as @Transactional , @Async , or @Cacheable .
There are two common approaches to restricting access to certain endpoints:
URL-based security : Involves configuring access rules in your SecurityFilterChain bean.
Method-level security : Used to gain more control inside service or controller methods by enabling @EnableMethodSecurity and annotating methods with @PreAuthorize("hasRole('ADMIN')") .
Gives centralized control and easy to see all endpoint rules
Less flexibility for complex business rules
Gives granular control, works inside the service layer and supports dynamic checks
Requires enabling method security and harder to visualize all rules in one place
Iterable is the most basic collection type. It returns all matching records as an Iterable. Its best use cases are when you only need to loop through results and need minimal memory overhead.
List is a standard Java List. It fetches all records into memory. Its best use cases are when the total number of results is small, and you want to perform standard collection operations.
Slice is a chunk of data that represents a slice of the result set. It fetches only the current chunk of data. Its best use case is for implementing ‘Load More’ buttons or infinite scrolling.
Page is an extension of Slice, but also contains pagination metadata. It fetches the current chunk of data and performs a count query to know the total number of pages. Its best use case is for numbered pagination.
@Lazy delays the creation of a Spring bean until it is actually needed. It tells the Spring container not to create a Spring bean immediately at application startup, which is the default behavior. When you annotate a bean with @Lazy , Spring creates a proxy object and instantiates the real bean only when it is first requested or used.
In Spring Boot, these annotations differ in several ways:
Exception translation
Handles HTTP requests
CORS can be configured in Spring Boot either globally or locally at the controller level, depending on the required access scope.
If your frontend needs to access many endpoints, configure CORS globally.
If you want to restrict cross-origin access to specific endpoints, configure it at the controller level.
Content negotiation is the process by which Spring determines the response media type to return to the client. It decides whether to return JSON, XML, text, or HTML based on the client’s request. When a client sends a request, Spring first checks the Accept header, then finds a compatible HttpMessageConverter and converts the returned Java object into the requested format.
Use bean validation with annotations such as @NotNull , @Size , and @Email on Data Transfer Object (DTO) fields, and use @Valid in controller methods. On invalid input, a MethodArgumentNotValidException will be thrown.
These approaches are both used for injecting configuration properties into your application, but have several differences.
@ConfigurationProperties
Structured and hierarchical
Supports bean validation
Low for many properties
Application-wide configs
In Spring Boot, you enable async methods by adding @EnableAsync to a configuration class and annotating the method with @Async . This makes the method run in a separate thread, letting the caller continue without waiting.
This is particularly useful for tasks such as sending emails, calling external APIs, or running background operations.
Access to endpoints is controlled with Spring Security by specifying which URLs require authentication and which roles can access them using HttpSecurity. It ensures that sensitive endpoints are only accessed by authorized users.
For stateless, token-based authentication, combine with JWT or OAuth2 . For method-level security, use @PreAuthorize or @Secured .
AOT processing is a build-time optimization technique that analyzes your application before it runs and generates code to reduce work done at runtime.
When you build your application, Spring:
Analyzes your configuration to determine which beans to instantiate, which proxies to create and reflection hints to add.
Then generates optimized source code that replaces runtime reflection logic.
This mechanism leads to:
Lower memory footprint
Enables native image support
A circular dependency occurs when two or more beans, directly or indirectly, depend on each other, forming a dependency cycle. Because each bean depends on the other, the framework cannot determine which to initialize, resulting in a startup failure.
Since circular dependencies are a design problem, the best solution is to refactor your application's design by decoupling through abstraction. By introducing an interface between two or more services, the circular dependency is removed. Also, choosing constructor injection vs. field injection affects how circular dependencies are detected and resolved.
Use lazy initialization : Beans should only be created when first used.
Enable AOT processing : Pre-compute beans wiring and proxies at build time.
Limit auto-configuration : Use @SpringBootApplication(exclude = ...) or spring.autoconfigure.exclude to prevent unnecessary loading of beans and starter modules.
Optimize proxies : Use @Configuration(proxyBeanMethods = false) to reduce proxy overhead.
Use profile-based configuration : Load only the required beans per environment using @Profile .
Use native images : Use GraalVM native image to reduce startup time.
Virtual threads can improve your application in:
Handling of massive concurrent requests without thread exhaustion
Writing simple code that scales
Effective cloud deployment and serverless execution
Less memory consumption
There are also trade-offs to using virtual threads in your application, like:
Virtual threads require Java 21+ and container support to be properly integrated.
Delegating work to traditional threads may limit scalability benefits.
Virtual threads can be limited by CPU cores.
AutoConfiguration.imports
META-INF/spring.factories
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
SpringFactoriesLoader
Optimized AutoConfiguration loader
Significantly faster
Used for many extension points
Dedicated to auto-configuration
Legacy (partially supported)
Recommended approach and fully supported
Microservices architecture involves each service having its own data, with communication happening over network calls. The absence of a single shared transaction manager creates a distributed transaction problem.
There are two main strategies to solve this problem:
Saga Pattern : This pattern breaks a distributed transaction into smaller local transactions, each managed by its own service. If one step fails, a compensating transaction is executed to undo previous actions.
Two-Phase Commit (2PC) : 2PC is a traditional distributed transaction protocol that involves Prepare and Commit or Rollback phases. It prioritizes strong consistency among transactions.
@ConditionalOnMissingBean allows users of a custom Spring Boot starter to override the default bean auto-configuration. Internally, during auto-configuration, each specific auto-configuration class is processed in the following order:
Spring evaluates conditional annotations.
It checks the context for bean type and name (if specified).
If a match exists, the condition fails, and the bean method is not executed.
The N+1 problem is a common performance issue in JPA/Hibernate, in which a single query fetches the parent entities, and N additional queries are executed to fetch the related child entities. This results in excessive database calls and poor performance.
There are a few ways to solve this problem:
Use JOIN FETCH : Forces JPA to fetch related entities in one query. With this approach:
Hibernate executes one SQL query.
Parents and children are fetched together.
Use @EntityGraph : Explicitly defines which related entities should be fetched in a single query. With this approach:
When fetching a parent entity, it also fetches its items.
The related entities are fetched in a single SQL query using a JOIN.
The Proxy Pitfall is a common issue where the @Transactional method does not start a transaction when called from another method within the same class. This happens because Spring implements @Transactional using Aspect-Oriented Programming (AOP) proxies, and internal method calls bypass the proxy.
You can fix Proxy Pitfall by:
Moving the transactional method to another bean. This is the recommended approach.
Injecting self-proxy.
Microservices architecture security should be decentralized, stateless, scalable, and independent per service. The modern approach that follows this standard is to use an OAuth2 Resource Server with JSON Web Token (JWT).
In this approach, each microservice acts as a Resource Server. Here is how it flows:
User authenticates with an Identity Provider (IdP).
The IdP issues a JWT.
The client sends that JWT in the Authorization header.
Each microservice will perform a series of actions, such as validating the JWT locally, verifying the signature using the IdP’s public key, extracting roles, and authorizing access.
Decide where rate limiting should be used. In microservices, rate limiting should not live inside each service by default.
Use Redis for distributed token coordination. The API Gateway serves as the enforcement point, while Redis acts as the shared consistency layer.
Choose the right algorithm. Could be Fixed Window , Sliding Window , Token Bucket , or Leaky Bucket .
Decide how you want to key the rate limit. Some common keys are per IP, per user ID, per API key, per tenant, and per client application.
Strategize on how to handle burst traffic. The rate limiter must be designed to distinguish between burst tolerance and sustained throughput control.
Decide on strategies to employ if Redis fails. For public APIs, allow traffic if Redis fails and pair with monitoring alerts.
Proxies are created during the post-initialization phase of the bean lifecycle, specifically inside BeanPostProcessor.postProcessAfterInitialization() . The problems that can arise at this stage are:
@Transactional won’t work in constructors.
Internal method calls bypass transactions.
@PostConstruct runs on the raw object, not the proxy.
Self-invocation breaks AOP because calls passing through the proxy are intercepted.
The core differences between WebClient and RestClient are:
Reactive HTTP client (Project Reactor)
Blocking HTTP client
One thread per request
RestTemplate (Reactive alternative)
RestTemplate (modern blocking replacement)
Architectural implications
Debugging is harder.
Lower memory consumption per request.
Context switching is reduced.
Better scalability in high-latency, I/O-heavy systems.
Debugging is easier.
Memory usage increases under load.
Context switching overhead increases with concurrency.
Scaling requires more threads.
In Kubernetes, liveness and readiness probes allow the orchestrator to determine whether a container should be restarted or receive traffic. Spring Boot Actuator exposes these endpoints:
/actuator/health/liveness checks whether the application context is running and not in a broken state.
/actuator/health/readiness depends on external dependencies such as database connectivity or downstream services.
Optimistic locking is a concurrency control mechanism that prevents lost updates when multiple transactions modify the same record. You enable it by adding a @Version field to your entity, either as an int , long , or timestamp . Each time the entity is updated, Hibernate automatically increments the version value and includes it in the WHERE clause of the SQL statement.
Projection interfaces allow you to retrieve only specific fields from an entity, rather than loading the entire object. Spring Data dynamically implements this interface at runtime and maps query results to them. When the interface defines getter methods that match entity fields, the generated SQL selects only the requested columns.
Spring Data JPA supports three types of projections:
Graceful shutdown in Spring Boot ensures that the application stops accepting new requests while allowing current and long-running tasks to complete safely. You enable it by setting server.shutdown=graceful in your application properties file. When shutdown is triggered, the embedded server stops accepting new connections, and existing requests are allowed to finish within a set period.
Spring Boot auto-configures a shared ObjectMapper for JSON serialization and deserialization using Jackson. To customize an existing ObjectMapper, define a @Bean of type Jackson2ObjectMapperBuilderCustomizer . This allows you to adjust settings while keeping Spring Boot’s defaults. This ensures consistency across controllers, HTTP message converters, restful web services, and avoids bugs caused by inconsistently configured mappers.
Constructor injection is preferred over field injection because it enforces immutability and makes dependencies explicit. Constructor injection ensures that the bean is always in a valid state by requiring all Spring Boot dependencies to be provided at object creation time. It improves clarity, supports immutability, triggers early detection of circular dependencies, and aligns with clean architectural principles.
The differences between Mono and Flux are:
Represents 0 or 1 element
Represents 0 to N elements
Single value or empty
Multiple values or empty
Fetching a single record, single HTTP response
Streaming multiple records, continuous events or collections
Transformation, filtering and combining (map, flatMap)
Same as Mono plus operators for multiple elements (concat, merge)
You can enable logging.level.org.springframework.boot.StartupInfoLogger=DEBUG to view context creation and bean instantiation durations. For deeper, low-level analysis, use tools like Async Profiler or Java Flight Recorder.
Mastering the intricacies of Spring Boot concepts and their application in real-world systems is invaluable. To be considered a strong candidate, you need to articulate your Spring Boot knowledge logically: Define concepts, explain how Spring Boot simplifies implementation, explain design decisions, and production implications.
There is a structured Java and Spring Boot roadmap to guide you from beginner to pro. Also, remember to always use the AI Tutor for mock interviews and deeper insights.