Top 60 Spring Interview Questions (2026)

The 60 Spring questions interviewers actually ask, with direct answers, runnable code, and what the interviewer is listening for. Grouped for freshers, intermediate, and experienced rounds.

60 questions with answers

What Is Spring?

Key Takeaways

  • Spring is an open-source Java framework built around dependency injection and an inversion-of-control container that wires your objects together.
  • The Spring Framework is the core (beans, context, AOP, transactions); Spring Boot, Spring Data, and Spring Security are projects layered on top.
  • Interviews test how well you understand the container, bean scopes and lifecycle, AOP, and transactions, not just annotation names.
  • This page is a question bank: work your tier first, read one tier up, and say answers out loud because delivery is evaluated too.

Spring is an open-source application framework for Java, first released in 2003, that manages the objects your program depends on so you don't wire them by hand. Its core idea is inversion of control: instead of your code creating and connecting its collaborators, a container does it and injects them where needed, which the Spring team calls dependency injection. Around that core sit modules for aspect-oriented programming, data access, transactions, web MVC, and security, and higher-level projects like Spring Boot that remove most configuration. In interviews, Spring questions probe how the container works (bean definitions, scopes, lifecycle callbacks), how AOP and transactions apply behavior through proxies, and how you'd structure a real service, not memorized annotation lists. According to the Spring Framework Reference, the IoC container is the heart of the framework and the org.springframework.context.ApplicationContext interface represents it. This page collects the 60 questions that come up most, each with a direct answer and runnable code. Increasingly the first Spring round is a live AI coding interview, so pair this bank with our AI interview preparation guides for the format side.

60Questions with answers on this page
3Difficulty tiers: freshers, intermediate, experienced
20+Runnable code snippets you can practice from
45-60 minTypical length of a Spring technical round

Watch: Spring Boot Tutorial for Beginners (Java Framework)

Video: Spring Boot Tutorial for Beginners (Java Framework) (freeCodeCamp.org, YouTube)

Test yourself and earn a certificate

10 quick questions. Score 70%+ to download your Spring certificate.

Jump to quiz

All Questions on This Page

60 questions
Spring Interview Questions for Freshers
  1. 1. What is the Spring Framework and why is it used?
  2. 2. What is Inversion of Control (IoC) and how does dependency injection relate to it?
  3. 3. What are the types of dependency injection in Spring?
  4. 4. What is a Spring bean?
  5. 5. What is the difference between BeanFactory and ApplicationContext?
  6. 6. What are bean scopes in Spring?
  7. 7. What is the difference between singleton and prototype scope?
  8. 8. What does @Autowired do?
  9. 9. How do you resolve ambiguity when multiple beans match a type?
  10. 10. What is the difference between @Component, @Service, @Repository, and @Controller?
  11. 11. What do @Configuration and @Bean do?
  12. 12. What is the difference between Spring Framework and Spring Boot?
  13. 13. What are the ways to configure a Spring application?
  14. 14. How does Spring MVC handle a web request?
  15. 15. What is the difference between @Controller and @RestController?
  16. 16. What do @RequestMapping and the HTTP method shortcuts do?
  17. 17. What is the difference between @PathVariable and @RequestParam?
  18. 18. What do @RequestBody and @ResponseBody do?
  19. 19. What is JdbcTemplate and what problem does it solve?
  20. 20. What is Spring Data JPA and how does a repository work?
  21. 21. How does Spring Boot handle external configuration?
  22. 22. What are Spring profiles?
  23. 23. What does the @Value annotation do?
  24. 24. What does @SpringBootApplication do and how does a Boot app start?
Spring Intermediate Interview Questions
  1. 25. Walk through the Spring bean lifecycle.
  2. 26. What do @PostConstruct and @PreDestroy do?
  3. 27. What is aspect-oriented programming (AOP) in Spring?
  4. 28. Explain the core AOP terms: aspect, advice, pointcut, join point.
  5. 29. How does @Transactional work?
  6. 30. What is transaction propagation and what are the common settings?
  7. 31. What are transaction isolation levels?
  8. 32. Why is constructor injection preferred over field injection?
  9. 33. How does Spring handle circular dependencies, and how do you fix one?
  10. 34. How does Spring Security handle authentication and authorization?
  11. 35. How do you handle exceptions globally in Spring MVC?
  12. 36. How does validation work in Spring?
  13. 37. What are Spring Boot starters and auto-configuration?
  14. 38. What is Spring Boot Actuator?
  15. 39. How do you call another HTTP service from Spring?
  16. 40. What is the difference between CrudRepository, JpaRepository, and PagingAndSortingRepository?
  17. 41. What is the difference between lazy and eager loading in JPA, and what is the N+1 problem?
  18. 42. What is the Spring application event mechanism?
  19. 43. How do you run asynchronous or scheduled tasks in Spring?
  20. 44. How do you inject a prototype bean into a singleton so you get a fresh instance each time?
Spring Interview Questions for Experienced Developers
  1. 45. How does Spring create proxies: JDK dynamic proxies vs CGLIB?
  2. 46. Why does calling a @Transactional method from within the same class not start a transaction?
  3. 47. What is a BeanPostProcessor and how does Spring use it internally?
  4. 48. What is the difference between BeanPostProcessor and BeanFactoryPostProcessor?
  5. 49. How does Spring Boot auto-configuration decide what to configure?
  6. 50. How would you build a custom Spring Boot starter or auto-configuration?
  7. 51. How does Spring's declarative transaction management actually work under the hood?
  8. 52. When would you choose Spring WebFlux over Spring MVC?
  9. 53. How do Java 21 virtual threads affect Spring applications?
  10. 54. How do you test a Spring Boot application at different layers?
  11. 55. What is the difference between @Mock, @MockBean, and @Autowired in tests?
  12. 56. How does graceful shutdown work in Spring Boot, and why does it matter?
  13. 57. How do you manage configuration and service discovery across many Spring services?
  14. 58. How do you make Spring service-to-service calls resilient?
  15. 59. How do you improve Spring Boot startup time and memory footprint?
  16. 60. A Spring endpoint is slow in production. Walk through how you'd diagnose it.

Spring Interview Questions for Freshers

Freshers24 questions

The fundamentals every entry-level round checks. If any answer here surprises you, that's your study list.

Q1. What is the Spring Framework and why is it used?

Spring is an open-source Java framework whose core job is managing the objects your application depends on. Instead of your classes creating and connecting their own collaborators, a Spring container does it and injects them, which keeps components loosely coupled.

Teams use it because that wiring, plus built-in support for transactions, data access, web MVC, and security, removes a lot of boilerplate and makes code easier to test. Spring Boot builds on it to remove most configuration too.

Key point: A one-line definition (dependency injection and an IoC container) plus one concrete benefit (testability, loose coupling) beats a memorized feature list. This is usually the opener.

Watch a deeper explanation

Video: Spring Boot Tutorial for Beginners [2025] (Programming with Mosh, YouTube)

Q2. What is Inversion of Control (IoC) and how does dependency injection relate to it?

Inversion of control means your objects don't create their own dependencies; something external (the Spring container) creates them and hands them over. Control of construction is inverted from your code to the framework.

Dependency injection is the specific way Spring does IoC: it injects the needed objects through a constructor, setter, or field. IoC is the principle; DI is the technique.

java
// Without DI: the class creates its own dependency (tight coupling)
class OrderService {
    private final EmailClient email = new SmtpEmailClient();
}

// With DI: the dependency is injected (loose coupling)
class OrderService {
    private final EmailClient email;
    OrderService(EmailClient email) { this.email = email; }
}

Key point: the question needs you to separate the concept (IoC) from the mechanism (DI). Muddling them is the most common freshers mistake.

Q3. What are the types of dependency injection in Spring?

Constructor injection passes dependencies through the constructor; setter injection sets them via setter methods after construction; field injection puts them directly on fields with @Autowired.

The Spring team recommends constructor injection for required dependencies because it makes them explicit and mandatory, allows final fields, and lets you build the object in a test without the container. Setter injection suits optional dependencies. Field injection is discouraged because it hides dependencies and needs reflection to test.

java
@Service
class ReportService {
    private final Repo repo;
    // constructor injection: preferred, works without @Autowired since one constructor
    ReportService(Repo repo) {
        this.repo = repo;
    }
}
TypeHowBest for
ConstructorVia constructor paramsRequired dependencies (recommended)
SetterVia setter methodsOptional or reconfigurable dependencies
Field@Autowired on fieldDiscouraged: hard to test, hidden deps

Key point: Saying constructor injection is preferred, and why (final fields, testable without the container), is the answer that indicates real experience.

Q4. What is a Spring bean?

A bean is any object that the Spring IoC container creates, configures, and manages. If the container owns its lifecycle, it's a bean; a plain object you new up yourself is not.

You tell Spring about beans through stereotype annotations (@Component and friends) picked up by component scanning, or through @Bean methods in a @Configuration class.

java
@Configuration
class AppConfig {
    @Bean
    EmailClient emailClient() {   // this returned object is a managed bean
        return new SmtpEmailClient();
    }
}

Q5. What is the difference between BeanFactory and ApplicationContext?

BeanFactory is the basic container that instantiates and wires beans lazily. ApplicationContext is a superset that adds event publishing, internationalization message sources, resource loading, and eager instantiation of singletons at startup.

In practice you almost always use ApplicationContext; BeanFactory shows up mainly in memory-constrained or embedded scenarios. Naming ApplicationContext as the everyday container is the expected answer.

FeatureBeanFactoryApplicationContext
Bean creationLazyEager for singletons
EventsNoYes
i18n / messagesNoYes
Typical useRare, constrainedAlmost always

Q6. What are bean scopes in Spring?

A scope controls how many instances of a bean the container creates and how long they live. singleton (the default) means one shared instance per container; prototype means a new instance on every request for the bean.

In web applications there are also request, session, and application scopes, tied to the HTTP request, user session, and servlet context. Singleton beans must be stateless because they're shared across all callers.

java
@Component
@Scope("prototype")
class ReportBuilder { }   // new instance each time it is requested

Key point: The follow-up is 'why must singleton beans be thread-safe?' Have the answer ready: one instance serves every concurrent caller.

Q7. What is the difference between singleton and prototype scope?

A singleton bean is created once and the same instance is returned every time it's injected or looked up. A prototype bean is created fresh on each request, so every injection point gets its own instance.

Singletons hold no per-call state; prototypes are for stateful, short-lived objects. Also worth knowing: Spring fully manages the singleton lifecycle including destruction, but for prototypes it stops after handing the object over.

SingletonPrototype
InstancesOne per containerOne per request
StateMust be statelessCan hold state
Destroy callbackContainer runs itClient's responsibility

Q8. What does @Autowired do?

@Autowired tells Spring to inject a matching bean at that point: a constructor, setter, or field. By default it resolves by type, and if exactly one matching bean exists, Spring wires it in.

If no matching bean is found it fails at startup, unless you mark the injection optional with required=false, Optional, or @Nullable. On a class with a single constructor, @Autowired is now implied and can be omitted.

java
@Service
class Checkout {
    private final PaymentGateway gateway;
    // @Autowired optional here: single constructor
    Checkout(PaymentGateway gateway) {
        this.gateway = gateway;
    }
}

Q9. How do you resolve ambiguity when multiple beans match a type?

When two beans satisfy the same type, @Autowired can't pick one and startup fails. You disambiguate with @Qualifier("beanName") at the injection point, or mark one bean @Primary so it wins by default.

@Primary sets the fallback choice for the whole context; @Qualifier makes the choice at a specific injection point. Use @Primary for the common default and @Qualifier for the exceptions.

java
@Component @Primary
class SmtpEmailClient implements EmailClient { }

@Component
class SesEmailClient implements EmailClient { }

@Service
class Notifier {
    Notifier(@Qualifier("sesEmailClient") EmailClient client) { }  // override the primary
}

Q10. What is the difference between @Component, @Service, @Repository, and @Controller?

All four register a class as a Spring bean via component scanning. @Component is the generic stereotype; @Service, @Repository, and @Controller are specializations that carry the same behavior plus semantic meaning about the layer.

Two carry extra behavior: @Repository adds automatic translation of persistence exceptions into Spring's DataAccessException hierarchy, and @Controller marks a web MVC handler. Using the specific stereotype makes the architecture readable at a glance.

AnnotationLayerExtra behavior
@ComponentGenericNone
@ServiceBusiness logicNone (semantic only)
@RepositoryData accessException translation
@ControllerWebMVC request handling

Q11. What do @Configuration and @Bean do?

@Configuration marks a class as a source of bean definitions. Inside it, methods annotated @Bean return objects that Spring registers and manages as beans, using the method name as the bean name by default.

This is the Java-based alternative to XML configuration and to component scanning. You reach for @Bean when you need to construct a bean with custom logic or wire a third-party class you can't annotate.

java
@Configuration
class DataConfig {
    @Bean
    DataSource dataSource() {
        var ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:postgresql://localhost/app");
        return ds;   // Spring manages this third-party object as a bean
    }
}

Q12. What is the difference between Spring Framework and Spring Boot?

Spring Framework is the core: the container, dependency injection, AOP, transactions, and the web stack. Spring Boot sits on top and removes configuration through auto-configuration, starter dependencies, and an embedded server, so you can run a standalone app with almost no setup.

Boot doesn't replace the framework; it opinionatedly configures it. A Boot app is still a Spring app underneath. Explaining that layering is exactly what this question checks.

Spring FrameworkSpring Boot
ConfigurationExplicit, manualAuto-configured
ServerYou supply oneEmbedded (Tomcat/Netty)
DependenciesPick each oneStarter bundles
GoalFlexibilityFast standalone apps

Key point: The trap is treating them as competitors. They're layers: framework at the bottom, Boot on top.

Watch a deeper explanation

Video: Spring Boot Quick Start 1 - Introduction (Java Brains, YouTube)

Q13. What are the ways to configure a Spring application?

Three styles: XML configuration (the original, now rare), annotation-based configuration with component scanning and stereotypes, and Java-based configuration with @Configuration and @Bean classes.

Modern apps use annotations plus Java config, and Spring Boot pushes almost everything into auto-configuration and properties files. XML shows up mainly in older codebases.

Q14. How does Spring MVC handle a web request?

A single front controller, the DispatcherServlet, receives every request. It consults handler mappings to find the right controller method, invokes it, and the method returns either a view name or, for REST, a serialized body.

For a view, a view resolver turns the name into a template that gets rendered. For REST, @ResponseBody (or @RestController) serializes the return value straight to the response, usually as JSON.

java
@RestController
@RequestMapping("/api/users")
class UserController {
    @GetMapping("/{id}")
    User getUser(@PathVariable Long id) {
        return userService.find(id);   // serialized to JSON
    }
}

Q15. What is the difference between @Controller and @RestController?

@Controller is the general web stereotype; its methods usually return a view name that a template engine renders. @RestController is @Controller plus @ResponseBody applied to every method, so return values are serialized directly to the response body.

Use @RestController for JSON APIs and @Controller when you're rendering server-side HTML views. Mixing them up is a common cause of getting a view-name string in your JSON response.

Q16. What do @RequestMapping and the HTTP method shortcuts do?

@RequestMapping maps a URL pattern (and optionally an HTTP method, headers, or content type) to a handler method or an entire controller class. The shortcuts @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, and @PatchMapping are method-specific forms of it.

Prefer the shortcuts on methods for readability and put a shared base path in a class-level @RequestMapping.

java
@RestController
@RequestMapping("/api/orders")
class OrderController {
    @GetMapping        List<Order> list() { ... }
    @PostMapping       Order create(@RequestBody Order o) { ... }
    @DeleteMapping("/{id}") void delete(@PathVariable Long id) { ... }
}

Q17. What is the difference between @PathVariable and @RequestParam?

@PathVariable binds a value embedded in the URL path (/users/42, the 42), so it's for identifying a resource. @RequestParam binds a query-string or form parameter (/users?role=admin, the role), so it's for filters and options.

Rule of thumb: identity in the path, refinement in the query. @RequestParam also supports defaults and required=false; path variables are part of the route and always present.

java
@GetMapping("/users/{id}")
User getUser(@PathVariable Long id,
             @RequestParam(defaultValue = "summary") String view) {
    return userService.find(id, view);
}

Q18. What do @RequestBody and @ResponseBody do?

@RequestBody tells Spring to deserialize the incoming HTTP request body (usually JSON) into a method parameter object using a message converter like Jackson. @ResponseBody does the reverse: it serializes the return value into the response body instead of treating it as a view name.

@RestController applies @ResponseBody to every method, which is why REST controllers rarely write it explicitly.

Q19. What is JdbcTemplate and what problem does it solve?

JdbcTemplate is Spring's helper for raw JDBC. It handles the repetitive plumbing: opening and closing connections and statements, iterating result sets, and translating SQL exceptions into Spring's DataAccessException hierarchy, so you write only the query and the row mapping.

It sits below JPA and Spring Data. Reach for it when you want direct SQL control without hand-writing boilerplate.

java
int count = jdbcTemplate.queryForObject(
    "SELECT count(*) FROM users WHERE active = ?",
    Integer.class, true);

Q20. What is Spring Data JPA and how does a repository work?

Spring Data JPA lets you define a repository interface and get a working implementation for free. You extend JpaRepository, and Spring generates CRUD methods plus derived queries from method names like findByEmail at startup.

You write no implementation class. For anything the naming convention can't express, you add an @Query with JPQL or native SQL.

java
interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);          // derived query
    List<User> findByActiveTrueOrderByCreatedAtDesc(); // derived query
}

Q21. How does Spring Boot handle external configuration?

Spring Boot reads configuration from application.properties or application.yml, environment variables, command-line arguments, and profile-specific files, then merges them with a defined precedence. You inject values with @Value or, better, bind a group of them to a typed class with @ConfigurationProperties.

Profiles (application-dev.yml, application-prod.yml) switch configuration per environment. Secrets should come from the environment or a secret manager, never the committed file.

java
@ConfigurationProperties(prefix = "mail")
class MailProps {
    private String host;
    private int port;
    // getters/setters; bound from mail.host, mail.port
}

Q22. What are Spring profiles?

Profiles let you group beans and configuration per environment and activate a set at runtime. A bean or config class marked @Profile("prod") only loads when the prod profile is active, so dev, test, and prod can wire different implementations.

You activate a profile with spring.profiles.active in properties, an environment variable, or a command-line flag. Common use: an in-memory database for dev and the real one for prod.

Q23. What does the @Value annotation do?

@Value injects a value from external configuration into a field or parameter, resolving property placeholders like ${server.port} or Spring Expression Language expressions like #{2 * 60}. It reads from properties files, YAML, environment variables, and command-line arguments.

For a single loose value @Value is fine, but for a group of related settings @ConfigurationProperties binding a typed class is cleaner and easier to validate. Reaching for the typed binding on real config signals experience.

java
@Component
class Mailer {
    @Value("${mail.host}")
    private String host;

    @Value("${mail.retries:3}")   // default 3 if property missing
    private int retries;
}

Q24. What does @SpringBootApplication do and how does a Boot app start?

@SpringBootApplication is a shortcut for three annotations: @SpringBootConfiguration (a @Configuration class), @EnableAutoConfiguration (turn on Boot's auto-configuration), and @ComponentScan (scan this package and below for beans). One annotation on the main class sets up the whole application.

SpringApplication.run() in main() bootstraps the context: it creates the ApplicationContext, runs auto-configuration, starts the embedded server, and the app is live. That single run call is the entry point of every Boot service.

java
@SpringBootApplication
class StoreApplication {
    public static void main(String[] args) {
        SpringApplication.run(StoreApplication.class, args);
    }
}
Back to question list

Spring Intermediate Interview Questions

Intermediate20 questions

For candidates with working experience: container mechanics, AOP, transactions, and the questions that separate users from understanders.

Q25. Walk through the Spring bean lifecycle.

The container instantiates the bean, injects its dependencies, and then runs a series of callbacks before the bean is ready: aware interfaces, BeanPostProcessor before-init hooks, the init callback (@PostConstruct, then InitializingBean.afterPropertiesSet, then a custom init-method), and BeanPostProcessor after-init hooks. At shutdown it runs @PreDestroy, then DisposableBean.destroy, then a custom destroy-method.

The BeanPostProcessor hooks matter because that's where Spring itself applies proxies for AOP and transactions. Knowing the init order (@PostConstruct before afterPropertiesSet) signals real depth.

Bean lifecycle order

1Instantiate
constructor called, dependencies injected
2Aware + post-process (before init)
BeanPostProcessor may wrap the bean in a proxy
3Initialize
@PostConstruct, then afterPropertiesSet, then custom init-method
4Ready, then destroy
in use; at shutdown @PreDestroy, destroy(), custom destroy-method

AOP and transaction proxies are applied during the post-processing step, which is why @Transactional works.

Key point: Naming @PostConstruct before afterPropertiesSet, and mentioning that BeanPostProcessor is where proxies get applied, is the intermediate-to-production signal.

Watch a deeper explanation

Video: Spring Boot Tutorials | Full Course (Telusko, YouTube)

Q26. What do @PostConstruct and @PreDestroy do?

@PostConstruct marks a method to run once after the bean is constructed and its dependencies are injected, for initialization that needs the wired dependencies. @PreDestroy marks a method to run before the container removes the bean, for cleanup like closing connections.

They're the annotation-based, framework-neutral way to hook the lifecycle, preferred over implementing InitializingBean and DisposableBean because they don't couple your class to Spring interfaces.

java
@Component
class CacheWarmer {
    @PostConstruct void warm()  { load(); }   // after injection
    @PreDestroy   void flush() { persist(); } // before shutdown
}

Q27. What is aspect-oriented programming (AOP) in Spring?

AOP lets you apply behavior that cuts across many methods (logging, security checks, transactions, metrics) in one place instead of scattering it through every method. You write an aspect that says what to do (advice) and where to apply it (a pointcut).

Spring AOP is proxy-based: at startup it wraps matching beans in a proxy that runs the advice around the real method. That's the mechanism behind @Transactional and method-level security.

java
@Aspect @Component
class TimingAspect {
    @Around("execution(* com.app.service..*(..))")
    Object time(ProceedingJoinPoint pjp) throws Throwable {
        long t = System.nanoTime();
        try { return pjp.proceed(); }
        finally { log.info("{} ns", System.nanoTime() - t); }
    }
}

Q28. Explain the core AOP terms: aspect, advice, pointcut, join point.

A join point is a point in execution where advice can apply; in Spring AOP that's always a method call. A pointcut is an expression that selects which join points to match. Advice is the code that runs (before, after, around). An aspect bundles pointcuts and advice into one module.

The types of advice: @Before, @After (finally), @AfterReturning, @AfterThrowing, and @Around, which is the most flexible because it wraps the call and controls whether it proceeds.

TermMeaning
Join pointA method execution where advice can run
PointcutExpression selecting matching join points
AdviceCode that runs at a join point
AspectModule bundling pointcuts and advice

Q29. How does @Transactional work?

@Transactional wraps a method in a database transaction: Spring's AOP proxy opens a transaction before the method, commits if it returns normally, and rolls back on failure. By default it rolls back on unchecked exceptions and Errors, and commits on checked exceptions unless you set rollbackFor.

Because it's proxy-based, an internal self-call (this.other()) inside the same bean bypasses the proxy and the transaction won't apply. That gotcha is a favorite follow-up.

java
@Service
class TransferService {
    @Transactional
    void transfer(Account from, Account to, BigDecimal amt) {
        from.withdraw(amt);
        to.deposit(amt);   // both persist, or neither does
    }
}

Key point: The self-invocation gotcha (a private/internal call skips the proxy so @Transactional does nothing) is the question behind the question. Volunteer it.

Q30. What is transaction propagation and what are the common settings?

Propagation decides what happens when a transactional method calls another transactional method: does it join the existing transaction or start a new one? REQUIRED (the default) joins an existing transaction or starts one if none exists. REQUIRES_NEW always suspends any current transaction and starts an independent one.

Others: SUPPORTS (join if present, else run non-transactionally), MANDATORY (must already be in one), NESTED (a savepoint inside the current one). REQUIRES_NEW is the one to know: it's how you commit an audit log even if the outer transaction rolls back.

PropagationBehavior
REQUIREDJoin existing or start new (default)
REQUIRES_NEWSuspend current, start independent one
SUPPORTSJoin if present, else non-transactional
MANDATORYMust run inside an existing transaction
NESTEDSavepoint within the current transaction

Q31. What are transaction isolation levels?

Isolation controls how much one transaction sees of another's uncommitted or in-flight changes, trading consistency against concurrency. From loosest to strictest: READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE.

DEFAULT uses the database's own default (often READ_COMMITTED). Each step up prevents another anomaly (dirty reads, non-repeatable reads, phantom reads) but costs concurrency. Naming the anomalies is what separates a memorized list from understanding.

  • READ_UNCOMMITTED: allows dirty reads; almost never used.
  • READ_COMMITTED: no dirty reads; the common default.
  • REPEATABLE_READ: same row reads stay consistent within the transaction.
  • SERIALIZABLE: strictest, transactions behave as if run one at a time.

Q32. Why is constructor injection preferred over field injection?

Constructor injection makes dependencies explicit and required: you can't construct the object without them, they can be final (immutable), and you can build it in a plain unit test with new, no container needed. Field injection hides dependencies, allows partly-constructed objects, and needs reflection or the container to test.

Constructor injection also surfaces a design smell: if the constructor has eight parameters, the class is doing too much. Field injection quietly hides that.

java
// testable without Spring
var svc = new ReportService(new FakeRepo());

// field injection would force a container or reflection to set the field

Key point: Mentioning testability without the container and the 'too many params is a smell' point is the answer that lands.

Q33. How does Spring handle circular dependencies, and how do you fix one?

If bean A needs B and B needs A through constructor injection, Spring can't build either first and throws a BeanCurrentlyInCreationException at startup. With setter or field injection it can sometimes break the cycle by injecting a partially-built proxy, but that's a smell, not a solution.

The real fix is to remove the cycle: extract the shared logic into a third bean, or rethink the responsibilities. @Lazy on one dependency can break the loop as a stopgap, but two classes that need each other usually signal a design problem.

Key point: the question needs 'redesign to remove the cycle' first, with @Lazy mentioned as a stopgap, not the fix.

Q34. How does Spring Security handle authentication and authorization?

Spring Security inserts a chain of servlet filters ahead of your app. Authentication filters establish who the caller is and store an Authentication in the SecurityContext; authorization then checks whether that principal may access the requested resource, via URL rules or method annotations like @PreAuthorize.

You configure it with a SecurityFilterChain bean: which paths are public, which need a role, how login works (form, HTTP Basic, JWT, OAuth2). The filter-chain model is what to explain first.

java
@Bean
SecurityFilterChain chain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(a -> a
        .requestMatchers("/public/**").permitAll()
        .requestMatchers("/admin/**").hasRole("ADMIN")
        .anyRequest().authenticated());
    return http.build();
}

Q35. How do you handle exceptions globally in Spring MVC?

Use @RestControllerAdvice (or @ControllerAdvice) with @ExceptionHandler methods to catch exceptions across all controllers in one place and map each to a proper HTTP status and body. This keeps error handling out of individual handlers.

For per-controller handling you can put @ExceptionHandler methods directly on a controller. The advice class is the standard for consistent API error responses.

java
@RestControllerAdvice
class ApiErrors {
    @ExceptionHandler(NotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    ErrorBody notFound(NotFoundException e) {
        return new ErrorBody("not_found", e.getMessage());
    }
}

Q36. How does validation work in Spring?

Spring integrates Bean Validation (Jakarta Validation): you annotate fields with constraints like @NotNull, @Size, @Email, then mark the controller parameter @Valid so the framework validates it before your method runs. A failure raises MethodArgumentNotValidException, which you map to a 400.

For rules that span fields or need context, write a custom ConstraintValidator or validate in the service layer. Combining declarative constraints with a global handler gives clean, consistent 400 responses.

java
record SignupRequest(@Email String email, @Size(min = 8) String password) {}

@PostMapping("/signup")
User signup(@Valid @RequestBody SignupRequest req) { ... }

Q37. What are Spring Boot starters and auto-configuration?

Starters are curated dependency bundles: adding spring-boot-starter-web pulls in Spring MVC, Jackson, and an embedded Tomcat at compatible versions, so you don't assemble the dependency graph yourself. Auto-configuration then wires sensible beans based on what's on the classpath and your properties.

Auto-configuration backs off the moment you define your own bean of the same type, so it's a default, not a lock-in. Understanding that back-off behavior is the intermediate-level point.

Key point: Saying auto-config 'backs off when you define your own bean' shows you understand it's overridable defaults, not magic you fight.

Q38. What is Spring Boot Actuator?

Actuator adds production-ready operational endpoints to your app: health checks, metrics, environment info, thread dumps, and more, exposed over HTTP or JMX. /actuator/health and /actuator/metrics are the everyday ones, used by load balancers and monitoring.

It integrates with Micrometer to feed metrics to Prometheus, Datadog, and similar. Because these endpoints leak internals, you secure and selectively expose them in production.

Q39. How do you call another HTTP service from Spring?

The modern synchronous choice is RestClient (Spring 6.1+), a fluent blocking client that replaces the older RestTemplate. For reactive or high-concurrency non-blocking calls, WebClient from Spring WebFlux is the tool.

RestTemplate still works and appears in older code but is in maintenance mode. Picking RestClient for blocking code and WebClient for reactive is the current, correct answer.

ClientStyleUse when
RestClientSynchronous, fluentNew blocking code (Spring 6.1+)
WebClientReactive, non-blockingHigh concurrency, WebFlux
RestTemplateSynchronous, olderLegacy code (maintenance mode)

Q40. What is the difference between CrudRepository, JpaRepository, and PagingAndSortingRepository?

They form a hierarchy. CrudRepository gives basic save, find, delete. PagingAndSortingRepository adds pagination and sorting on top. JpaRepository extends both and adds JPA-specific extras like flush, batch deletes, and returning List instead of Iterable.

In practice most code extends JpaRepository because it's the richest. Knowing the layering explains why some methods exist on one interface and not another.

Watch a deeper explanation

Video: Spring Boot Tutorial | Spring Data JPA | 2021 (Amigoscode, YouTube)

Q41. What is the difference between lazy and eager loading in JPA, and what is the N+1 problem?

Eager loading fetches an entity's associations immediately with the entity; lazy loading defers the fetch until you first access the association. Lazy is the sensible default for collections, but touching a lazy association after the persistence context closes throws LazyInitializationException.

The N+1 problem: loading N parents then firing one query per parent to load its children, so N+1 queries instead of one. The fix is a fetch join or an @EntityGraph to load parents and children in a single query.

java
// N+1: one query for orders, then one per order for its items
@Query("select o from Order o join fetch o.items where o.active = true")
List<Order> findActiveWithItems();   // one query instead of N+1

Key point: Being able to name N+1 and its fetch-join fix is a strong data-layer signal, even in a Spring-framed question.

Q42. What is the Spring application event mechanism?

Spring lets beans publish and listen for events in-process, decoupling the publisher from the handlers. You publish with ApplicationEventPublisher (or just return the event from an aggregate) and handle it with an @EventListener method. Handlers run synchronously by default, in the publisher's thread and transaction.

Add @Async to run a listener on another thread, and @TransactionalEventListener to run only after the surrounding transaction commits, which is the right way to send an email only if the order actually saved.

java
@Component
class WelcomeMailer {
    @TransactionalEventListener(phase = AFTER_COMMIT)
    void onSignup(UserRegistered e) {
        mail.sendWelcome(e.email());   // only after the tx commits
    }
}

Q43. How do you run asynchronous or scheduled tasks in Spring?

@Async on a method makes Spring run it on a separate thread pool and return immediately (void or a Future/CompletableFuture); you enable it with @EnableAsync. @Scheduled runs a method on a fixed rate, fixed delay, or cron expression, enabled with @EnableScheduling.

Both are proxy-based, so the same self-invocation gotcha as @Transactional applies: calling an @Async method from within the same bean runs it synchronously. Configure an explicit TaskExecutor rather than relying on the default.

java
@Scheduled(cron = "0 0 2 * * *")   // 02:00 daily
void nightlyCleanup() { purgeExpired(); }

@Async
CompletableFuture<Report> build(Long id) { ... }

Q44. How do you inject a prototype bean into a singleton so you get a fresh instance each time?

By default a prototype injected into a singleton is resolved once, when the singleton is created, so you keep getting the same instance, which defeats the point. The container only creates a new prototype when it's asked, and a singleton's dependency is asked for exactly once.

Fixes: inject an ObjectProvider (or a Provider) and call getObject() each time you need a fresh one, use a @Lookup method that Spring overrides to return a new instance, or use scoped-proxy mode on the prototype. ObjectProvider is the clean, current choice.

java
@Service
class Reports {
    private final ObjectProvider<ReportBuilder> builders;
    Reports(ObjectProvider<ReportBuilder> builders) { this.builders = builders; }

    Report build() {
        return builders.getObject().run();   // fresh prototype each call
    }
}

Key point: Naming ObjectProvider or @Lookup, and explaining why a plain field gives you the same instance, is the answer that separates real users from readers.

Back to question list

Spring Interview Questions for Experienced Developers

Experienced16 questions

advanced rounds probe internals, design judgment, and production scars. Expect every answer here to draw a follow-up.

Q45. How does Spring create proxies: JDK dynamic proxies vs CGLIB?

Spring AOP proxies a bean one of two ways. If the bean implements an interface, it uses a JDK dynamic proxy that implements that interface. If it doesn't, or you force it, Spring uses CGLIB to generate a runtime subclass. Spring Boot defaults to CGLIB (proxy-target-class true) so proxying works regardless of interfaces.

The consequences experienced engineers cite: CGLIB can't proxy final classes or final methods, and both approaches only intercept external calls through the proxy, which is why an internal self-call skips the advice.

JDK dynamic proxyCGLIB
RequiresBean implements an interfaceNo interface needed
MechanismImplements the interfaceSubclasses the class
LimitationOnly interface methodsNo final classes/methods
Spring Boot defaultNoYes

Key point: Connecting the proxy mechanism to the self-invocation limitation is the answer that indicates deep understanding, not memorization.

Watch a deeper explanation

Video: Spring Boot Tutorial | Full Course [2023] [NEW] (Amigoscode, YouTube)

Q46. Why does calling a @Transactional method from within the same class not start a transaction?

Because Spring AOP works through a proxy that wraps the bean. When an external caller invokes the method, the call goes through the proxy, which applies the transaction. But an internal call (this.method()) goes straight to the target instance and never touches the proxy, so no advice runs.

Fixes: move the transactional method to a separate bean and inject it, self-inject the proxy, or use AspectJ load-time weaving which weaves the advice into the bytecode and works for self-calls. Naming the mechanism, not just the symptom, is what's evaluated.

java
@Service
class Orders {
    void handle() {
        save();          // internal call: @Transactional on save() is SKIPPED
    }
    @Transactional
    void save() { ... }
}

Q47. What is a BeanPostProcessor and how does Spring use it internally?

A BeanPostProcessor is a container extension point with two hooks that run for every bean, before and after its initialization callbacks. It can inspect, modify, or replace a bean, most importantly by wrapping it in a proxy.

This is how Spring itself applies AOP, @Transactional, and @Async: an internal BeanPostProcessor (like AbstractAutoProxyCreator) returns a proxy in the after-initialization hook. Understanding this explains where proxies come from in the lifecycle.

Q48. What is the difference between BeanPostProcessor and BeanFactoryPostProcessor?

A BeanFactoryPostProcessor runs earlier: it operates on the bean definitions (the metadata) after they're loaded but before any bean is instantiated, so it can change a definition's properties. PropertySourcesPlaceholderConfigurer, which resolves ${...} placeholders, is one.

A BeanPostProcessor runs later, on the actual bean instances during initialization. Order matters: definitions first, instances second. Mixing them up is a common senior-level slip.

BeanFactoryPostProcessorBeanPostProcessor
Operates onBean definitions (metadata)Bean instances
TimingBefore instantiationDuring initialization
Example useResolve placeholdersApply AOP proxies

Q49. How does Spring Boot auto-configuration decide what to configure?

Auto-configuration classes are listed in each starter and gated by @Conditional annotations: @ConditionalOnClass (a type is on the classpath), @ConditionalOnMissingBean (you haven't defined your own), @ConditionalOnProperty (a property is set), and others. Boot evaluates these at startup and applies only the ones whose conditions pass.

@ConditionalOnMissingBean is why your bean overrides the default: define your own DataSource and the auto-configured one backs off. The Actuator 'conditions' report shows exactly which matched and why.

java
@AutoConfiguration
class MailAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean   // your bean wins if you define one
    @ConditionalOnProperty("mail.enabled")
    MailSender mailSender() { return new SmtpMailSender(); }
}

Q50. How would you build a custom Spring Boot starter or auto-configuration?

Create an @AutoConfiguration class with the conditional beans you want to contribute, register it in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports, and gate everything with @ConditionalOnMissingBean so consumers can override. Bind settings through a @ConfigurationProperties class. Package it as a library other services depend on.

The design discipline that indicates senior: expose properties for everything configurable, back off when the consumer defines their own bean, and never force beans the app didn't ask for.

Q51. How does Spring's declarative transaction management actually work under the hood?

@Transactional is backed by a PlatformTransactionManager (like DataSourceTransactionManager or JpaTransactionManager). The AOP proxy asks the manager to begin a transaction, binds the connection or EntityManager to the current thread via a ThreadLocal (TransactionSynchronizationManager), runs your method, then commits or rolls back through the manager.

Thread-binding is the reason a transaction doesn't cross to another thread: an @Async method or a new thread starts with no bound transaction. That's a frequent production bug and a favorite deep follow-up.

Key point: The thread-bound-connection detail explains both how propagation works and why transactions don't follow @Async threads. Bring it up in practice.

Q52. When would you choose Spring WebFlux over Spring MVC?

Spring MVC is thread-per-request and blocking: simple to reason about, and fine until you have many concurrent connections mostly waiting on I/O. WebFlux is reactive and non-blocking, handling high concurrency on a small thread pool, which pays off for many slow or streaming downstream calls.

The honest trade-off: WebFlux demands a non-blocking stack end to end (reactive driver, WebClient) and reactive code is harder to write and debug. For most CRUD services with a blocking JDBC database, MVC is the right, simpler choice. With Java 21 virtual threads, blocking MVC scales further, narrowing WebFlux's niche.

Spring MVCSpring WebFlux
ModelThread-per-request, blockingEvent loop, non-blocking
Best atStandard CRUD, blocking DBHigh-concurrency I/O, streaming
CostThreads under heavy I/OHarder to write and debug

Q53. How do Java 21 virtual threads affect Spring applications?

Virtual threads are lightweight JVM threads that let blocking code scale to huge concurrency without the memory cost of platform threads. Spring Boot 3.2+ can run the web server and @Async executor on virtual threads with one property (spring.threads.virtual.enabled), so a normal blocking MVC app handles many more concurrent requests.

The practical effect: much of the pressure that pushed teams to reactive WebFlux eases, because you get high concurrency while keeping simple blocking code. The caveat is pinning: synchronized blocks around blocking calls can pin a virtual thread to its carrier, so those spots need attention.

Q54. How do you test a Spring Boot application at different layers?

Use the narrowest slice that proves what you need. A plain unit test with mocks needs no Spring context and is fastest. @WebMvcTest loads only the web layer to test controllers with a mocked service. @DataJpaTest loads only the persistence layer against an in-memory or Testcontainers database. @SpringBootTest boots the whole context for true end-to-end integration tests, and is the slowest.

The senior point is choosing the right slice: reaching for @SpringBootTest everywhere makes a slow, brittle suite. Testcontainers for a real database in integration tests is the current best practice over in-memory substitutes.

AnnotationLoadsUse for
(none) + mocksNothing SpringPure unit tests
@WebMvcTestWeb layer onlyController tests
@DataJpaTestPersistence layerRepository tests
@SpringBootTestFull contextEnd-to-end integration

Q55. What is the difference between @Mock, @MockBean, and @Autowired in tests?

@Mock (Mockito) creates a bare mock with no Spring involvement, for unit tests. @MockBean (now @MockitoBean in newer Boot) creates a mock and replaces the matching bean inside the Spring context, so injected collaborators get the mock, for slice and integration tests. @Autowired pulls the real bean from the context.

The distinction that matters: @Mock lives outside Spring; @MockBean rewrites the running context, which also invalidates the cached context and can slow the suite if overused.

Q56. How does graceful shutdown work in Spring Boot, and why does it matter?

With graceful shutdown enabled, on a stop signal the server stops accepting new requests but lets in-flight ones finish within a timeout before the context closes and @PreDestroy runs. Boot enables it via server.shutdown=graceful plus a timeout property.

It matters in orchestrated environments (Kubernetes): during a rolling deploy, pods get SIGTERM, and without graceful shutdown you drop requests that were mid-flight. Pairing it with a readiness probe that fails first drains traffic cleanly.

Q57. How do you manage configuration and service discovery across many Spring services?

Spring Cloud Config centralizes configuration in a Git-backed server that services fetch at startup, so config lives outside each deployable and changes without rebuilds. Service discovery (Eureka, or the platform's own DNS in Kubernetes) lets services find each other by name instead of hardcoded hosts.

The pragmatic note experienced engineers add: on Kubernetes much of this is handled by ConfigMaps, Secrets, and cluster DNS, so Spring Cloud Config and Eureka are less common than they were. Choosing platform-native tools when they exist is the mature answer.

Q58. How do you make Spring service-to-service calls resilient?

Apply the standard patterns with Resilience4j: timeouts on every outbound call so a slow dependency can't hang your threads, retries with backoff for transient failures (idempotent calls only), a circuit breaker that stops hammering a failing dependency, and a bulkhead to cap concurrent calls so one slow service can't exhaust the pool.

The judgment part: retries without a circuit breaker amplify an outage, and retrying non-idempotent calls double-charges. Naming those failure modes is what a senior interview probes.

java
@CircuitBreaker(name = "pricing", fallbackMethod = "cached")
@Retry(name = "pricing")
Price fetch(String sku) { return pricingClient.get(sku); }

Price cached(String sku, Throwable t) { return lastKnown.get(sku); }

Q59. How do you improve Spring Boot startup time and memory footprint?

Measure first: the Actuator startup endpoint and the auto-configuration conditions report show where time goes. Then trim: exclude unneeded auto-configurations, prefer lazy initialization for rarely-used beans, and cut dependencies that drag in heavy starters. For serverless or fast-scaling workloads, Spring's AOT processing and GraalVM native images cut startup from seconds to milliseconds and shrink memory.

The trade-off with native images: build times grow and reflection needs hints, so it's worth it for cold-start-sensitive deployments, not every service.

Q60. A Spring endpoint is slow in production. Walk through how you'd diagnose it.

Observe first: distributed tracing (Micrometer Tracing) to see where the time goes across services, and metrics on that endpoint's latency percentiles. If it's inside the service, take a thread dump or profile the live process to see whether it's CPU, lock contention, or waiting on I/O. Check the usual Spring suspects: N+1 queries from lazy loading, a missing connection-pool timeout, a synchronous external call without a timeout, or serialization of a huge payload.

Then fix at the right layer and confirm with the same metric. The structure, observe, hypothesize, verify, fix, confirm, matters more than any single tool; The methodology is.

Key point: Lead with observability, name concrete Spring pitfalls (N+1, missing timeouts), and end with a confirming measurement.

Back to question list

Spring Framework vs Spring Boot vs Jakarta EE

The distinction candidates most often blur is Spring Framework versus Spring Boot. The framework gives you the container, dependency injection, AOP, and the web stack; Boot sits on top and removes configuration with auto-configuration, starter dependencies, and an embedded server. Jakarta EE (formerly Java EE) is the standards-based alternative with its own dependency-injection spec (CDI) and application servers. Knowing which layer you're talking about, and where each fits, is the signal this question screens for.

Spring FrameworkSpring BootJakarta EE
What it isCore container plus modulesOpinionated layer on SpringJava standard specs
ConfigurationExplicit (Java/XML)Auto-configured by defaultContainer-provided
ServerYou supply oneEmbedded (Tomcat/Netty)External app server
Best atFine-grained controlFast standalone servicesStandards-driven shops

How to Prepare for a Spring Interview

Prepare in layers, and practice out loud. Most Spring rounds move from container concepts to writing a small component to a design or debugging discussion, so rehearse each stage rather than only reading answers.

  • Master your tier's concepts until you can explain the container and injection without notes, then read one tier up for the stretch questions.
  • Type and run every snippet in a scratch Spring Boot project; wiring beans yourself cements it far faster than reading.
  • Practice thinking aloud on small problems with a timer, because your process, not just the final answer is the technical point.
  • Take the quiz on this page to find weak spots, then revisit those questions before the real round.

The typical Spring interview flow

1Recruiter or phone screen
background, motivation, a few concept checks
2Core concepts
IoC container, dependency injection, bean scopes and lifecycle
3Live coding
write a bean, a controller, or a small service and explain it
4Design or debugging
AOP, transactions, trade-offs, reading unfamiliar code

Earlier rounds increasingly run as AI coding interviews. The concepts on this page are what gets probed at every stage.

Test Yourself: Spring Quiz

Ready to test your Spring knowledge?

10 questions, about 6 minutes. Score 70% or higher to earn a shareable certificate.

10 questions Instant feedback Free certificate on 70%+

Frequently  Asked  Questions

Which Spring topics should I prioritize before a technical round?

Prioritize the areas that change real decisions: fundamentals, practical tasks, debugging, trade-offs, and evidence. The highest-value questions are tied to a project example, a validation check, or a failure mode.

Should I learn Spring or Spring Boot first?

Learn the core ideas of the Spring Framework first: the IoC container, beans, and dependency injection. Then learn Spring Boot, which is how almost everyone builds Spring apps today. the question expects you to explain what Boot adds on top of the framework, so understanding both layers matters. Our Spring Boot interview questions page covers the Boot-specific side in depth.

Are these questions enough to pass a Spring interview?

They cover the question-answer portion well, but most Spring rounds also include live coding: writing a bean, a controller, or a small service while explaining your thinking. building small components out loud with a timer is the practice path. Our AI coding interview prep guide covers that format, including how automated evaluation reads your process.

Which Spring version do these answers assume?

Spring Framework 6 and Spring Boot 3, which run on Jakarta imports (jakarta.*) and Java 17 or later. If a difference from Spring 5 comes up, it's usually the javax-to-jakarta package rename. When in doubt in an interview, say you're answering for the current Spring 6 and Boot 3 line.

How long does it take to prepare for a Spring interview?

If you use Spring at work or in study, one to two weeks of an hour a day covers this bank with practice runs. Starting colder, plan three to four weeks and build a small Boot project daily; reading answers without wiring beans yourself is how preparation quietly fails.

Is there a way to test my Spring knowledge?

Yes. The quiz on this page scores you as you go and explains every answer, so you find your weak spots fast. Pass the threshold and you can download a shareable certificate with your name and score, free and with no sign-up. It's the quickest way to check yourself before the real round.

From the team that builds coding interviews

Hyring builds the AI Coding Interviewer that runs live technical rounds in 20+ languages for 5,000+ hiring teams. These Spring questions and scoring notes reflect what actually gets asked and evaluated inside the interviews we host.

See how the AI Coding Interviewer works

Sources

Adithyan RKWritten by Adithyan RK
Surya N
Fact-checked by Surya N
Published on: 25 Apr 2026Last updated: 26 Jun 2026
Share: