Spring Framework: Interview Questions
A comprehensive collection of commonly asked Spring Framework interview questions, organized by topic and difficulty level.
Core Spring Conceptsโ
Q1: What is Spring Framework?โ
Spring is an open-source Java framework for building enterprise applications. It provides infrastructure support including dependency injection, aspect-oriented programming, transaction management, and integration with various technologies. It simplifies development by managing technical details so developers can focus on business logic.
Q2: What are the advantages of the Spring Framework?โ
- Manages object creation and wiring through IoC, making code simpler
- Provides declarative transaction management
- Integrates well with other technologies (JPA, Kafka, REST, etc.)
- Makes testing easier through constructor injection and interfaces
- Spring Boot and Spring Cloud enable rapid development of scalable, distributed applications
Q3: What are the main modules of the Spring Framework?โ
| Module | Purpose |
|---|---|
| Core | IoC container and dependency injection |
| AOP | Aspect-oriented programming for cross-cutting concerns |
| Data Access | JDBC, ORM, transaction management |
| Web | Spring MVC, WebFlux, REST |
| Security | Authentication and authorization |
| Test | Unit and integration testing support |
| Messaging | JMS, AMQP, Kafka support |
| Cloud | Distributed systems and microservices |
IoC and Dependency Injectionโ
Q4: What is IoC and DI?โ
Inversion of Control (IoC) is a design principle where the framework controls the flow of a program instead of the developer's code. Dependency Injection (DI) is the mechanism used to implement IoC โ necessary objects are provided to a class rather than the class creating them itself. This makes code easier to manage, test, and change.
Q5: What is the role of the IoC container in Spring?โ
The IoC container manages the creation and configuration of objects (beans). It provides required dependencies automatically, connecting objects and their dependencies so developers can build applications in a more organized and efficient way.
Q6: What are the types of IoC containers in Spring?โ
| Container | Description |
|---|---|
| BeanFactory | Basic container that handles creating and managing objects. Lazy initialization. |
| ApplicationContext | Advanced container adding event handling, AOP integration, i18n, and web context support. Eager initialization. |
Most developers prefer
ApplicationContextbecause it offers more capabilities and is easier to use.
Q7: What are the differences between ApplicationContext and BeanFactory?โ
| Feature | BeanFactory | ApplicationContext |
|---|---|---|
| Bean Loading | Lazy | Eager |
| Event Propagation | No | Yes |
| AOP Support | Manual | Built-in |
| i18n Support | No | Yes |
| Web Context | No | Yes |
| Best For | Low-memory / embedded systems | Enterprise applications |
Q8: When would you use BeanFactory over ApplicationContext?โ
Use BeanFactory in scenarios with minimal resources or when only basic bean management is needed โ such as small applications or embedded systems. Use ApplicationContext for enterprise-level applications requiring advanced features like event propagation, AOP integration, and declarative services.
Bean Configurationโ
Q9: What is a Spring Bean?โ
A Spring Bean is an object created and managed by the Spring IoC container. Beans are the key building blocks of a Spring application โ the framework handles their creation, wiring, and lifecycle.
Q10: What is the use of @Configuration and @Bean?โ
@Configuration indicates a class contains bean definitions that the Spring container can use. @Bean is used on methods within that class to define beans managed by the Spring container.
@Configuration
public class AppConfig {
@Bean
public PaymentService paymentService() {
return new PaymentServiceImpl();
}
}
Q11: What are the different bean scopes in Spring?โ
| Scope | Description | Use Case |
|---|---|---|
| Singleton (default) | One instance for the entire application context | Configuration, shared services |
| Prototype | New instance each time the bean is requested | Stateful or user-specific objects |
| Request | One instance per HTTP request | Web request-scoped data |
| Session | One instance per user session | User session data |
| Global Session | One instance per global session | Portlet applications |
Q12: What is the default bean scope?โ
The default scope is singleton โ only one instance of the bean is created and shared across the entire application context.
Q13: When would you use Singleton vs Prototype scope?โ
- Singleton: When you need one shared instance โ e.g., configuration settings, stateless services
- Prototype: When you need a new instance each time โ e.g., objects holding user-specific data or different states for different uses
Q14: Are singleton beans thread-safe?โ
No. Singleton beans are not thread-safe by default. Since they are shared across the application, you need to add thread-safety measures:
- Use
synchronizedmethods or blocks - Use
ThreadLocalfor thread-confined data - Implement stateless beans where possible
- Use concurrent utilities from
java.util.concurrent
Q15: Can we have multiple Spring configuration files in one project?โ
Yes. Multiple configuration files help organize bean definitions by purpose or module. You can load them into the application context as needed using @Import or component scanning.
Dependency Injectionโ
Q16: Which is the best way of injecting beans and why?โ
Constructor injection is the recommended approach. It ensures all necessary dependencies are provided when the object is created, making the object more reliable, immutable, and easier to test.
Q17: Difference between Constructor Injection and Setter Injection?โ
| Aspect | Constructor Injection | Setter Injection |
|---|---|---|
| When dependencies are set | At object creation time | After object creation |
| Immutability | Supports immutable objects | Dependencies can change |
| Required dependencies | Enforced โ object can't exist without them | Optional โ can be set later |
| Circular dependencies | Can cause issues | Helps resolve circular dependencies |
Q18: What type of injection does @Autowired use?โ
@Autowired primarily uses constructor injection by default. It can also be used for:
- Field injection โ Spring directly sets field values
- Setter injection โ Dependencies injected through setter methods
Q19: Why is constructor injection recommended over setter-based injection?โ
Constructor injection ensures all required dependencies are provided at creation time. This makes objects:
- Immutable once constructed
- Complete โ they can't exist without their dependencies
- Safer โ no risk of
NullPointerExceptionfrom uninitialized dependencies - Testable โ dependencies are explicit in the constructor signature
Advanced Topicsโ
Q20: What is a circular dependency issue?โ
A circular dependency occurs when two or more beans depend on each other to be created. For example, Bean A requires Bean B, and Bean B requires Bean A. This leads to a deadlock that prevents the application from starting.
Q21: How do you resolve circular dependencies in Spring Boot?โ
| Strategy | How It Works |
|---|---|
| Setter injection | Allows beans to be instantiated before dependencies are set |
@Lazy annotation | Defers bean initialization until actually needed |
| Redesign architecture | Separate concerns and reduce coupling between beans |
| Introduce interfaces | Abstract implementation details to decouple components |
Q22: Difference between @Component and @Service. Are they interchangeable?โ
Both create Spring beans and are technically interchangeable. However:
@Componentโ generic stereotype for any Spring-managed component@Serviceโ specialization indicating the bean performs service/business logic
Using the correct stereotype improves code clarity about the bean's role in the application.
Q23: Difference between @Qualifier and @Primary?โ
| Annotation | Purpose |
|---|---|
@Qualifier | Specifies exactly which bean to inject by name |
@Primary | Marks a bean as the default choice when multiple candidates exist |
@Autowired
@Qualifier("reportingDataSource")
private DataSource dataSource; // Injects the specific bean
@Bean
@Primary
public DataSource primaryDataSource() { ... } // Default when no qualifier specified
Q24: What is the usage of @Transactional?โ
@Transactional defines the scope of a database transaction. All operations within the annotated method either all succeed or all fail together, maintaining data integrity for complex multi-step operations.
Q25: What is Spring Profiles? How do you activate a profile?โ
Spring Profiles segregate application configuration by environment (dev, test, prod). Activate a profile using:
- Command line:
-Dspring.profiles.active=prod - Properties file:
spring.profiles.active=prod - Programmatically:
SpringApplication.setAdditionalProfiles("prod")
Q26: How can you inject properties using environment variables?โ
Use the @Value annotation:
@Value("${MY_ENV_VAR}")
private String myProperty;
This injects the value of the MY_ENV_VAR environment variable into the bean.
Q27: What happens if multiple AutoConfiguration classes define the same bean?โ
The last one loaded takes precedence. Control ordering with:
@AutoConfigureOrderโ explicit priority@AutoConfigureAfter/@AutoConfigureBeforeโ relative ordering@ConditionalOnMissingBeanโ only create if no existing bean
AOP (Aspect-Oriented Programming)โ
Q28: What is AOP? What is its biggest disadvantage?โ
AOP modularizes cross-cutting concerns (logging, security, transactions) separate from business logic. It improves code readability and reduces redundancy.
Biggest disadvantage: It makes execution flow harder to follow. The modularized code runs separately from the main application flow, making it challenging to trace and debug.
Q29: What is the difference between Join Point and Pointcut?โ
| Concept | Description |
|---|---|
| Join Point | A specific point during program execution (e.g., a method call) where an aspect can be applied |
| Pointcut | An expression that selects one or more join points, determining where advice should execute |
Join Points = actual locations. Pointcuts = the selectors that pick those locations.
Spring Batchโ
Q30: What is Spring Batch?โ
Spring Batch is a framework for processing large volumes of data automatically and efficiently โ ideal for data migration, daily transaction processing, and report generation.
Implementation steps:
- Define a Job configuration with steps
- Set up an ItemReader to pull data
- Create an ItemProcessor to apply business logic
- Configure an ItemWriter to output processed data
- All managed within Spring's context for transactional integrity and job monitoring
Testingโ
Q31: What is the difference between @Spy and @Mock in Mockito?โ
| Aspect | @Mock | @Spy |
|---|---|---|
| Instance type | Fully mocked (no real code executes) | Partial mock wrapping a real instance |
| Default behavior | All methods return defaults (null, 0, false) | All methods execute real code |
| Override behavior | when().thenReturn() | doReturn().when() for selective stubbing |
| Best for | Isolating dependencies | When some real behavior is needed |
Scenario-Based Questionsโ
Q32: You are starting a new Spring project. Would you use annotations or XML for configuration?โ
Consider:
- Annotations โ concise, readable, part of the code, easier to maintain
- XML โ better for complex configurations, separation of concerns, modifiable without recompilation
Decision factors: team familiarity, project requirements, and configuration complexity. Most modern projects favor annotations.
Q33: You have a large project with many interdependent beans. How would you manage dependencies?โ
- Use dependency injection to manage dependencies
- Use Spring Profiles for environment-specific configurations
- Group related beans in separate
@Configurationclasses - Use
@ComponentScanto automatically discover beans - Apply interface-driven design to reduce coupling
Q34: How would you make a singleton bean thread-safe?โ
- Use
synchronizedmethods or blocks for critical sections - Use
ThreadLocalfor thread-confined objects - Implement stateless beans to avoid shared state
- Use concurrent utilities from
java.util.concurrent
Q35: How would you resolve a bean conflict in Spring Boot?โ
Use @Qualifier("beanName") at the injection point to specify exactly which bean to inject when multiple beans of the same type exist. Alternatively, mark one bean as @Primary to set a default.
Q36: Difference between JpaRepository and CrudRepository?โ
| Feature | CrudRepository | JpaRepository |
|---|---|---|
| CRUD operations | Yes | Yes (inherited) |
| Pagination & Sorting | No | Yes |
| Batch operations | No | Yes |
| Flush persistence context | No | Yes |
| Use CrudRepository when | Simple database interactions without advanced JPA features | |
| Use JpaRepository when | Full JPA capabilities are needed |
Senior-Level Questionsโ
Q37: What is the difference between CGLIB and JDK Dynamic Proxy? When does Spring use each?โ
JDK Dynamic Proxy wraps an interface using java.lang.reflect.Proxy โ only works if the target bean implements at least one interface.
CGLIB Proxy generates a bytecode subclass of the target class at startup โ no interface needed.
Spring Boot defaults to CGLIB for all beans (spring.aop.proxy-target-class=true). @Configuration classes always use CGLIB to ensure @Bean methods return the same singleton instance even when called multiple times.
CGLIB cannot proxy: final classes, final methods, or classes without a no-arg constructor.
Q38: Why does @Transactional have no effect when a method calls another @Transactional method in the same class?โ
Spring applies @Transactional through an AOP proxy. External callers reach the method via the proxy, which applies transactional behavior. But internal calls (this.method()) go directly to the raw object โ bypassing the proxy entirely.
This is the self-invocation problem. The fix is either:
- Extract to a separate
@Servicebean (preferred) - Inject the proxy into itself using
@Autowired private MyService self
The same problem affects @Async, @Cacheable, and @Retryable.
Q39: What is BeanPostProcessor, and what is the risk of using it incorrectly?โ
BeanPostProcessor intercepts every bean after instantiation โ Spring uses it internally for AOP proxying and @Autowired injection. You can implement it to wrap or modify beans.
The main risk: BeanPostProcessor beans are instantiated very early, before most other beans. If a BeanPostProcessor depends on another bean (e.g., a JPA repository), it forces premature instantiation of that bean โ potentially before auto-configuration has run, breaking things silently.
Rule: BeanPostProcessor beans should have minimal dependencies and never depend on auto-configured infrastructure beans.
Q40: How do you inject a prototype-scoped bean into a singleton bean?โ
If you inject a @Scope("prototype") bean via constructor or @Autowired, Spring injects it once โ effectively making it singleton in that class.
Correct approaches:
// Option 1: @Lookup (Spring overrides this method to return a new prototype each time)
@Component
public abstract class OrderProcessor {
@Lookup
public abstract PrototypeService getService(); // Spring generates impl
public void process(Order order) {
getService().execute(order); // New instance each call โ
}
}
// Option 2: ObjectFactory/ObjectProvider
@Service
public class OrderService {
private final ObjectProvider<PrototypeBean> prototypeProvider;
public void process() {
PrototypeBean bean = prototypeProvider.getObject(); // New instance each time
}
}
// Option 3: ApplicationContext.getBean() โ last resort
Q41: What is SpEL (Spring Expression Language) and where is it commonly used?โ
SpEL is a runtime expression language evaluated within Spring annotations:
// @Value โ inject computed or conditional values
@Value("#{systemProperties['user.timezone'] ?: 'UTC'}")
private String timezone;
// @PreAuthorize โ check business data in security expressions
@PreAuthorize("#order.ownerId == authentication.principal.id or hasRole('ADMIN')")
public void refundOrder(Order order) { ... }
// @Cacheable โ dynamic cache key
@Cacheable(key = "#userId + '_' + #status.name()")
public List<Order> findOrders(Long userId, OrderStatus status) { ... }
// @ConditionalOnExpression โ in auto-configuration
@ConditionalOnExpression("${app.feature.enabled:false} && '${app.env}' == 'production'")
public class ProductionFeatureConfig { ... }
Q42: How do you detect and break circular dependencies at design time?โ
Spring Boot will throw BeanCurrentlyInCreationException at startup for constructor injection circular dependencies. For setter injection, the cycle is silently resolved (beans exist before dependencies are set).
Detection:
# Spring Boot 2.6+ detects circular deps at startup by default
spring.main.allow-circular-references=false # default โ throws exception
Resolution strategies:
- Refactor architecture โ introduce a third mediator bean or event-driven pattern (preferred)
@Lazyโ defer initialization of one dependency:@Autowired @Lazy ServiceB serviceB- Use setter/field injection โ allows the cycle to resolve at cost of hidden coupling
Q43: What is ApplicationEventPublisher and what are its use cases?โ
ApplicationEventPublisher decouples components using an in-process event bus โ publish events without the publisher knowing about consumers.
// Define event (can be any object since Spring 4.2)
public record OrderPlacedEvent(Long orderId, String customerId) {}
// Publisher โ doesn't know about consumers
@Service
public class OrderService {
private final ApplicationEventPublisher publisher;
@Transactional
public Order placeOrder(OrderRequest req) {
Order order = orderRepository.save(new Order(req));
publisher.publishEvent(new OrderPlacedEvent(order.getId(), req.getCustomerId()));
return order;
}
}
// Consumer โ decoupled listener
@Component
public class NotificationHandler {
@EventListener
@Async // Make async to not block the order transaction
public void onOrderPlaced(OrderPlacedEvent event) {
emailService.sendConfirmation(event.customerId(), event.orderId());
}
}
@TransactionalEventListener โ for events that should only fire if the publishing transaction commits:
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void onOrderConfirmed(OrderPlacedEvent event) {
// Safe to trigger external systems โ only runs after DB commit
}
Q44: What is the difference between @Primary, @Qualifier, and @ConditionalOnMissingBean?โ
| Annotation | Purpose | Where used |
|---|---|---|
@Primary | Default bean when multiple candidates exist | On the bean definition |
@Qualifier("name") | Select a specific bean by name | At the injection point |
@ConditionalOnMissingBean | Only create this bean if none of this type exists | In auto-configuration |
@Primary and @Qualifier manage which bean is chosen among existing ones. @ConditionalOnMissingBean determines whether a bean is created at all โ used in auto-configuration to allow user-defined beans to override framework defaults.
// User provides their own DataSource โ auto-config backs off
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() { ... } // Only created if user didn't define one
Advanced Editorial Pass: Spring Interview Answers That Stand Outโ
Upgrade Path for Responsesโ
- Translate conceptual answers into architecture and production implications.
- Highlight boundaries: container concern, application concern, platform concern.
- Show explicit trade-offs and failure containment strategy.
Red Flags to Avoidโ
- Memorized definitions without decision criteria.
- Ignoring observability, rollout, and rollback implications.
- Assuming default framework behavior is always safe at scale.
Deliberate Practiceโ
- Pair each answer with one performance and one reliability consideration.
- Add one anti-pattern and how you would detect it in production.
- Practice concise, layered explanations: concept, trade-off, implementation.