All articles
Spring CoreInterview Prep

30 Spring Framework Interview Questions & Answers (2026)

June 10, 202617 min read

The Spring Framework is the backbone of most Java backends, which makes it one of the most heavily tested topics in technical interviews. This guide collects 30 Spring interview questions that cut across the whole core framework — the IoC container, dependency injection, bean lifecycle and scopes, AOP, configuration, transactions, and Spring MVC — each with a detailed, code-backed answer of the kind a strong engineer would actually give.

These Spring framework interview questions are written for 2026: Spring Framework 6, the jakarta.* namespace, Java 17+ baselines, and modern constructor-injection idioms. They're grouped by theme and roughly ordered from junior fundamentals to senior depth, so you can skim for revision or work straight through.

Reading the answers is step one; proving you can recall them under pressure is step two. Once a concept clicks, drill it interactively in our free practice questions — active recall beats passive reading every time.

How to use these questions

Work top to bottom. The early IoC and dependency-injection questions are junior-friendly warm-ups; the AOP, configuration, and transaction sections are where senior candidates pull ahead. For each one, try to answer out loud before reading our answer — interviews are verbal, so practice verbalizing.

When a question lands, lock it in with a quick rep on /practice (free, no signup to start). If you're also chasing the Spring Professional certification, pair this with our exam guide, which maps the same topics to the official exam weighting. For the Boot-specific layer, see our sister article on Spring Boot interview questions.

IoC & Dependency Injection Interview Questions

1. What is Inversion of Control (IoC), and how does Spring implement it?

Inversion of Control is the principle that a component should not create or look up its own dependencies — that responsibility is inverted and handed to a container. In Spring, the IoC container (the ApplicationContext) instantiates your objects, wires their dependencies, and manages their lifecycle.

Spring realizes IoC primarily through Dependency Injection. Instead of a class writing new PaymentService(), the container supplies a PaymentService from outside. The two factors IoC most directly mitigates are unmanaged dependency creation (tight coupling from new) and hardcoded configuration baked into Java code.

2. What is dependency injection, and what are its main benefits?

Dependency injection (DI) is the mechanism by which the container passes a component its collaborators rather than the component constructing them itself. The headline benefits interviewers want to hear:

  • Loose coupling — components depend on abstractions (interfaces), not concrete implementations.
  • Centralized, externalized configuration — wiring lives in a small set of config classes, not scattered through the code.
  • Improved testability — you can inject mocks in a plain unit test, no container required.

3. What are the three types of dependency injection in Spring?

Constructor, setter, and field injection.

// Constructor injection (recommended)
@Component
public class OrderService {
    private final PaymentService payment;
    public OrderService(PaymentService payment) {  // @Autowired optional with one constructor
        this.payment = payment;
    }
}
 
// Setter injection
@Autowired
public void setPayment(PaymentService payment) { this.payment = payment; }
 
// Field injection (discouraged)
@Autowired
private PaymentService payment;

4. Why is constructor injection preferred over field injection?

Constructor injection lets you declare dependencies final, guaranteeing they're set once at construction and never null — the object is fully initialized the moment it exists. It also makes the class testable without the Spring container: you just call the constructor with mocks in a plain JUnit test.

Field injection hides dependencies (they're invisible in the public API), prevents final fields, and forces reflection or a container to inject test doubles. Spring also surfaces unresolvable circular dependencies at startup with constructor injection.

In an interview: say you default to constructor injection for required dependencies and reserve setter injection for genuinely optional ones. That's the answer a senior gives.

5. Is @Autowired required on a constructor?

No — since Spring 4.3, if a class has exactly one constructor, @Autowired is optional; Spring uses that constructor automatically.

@Service
public class OrderService {
    private final PaymentService payment;
    public OrderService(PaymentService payment) { this.payment = payment; } // no @Autowired needed
}

You only need @Autowired to disambiguate when there are multiple constructors and you want Spring to use a specific one.

6. How does @Autowired resolve a dependency, and what does @Qualifier do?

@Autowired resolves by type first. If exactly one bean of that type exists, it's injected. If several candidates match, Spring needs a tiebreaker, otherwise it throws NoUniqueBeanDefinitionException.

@Qualifier provides that tiebreaker by naming the bean you want. The bean name acts as a default qualifier value, and @Qualifier must be paired with @Autowired — on its own it does nothing.

@Autowired
@Qualifier("smtpMailer")
private Mailer mailer;

7. What does @Primary do, and how does it differ from @Qualifier?

@Primary marks one bean as the default candidate when multiple beans of the same type exist, so injection points that don't specify a qualifier get the primary one.

@Component @Primary
public class ServiceB implements MyService {}  // injected by default

The difference: @Primary is a producer-side default ("pick me unless told otherwise"), while @Qualifier is a consumer-side override at the injection point. A @Qualifier always wins over @Primary.

Bean Lifecycle & Scopes Interview Questions

8. What is the default scope of a Spring bean?

singleton. Spring creates exactly one instance per container, and every request for that bean returns the same shared instance. This is true even in a web-aware context — the default is singleton regardless of whether the application is web-aware.

Because the instance is shared, singleton beans must be stateless (or thread-safe); storing per-request mutable state in a singleton is a classic bug.

9. What does the prototype scope do, and what's the gotcha with singletons?

prototype gives you a new instance every time the bean is requested or injected.

MyBean a = context.getBean(MyBean.class);
MyBean b = context.getBean(MyBean.class);
// a != b

The gotcha: when a prototype is injected into a singleton, it's resolved once at the singleton's creation, so the singleton holds a single prototype instance for its whole life — you do not get a fresh one per method call. To get a new instance each time, inject ObjectProvider<MyBean> (or use method injection / a scoped proxy).

10. What web-aware scopes does Spring offer?

Beyond singleton and prototype, web contexts add:

  • request — one instance per HTTP request.
  • session — one instance per HTTP session.
  • application — one instance per ServletContext.
  • websocket — one per WebSocket session.

We cover the trade-offs and scoped-proxy mechanics in depth in Spring bean scopes explained.

11. What are the main phases of the Spring bean lifecycle?

Instantiation → dependency injection (populate properties) → initialization callbacks → bean is in service → destruction callbacks on context shutdown. Initialization runs in this order:

  1. @PostConstruct-annotated method (runs first).
  2. InitializingBean.afterPropertiesSet().
  3. The custom init-method.

Destruction mirrors it: @PreDestroy, then DisposableBean.destroy(), then the custom destroy-method.

12. When are @PostConstruct and @PreDestroy called?

@PostConstruct runs after dependency injection is complete but before the bean is put into service — the recommended place for initialization logic that needs injected dependencies. @PreDestroy runs just before the bean is destroyed, for cleanup (closing pools, flushing buffers).

@Component
public class CacheWarmer {
    @PostConstruct void warm() { /* deps are injected here */ }
    @PreDestroy   void flush() { /* cleanup before shutdown */ }
}

These JSR-250 annotations are processed by CommonAnnotationBeanPostProcessor, and @PostConstruct runs before afterPropertiesSet().

13. What is a BeanPostProcessor?

A BeanPostProcessor is a container extension point that lets you intercept every bean during the initialization phase, with hooks running before and after a bean's init callbacks (postProcessBeforeInitialization / postProcessAfterInitialization). It runs after dependencies are injected.

This is how a lot of Spring's own magic works — AOP proxies, annotation processing, and validation are wired in via post-processors. You can implement your own and order them with @Order or Ordered.

In an interview: distinguish it from BeanFactoryPostProcessor, which operates earlier on bean definitions (metadata) before any bean is instantiated — for example to resolve ${...} placeholders.

AOP Interview Questions

14. What is AOP, and what problem does it solve?

AOP — Aspect-Oriented Programming — modularizes cross-cutting concerns: behavior that would otherwise be duplicated across many classes, such as logging, security, caching, and transaction management. Instead of scattering that code through every method, you write it once in an aspect and declare where it applies.

This keeps business logic clean and the cross-cutting logic in one place. Spring's own @Transactional and method-level security are built on AOP.

15. Define the core AOP terms: aspect, join point, pointcut, and advice.

  • Aspect — the module that encapsulates a cross-cutting concern (pointcuts + advice together).
  • Join point — a point during execution where an aspect can be applied. In Spring AOP, a join point is always a method execution.
  • Pointcut — an expression that selects which join points the advice runs at.
  • Advice — the actual code to run at a matched join point.
@Aspect @Component
public class LoggingAspect {
    @Before("execution(* com.acme.service.*.*(..))")  // pointcut
    public void log(JoinPoint jp) { /* advice */ }      // runs before matched methods
}

Our AOP pointcut exam guide drills the execution(...) designator syntax in detail.

16. What advice types does Spring AOP support?

Five: @Before, @AfterReturning (after normal return, can read the return value), @AfterThrowing (after an exception), @After (a finally-style callback that always runs), and @Around.

@Around is the most powerful — it wraps the join point, receives a ProceedingJoinPoint, and decides whether (and when) to call proceed(). It's the only advice that can prevent the method from running, modify arguments and the return value, and suppress or rethrow exceptions.

17. How does Spring AOP create proxies, and what are the limitations?

Spring AOP is proxy-based. At runtime it wraps the target bean in a proxy: a JDK dynamic proxy if the bean implements an interface, or a CGLIB subclass proxy otherwise. The proxy applies the advice, then delegates to the real object.

The key limitations follow directly from this design:

  • Self-invocation is not advised — when a method calls another method on this, the call bypasses the proxy, so the advice (including @Transactional) does not fire.
  • Only method execution join points are supported — no field access or constructor interception.
  • Advised methods must be visible through the proxy (effectively public for typical cases).

In an interview: mention that the self-invocation limitation is the single most common cause of "my @Transactional / @Cacheable isn't working." The fix is to call through the injected proxy or restructure into a separate bean.

Configuration Interview Questions

18. What's the difference between @Bean and @Component?

@Component annotates a class so component scanning discovers it and turns it into a bean — Spring controls instantiation. @Bean annotates a method inside a @Configuration class; the method body constructs and returns the bean, so you control instantiation.

Use @Component for your own classes you can annotate. Use @Bean when you need to register a type you don't own (a third-party class) or when construction requires custom logic.

@Configuration
public class AppConfig {
    @Bean
    public RestClient restClient() {            // you build it
        return RestClient.builder().baseUrl("https://api.example.com").build();
    }
}

19. What are the Spring stereotype annotations?

@Component is the generic stereotype; @Service, @Repository, and @Controller (and @RestController) are specializations of it. They're all discovered by component scanning, but the specializations add semantic intent and, in some cases, behavior.

@Repository is the notable one: it triggers automatic translation of persistence exceptions into Spring's consistent DataAccessException hierarchy.

20. What does @Configuration do that plain @Component doesn't for @Bean methods?

A @Configuration class is processed with CGLIB so its @Bean methods are intercepted. This gives inter-bean references their singleton semantics: if one @Bean method calls another, you get the same managed singleton instance back, not a new object.

@Configuration
public class AppConfig {
    @Bean public A a() { return new A(b()); }   // b() returns the managed singleton
    @Bean public B b() { return new B(); }
}

Declared on a plain @Component ("lite" mode), that b() call would create a brand-new B each time. This proxying behavior is the reason @Configuration exists.

21. How do @Profile and property injection support environment-specific config?

@Profile("prod") makes a bean or configuration eligible only when that profile is active, letting you swap implementations per environment (dev/test/prod). Profile expressions support negation and logic, e.g. @Profile("dev & !cloud").

For values rather than beans, @Value("${daily.limit}") injects a single property, while @ConfigurationProperties binds a whole prefixed group to a typed bean. @PropertySource adds a properties file to the environment so its keys are available for injection.

@Value("${daily.limit:100}")  // with a default
private int dailyLimit;

Data & Transactions Interview Questions

22. What does @Transactional do, and how does it work under the hood?

@Transactional declares that a method should run inside a database transaction — Spring starts a transaction before the method, commits on success, and rolls back on failure. It's declarative: no manual begin/commit/rollback in your code.

It works via AOP. Spring wraps the bean in a proxy whose advice opens a transaction, invokes the method, and then commits or rolls back. Because it's proxy-based, the same self-invocation caveat applies — calling a @Transactional method from within the same class bypasses the proxy and runs in the caller's transaction (or none).

@Service
public class TransferService {
    @Transactional
    public void transfer(Long from, Long to, BigDecimal amount) {
        debit(from, amount);
        credit(to, amount);   // both commit together, or both roll back
    }
}

23. What is Spring's default rollback policy?

By default Spring rolls back on unchecked exceptions (RuntimeException and Error) and commits on checked exceptions. This catches most application failures automatically while treating checked exceptions as recoverable by default.

You can override it per method:

@Transactional(rollbackFor = Exception.class)      // also roll back on checked
@Transactional(noRollbackFor = ValidationException.class)

24. What is transaction propagation, and what's the default?

Propagation controls how a @Transactional method participates in an existing transaction. The default is REQUIRED: join the current transaction if one exists, otherwise start a new one.

The other common ones: REQUIRES_NEW always suspends any current transaction and starts a fresh, independent one; SUPPORTS joins if present but runs non-transactionally otherwise; MANDATORY requires an existing transaction and throws if there isn't one; NESTED uses a savepoint.

We go deeper in the Spring @Transactional exam guide.

25. What happens when a @Transactional method calls another @Transactional method in the same class?

The inner call runs in the same transaction as the outer one — but not because of its @Transactional annotation. The internal call goes through this, bypassing the proxy, so Spring's transaction advice never re-evaluates it; the inner annotation (including any REQUIRES_NEW) is effectively ignored.

If you genuinely need the inner method's propagation to take effect, move it to a separate bean and inject it, so the call crosses a proxy boundary.

Spring MVC / REST Interview Questions

26. What is the role of the DispatcherServlet?

The DispatcherServlet is Spring MVC's front controller — a single entry point that receives every incoming HTTP request and orchestrates handling. It consults handler mappings to find the right controller method, invokes it, applies argument resolvers and return-value handlers, and renders the response.

Centralizing this flow is what lets Spring MVC offer consistent, pluggable request processing (interceptors, exception handling, content negotiation) across the whole application.

27. What's the difference between @Controller and @RestController?

@Controller marks a web controller whose methods typically return a view name to be resolved by a ViewResolver. @RestController is a convenience: @Controller + @ResponseBody, so every method's return value is serialized directly into the response body (usually JSON) instead of being treated as a view.

@RestController
@RequestMapping("/api/orders")
public class OrderController {
    @GetMapping("/{id}")
    public OrderDto get(@PathVariable Long id) { return service.find(id); }  // serialized to JSON
}

Use @RestController for REST APIs and @Controller for server-rendered views.

28. How do the request-mapping and parameter annotations work?

@RequestMapping maps requests to handler methods by path, HTTP method, params, and headers; @GetMapping, @PostMapping, etc. are method-specific shortcuts. To bind parts of the request to method arguments:

  • @PathVariable — a templated URI segment (/orders/{id}).
  • @RequestParam — a query or form parameter (required by default).
  • @RequestBody — the deserialized request body.
  • @RequestHeader — a header value.
@PostMapping("/orders")
public OrderDto create(@RequestBody CreateOrder cmd) { ... }

29. Which HTTP verbs map to REST operations, and what are the key REST principles?

The conventional verb mapping: POST creates a new resource, GET reads, PUT replaces/updates an existing resource (and is idempotent), PATCH partially updates, and DELETE removes. PUT and DELETE are idempotent; POST is not.

The core REST principles interviewers look for: a uniform interface, statelessness (each request carries everything needed; the server holds no client session state), resource-based URIs, and a client–server separation. We expand on REST and Spring MVC in the Spring MVC & REST exam guide.

30. What HTTP status code signals a server-side error, and how do you set one in Spring MVC?

A server-side failure returns 500 Internal Server Error. In Spring you rarely hardcode it — an unhandled exception in a controller produces a 500 automatically. To control status codes explicitly, return a ResponseEntity, annotate the method or exception with @ResponseStatus, or centralize handling in a @RestControllerAdvice with @ExceptionHandler.

@ResponseStatus(HttpStatus.NOT_FOUND)
public class OrderNotFoundException extends RuntimeException {}

This is also where you map domain exceptions to client-facing codes like 400 (bad request) or 404 (not found).

Frequently Asked Questions

What's the difference between Spring and Spring Boot?

Spring (the Framework) is the foundational toolkit: the IoC container, dependency injection, AOP, transactions, and Spring MVC. Spring Boot is an opinionated layer on top of Spring that removes configuration friction — auto-configuration wires sensible defaults based on the classpath, starters bundle compatible dependencies, and an embedded server lets you run a single self-contained jar.

Put simply: Spring gives you the building blocks; Spring Boot assembles them with sensible defaults so you write almost no boilerplate. You still need core Spring knowledge — Boot is built directly on it, and interviewers routinely follow a Boot question with a "why does that work?" rooted in core Spring. For the Boot-specific layer, see our Spring Boot interview questions.

Are these real interview questions?

These are questions written in the style of real Spring interviews and the Spring Professional exam, with original, detailed explanations — not leaked questions, dumps, or any "guaranteed pass" material. They reflect the concepts interviewers and the certification consistently test, so practicing them prepares you for the substance you'll actually face.

How should I prepare for a Spring interview?

Combine breadth and depth. First, make sure you can confidently explain the fundamentals in this list — IoC and dependency injection, bean scopes and lifecycle, AOP, @Bean vs @Component, transactions, and Spring MVC. Then go deeper on what your target role emphasizes (data access for backend roles, MVC/REST for API roles, and Spring Security for platform and auth-heavy roles). Crucially, practice answering out loud, because interviews are verbal. Drilling questions interactively on /practice builds the recall speed passive reading can't, and writing a small Spring app end-to-end surfaces gaps fast.

You now have 30 core Spring interview questions spanning the whole framework, from junior IoC basics to senior-level AOP proxies and transaction propagation. The fastest way to convert "I read it" into "I can answer it under pressure" is active recall — head to our free interactive practice questions and drill these until they're automatic, and if certification is your goal, work through the Spring Professional exam guide next.

Practice This Topic

Reinforce what you've learned with free practice questions and detailed explanations.