Skip to content

Spring Boot Interview Questions and Answers for 8+ Years Experience

Why Spring Boot instead of Spring Framework?

Section titled “Why Spring Boot instead of Spring Framework?”

Spring Boot simplifies development by reducing configuration.

Advantages

  • Auto Configuration
  • Embedded servers (Tomcat, Jetty)
  • Starter dependencies
  • Production-ready features
  • Minimal XML configuration

It combines:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {
}

More precisely, it’s meta-annotated with @SpringBootConfiguration (which is itself annotated with @Configuration), @EnableAutoConfiguration, and @ComponentScan:

flowchart TD
    A["@SpringBootApplication"]
    A --> B["@SpringBootConfiguration"]
    A --> C["@EnableAutoConfiguration"]
    A --> D["@ComponentScan"]

Purpose:

  • Enables configuration
  • Enables auto configuration
  • Performs component scanning

Auto configuration creates beans automatically based on classpath dependencies.

Example:

If spring-boot-starter-data-jpa is present, Spring Boot configures:

  • DataSource
  • EntityManager
  • Hibernate
flowchart LR
A[Application Starts] --> B[Read Classpath]
B --> C{Dependency Found?}
C -->|JPA| D[Configure DataSource]
C -->|Web| E[Configure Tomcat & MVC]
D --> F[Application Ready]
E --> F
Starter Purpose
spring-boot-starter-web Web APIs
spring-boot-starter-data-jpa JPA/Hibernate
spring-boot-starter-security Security
spring-boot-starter-test Testing
spring-boot-starter-validation Bean Validation (Hibernate Validator)
spring-boot-starter-actuator Monitoring and health endpoints
spring-boot-starter-cache Caching with Redis/Ehcache
spring-boot-starter-amqp Messaging with RabbitMQ
spring-boot-starter-kafka (from spring-kafka) Messaging with Kafka
Scope Description
Singleton One instance per container
Prototype New instance every request
Request One per HTTP request
Session One per session
Application One per servlet context
@Scope("prototype")
@Component
class MyBean {}
flowchart TD
A[Bean Request] --> B{Scope}
B -->|Singleton| C[Reuse one container instance]
B -->|Prototype| D[Create new instance]
B -->|Request| E[One per HTTP request]
B -->|Session| F[One per HTTP session]
B -->|Application| G[One per ServletContext]
Feature Spring Singleton Plain Java Singleton
Scope Per Spring container Per JVM
Creation Managed by Spring Manual
Lifecycle Spring-managed Developer-managed
Dependency Injection Supported Not supported

Plain Java singleton example:

class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance() {
return instance;
}
}

Using @Qualifier

@Autowired
@Qualifier("emailService")
private NotificationService service;

Using @Primary

@Primary
@Component
class EmailService {}
@PostConstruct
public void init() {
System.out.println("Bean initialized");
}

Common use cases: cache initialization, loading reference data, warming database connections, preloading configuration.

@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping
public List<Product> getProducts() {
return productService.getProducts();
}
}

Common annotations used to build the controller:

Annotation Purpose
@RestController Marks a class as a REST controller
@RequestMapping Base URL mapping
@GetMapping Handles HTTP GET requests
@PostMapping Handles HTTP POST requests
@PutMapping Handles HTTP PUT requests
@DeleteMapping Handles HTTP DELETE requests

Request flow through the layers:

flowchart LR
A[HTTP Request] --> B[DispatcherServlet]
B --> C[REST Controller]
C --> D[Service Layer]
D --> E[Repository]
E --> D
D --> C
C --> F[JSON Response]
Feature @RequestParam @PathVariable @RequestBody
Data Location Query parameters URL path Request body
Typical Use Filtering, optional values Resource identification Sending objects
Example URL /products?type=mobile /products/101 JSON payload
Common HTTP Methods Mostly GET GET/PUT/DELETE POST/PUT
@GetMapping("/products")
public List<Product> getProducts(@RequestParam String type)
@GetMapping("/products/{id}")
public Product getProduct(@PathVariable Long id)
@PostMapping("/products")
public Product createProduct(@RequestBody Product product)
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
return ResponseEntity.status(500).body(ex.getMessage());
}
}
flowchart LR
A[Controller] -->|Throws Exception| B[ControllerAdvice]
B --> C[@ExceptionHandler]
C --> D[ResponseEntity]
Feature @ControllerAdvice @ExceptionHandler
Purpose Global exception handling Handles a specific exception
Scope All controllers Individual handler method
Level Class Method
Feature JPA Hibernate Spring Data JPA
Type Specification Implementation Framework built on JPA
Developed by Java Hibernate team Spring
Purpose Defines ORM standard Implements ORM Simplifies data access
Query Support JPQL HQL Method names, JPQL, Native
Boilerplate More code Medium Very little
Example EntityManager SessionFactory JpaRepository
flowchart TD
    A[Spring Data JPA] --> B[JPA Specification]
    B --> C[Hibernate]
    C --> D[(Database)]

The same save operation at each layer:

// JPA
EntityManager.persist(employee);
// Hibernate
session.save(employee);
// Spring Data JPA
employeeRepository.save(employee);
@OneToMany(fetch = FetchType.LAZY)
private List<Order> orders;
Fetch Type Description
Lazy Load related entities only when accessed
Eager Load related entities immediately

Default fetch types by relationship:

Relationship Default
@ManyToOne EAGER
@OneToMany LAZY
List<User> findByAgeGreaterThan(int age);

See the JPA persistence fundamentals guide for more derived query examples, common keyword combinations, and the JPQL/native query alternative.

  • Atomicity
  • Consistency
  • Isolation
  • Durability
@Transactional
public void transfer() {}
Type Description
REQUIRED Join existing transaction
REQUIRES_NEW New transaction
SUPPORTS Use existing if present
NOT_SUPPORTED No transaction
MANDATORY Must run inside an existing transaction
NEVER Must not run inside a transaction
NESTED Create a nested transaction

Why @Transactional Doesn’t Work on Private Methods

Section titled “Why @Transactional Doesn’t Work on Private Methods”

Two separate issues combine here:

  1. Private methods can’t be proxied at all. CGLIB (subclass) proxies can’t override private methods, so @Transactional on a private method is silently ignored regardless of how it’s called.
  2. Self-invocation bypasses the proxy, even for public methods. Calling saveOrder() from inside the same class resolves to this.saveOrder() — the raw object — not the proxy wrapping it. So even if saveOrder() were public, calling it internally from placeOrder() would still skip the transactional behavior; only calls arriving through the proxy from outside the class trigger it.
@Service
public class OrderService {
public void placeOrder() {
saveOrder();
}
@Transactional
private void saveOrder() {
// Transaction will NOT start - private methods aren't proxied,
// and this is also a self-invoked call either way.
}
}

Isolation levels exist to prevent these concurrency problems, in increasing order of strictness:

Problem Description
Dirty Read Reading uncommitted data
Non-repeatable Read Same query returns different values
Phantom Read Additional rows appear in repeated queries
Isolation Description
READ_UNCOMMITTED Dirty reads allowed
READ_COMMITTED Reads committed data only
REPEATABLE_READ Prevents non-repeatable reads
SERIALIZABLE Highest isolation
@Transactional(isolation = Isolation.REPEATABLE_READ)

Typical defaults: MySQL uses REPEATABLE_READ; PostgreSQL uses READ_COMMITTED.

  • Use @Transactional in the service layer, not in controllers.
  • Prefer @Transactional(readOnly = true) for read operations.
  • Configure rollback rules explicitly when needed.
@Transactional(readOnly = true)
@Transactional(rollbackFor = Exception.class)
sequenceDiagram
participant Service
participant Eureka
participant Client
Service->>Eureka:Register
Client->>Eureka:Lookup Service
Eureka-->>Client:Instance Details
Client->>Service:Invoke API
  • Routing
  • Authentication
  • Logging
  • Rate limiting

Common endpoints:

  • /actuator/health
  • /actuator/metrics
  • /actuator/info
  1. Capture request
  2. Reproduce locally
  3. Enable logs
  4. Debug
  5. Analyze stack trace
logging.level.root=DEBUG
Authentication Authorization
Identity verification Access control
sequenceDiagram
participant User
participant Server
User->>Server: Login
Server-->>User: JWT Token
User->>Server: Bearer Token
Server-->>User: Protected Resource

Senior-Level Spring Boot Interview Questions (Not Covered in Basics)

Section titled “Senior-Level Spring Boot Interview Questions (Not Covered in Basics)”
  • How does auto configuration determine which configuration classes to load?
  • Explain @ConditionalOnClass, @ConditionalOnMissingBean, and @ConditionalOnProperty.
  • What happens internally during SpringApplication.run()?
  • What is ApplicationContextInitializer?
  • Explain Spring Boot application events.
  • How do you create a custom Spring Boot starter?
  • application.properties vs application.yml
  • Externalized configuration
  • @ConfigurationProperties vs @Value
  • Dynamic configuration refresh
  • Spring Cloud Config
  • Multiple active profiles
  • Reduce startup time
  • Reduce memory footprint
  • Optimize connection pools
  • Solve LazyInitializationException
  • Scale to millions of requests
  • Thread pool tuning
  • @Cacheable
  • @CachePut
  • @CacheEvict
  • Redis integration
  • Distributed caching
  • Cache stampede prevention
  • Synchronous vs asynchronous communication
  • Saga pattern
  • API composition
  • Idempotency
  • Kafka duplicate message handling
  • Centralized logging
  • @SpringBootTest
  • @WebMvcTest
  • @DataJpaTest
  • Integration testing
  • Mocking dependencies
  • Kafka testing
  • Prometheus
  • Grafana
  • Spring Boot Actuator metrics
  • Distributed tracing
  • Spring Cloud Sleuth
  • Kubernetes deployment
  • Readiness vs Liveness probes
  • Zero downtime deployment
  • CI/CD pipelines
  • Order Management System
  • Payment Service
  • Notification Service
  • Large File Upload Service
  • API Rate Limiter
  • Explain your architecture.
  • Biggest production issue solved.
  • Performance improvements delivered.
  • Most difficult debugging experience.
  • High availability design decisions.

Use this structure:

  1. Definition
  2. Internal working
  3. Practical example
  4. Real-world use case
  • Senior interviews focus heavily on internals, architecture, and production scenarios.
  • Master auto configuration, transactions, JPA performance, caching, and observability.
  • Be prepared to explain real project decisions and trade-offs.
  • Practice system design and microservices patterns alongside Spring Boot fundamentals.