• Skip to main content
  • Skip to secondary menu
  • Skip to primary sidebar

JavaTutorOnline

1-on-1 Online Java Training by a Senior Software Engineer

  • Home
  • AP CSA
    • AP CSA Summer
    • FRQ Practice
      • Arrays
      • ArrayList
      • Strings
      • 2D Arrays
  • Courses
  • Tutorials
    • Java
    • Servlets
    • Struts
    • Spring
    • Webservice
  • FAQ
  • Testimonials
  • Blog
  • CONTACT US

Top Spring Core Interview Questions and Answers for Developers

Spring Core Interview Questions

Spring Core interview questions and Answers

Are you preparing for a Java developer interview and looking for common Spring Core questions? You’ve come to the right place! The Spring Framework, known for its features like Dependency Injection (DI) and Inversion of Control (IoC), is a popular choice for enterprise applications.

This article covers essential Spring Core interview questions to help you succeed, whether you’re a beginner or an experienced developer.

1. What is the Spring Framework, and why is it widely used?

Spring is an open-source Java framework that simplifies the building of enterprise-level applications. At its core, it provides a comprehensive programming and configuration model. By supporting features like Dependency Injection (DI), Aspect-Oriented Programming (AOP), and transaction management, Spring promotes loosely coupled, easily testable, and highly maintainable code. Furthermore, its modular ecosystem integrates seamlessly with other frameworks and tools.

Interview Pro-Tip: Don’t just list features; mention that Spring solves the “plumbing” problems of enterprise Java. By handling infrastructure (like transaction management and object lifecycles), it allows developers to focus purely on business logic.


2. Explain Inversion of Control (IoC).

Inversion of Control (IoC) is a software design principle where the control of object creation, configuration, and lifecycle management is transferred from the application code to the Spring IoC container. Instead of a class instantiating its own dependencies using the new keyword, the Spring container injects those dependencies at runtime. Dependency Injection (DI) is the specific pattern Spring uses to implement IoC, resulting in code that is highly modular, testable, and loosely coupled.

Interview Pro-Tip: Relate IoC to the “Hollywood Principle” (“Don’t call us, we’ll call you”). Explain that shifting the responsibility of object creation from the developer to the framework makes unit testing significantly easier since dependencies can be easily mocked.


3. Explain Dependency Injection (DI). What are the different types of Dependency Injection in Spring?

Dependency Injection (DI) is the specific implementation of Inversion of Control (IoC). Instead of a class manually instantiating its dependencies, the Spring container automatically provides (injects) those required dependencies at runtime. This promotes loose coupling, easier testing, and cleaner code.

Spring supports three primary types of Dependency Injection:

  • Constructor-Based Injection: The Spring container resolves dependencies by passing them through the class constructor. This is the highly recommended approach because it allows fields to be declared as final (ensuring immutability) and guarantees that the bean is never instantiated in a partially initialized state.
  • Setter-Based Injection: Dependencies are injected via setter methods after the bean is instantiated. This approach is ideal for optional dependencies or when an object’s configuration might need to change dynamically after creation. Historically, it was also used as a workaround to break circular dependencies.
  • Field-Based Injection: Dependencies are injected directly into the private fields using annotations like @Autowired. While extremely concise, it is widely considered an anti-pattern in modern production code. It bypasses encapsulation, hides class dependencies (violating the Single Responsibility Principle), and makes unit testing difficult without starting up the Spring container or using Reflection.

Interview Pro-Tip: Always advocate for Constructor Injection during an interview. It allows you to enforce immutability and makes writing unit tests much easier, since you don’t need a Spring container to instantiate the class—you can just pass mocked objects directly into the constructor using the new keyword.


4. What are ApplicationContext and BeanFactory, and how do they differ?

Both BeanFactory and ApplicationContext are core interfaces representing the Spring IoC container, responsible for managing the lifecycle and configuration of beans. While both implement Dependency Injection, they serve different use cases:

  • BeanFactory: This is the root interface of the Spring container, providing fundamental bean management. Crucially, it uses lazy initialization, meaning beans are only instantiated when explicitly requested (e.g., via getBean()). It is rarely used today, reserved mostly for environments where memory consumption is strictly constrained (like lightweight applets or IoT devices).
  • ApplicationContext: This is a sub-interface of BeanFactory. It includes all the base functionality but adds enterprise-specific features like event publishing, internationalization (i18n) support, and AOP integration. Crucially, it uses eager initialization for singleton beans, meaning it creates and configures all beans immediately upon application startup. This is the standard container used in almost all modern Spring and Spring Boot applications.

Interview Pro-Tip: Emphasize that in modern Spring and Spring Boot development, you will almost exclusively use ApplicationContext. While knowing how BeanFactory works is required for interviews, actually using it in a modern enterprise application would be considered a severe anti-pattern.


5. How does the Spring IoC container work?

The Spring IoC (Inversion of Control) container is the engine of any Spring application. It is responsible for instantiating, configuring, and managing the entire lifecycle of objects (known as Spring beans). It operates on the principle of Dependency Injection (DI) to assemble these beans based on provided configuration metadata. Here is the step-by-step process of how it works:

  1. Reading Configuration Metadata: The container reads bean definitions and dependency graphs from your configuration sources (XML files, Java annotations, or Java @Configuration classes).
  2. Bean Instantiation: The container creates the bean instances based on the parsed metadata.
  3. Dependency Injection: Once instantiated, the container resolves and injects the required dependencies (via constructors, setters, or fields) to wire the application components together.
  4. Lifecycle Management: The container triggers any custom initialization methods (such as those annotated with @PostConstruct or implementing InitializingBean). It also handles the safe destruction of beans (via @PreDestroy) when the context is closed.
  5. Scope Enforcement: Throughout this process, the container enforces the defined bean scopes, ensuring, for example, that a Singleton bean is cached and shared, while a Prototype bean gets a fresh instance upon every request.

Interview Pro-Tip: Stand out by explaining that the ApplicationContext (the modern IoC container) reads configuration metadata, instantiates beans, and wires them together eagerly—meaning it does all of this before the application starts accepting HTTP requests. This allows the application to “fail fast” if there are any configuration or wiring errors.


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

In Spring, these are known as stereotype annotations. They are used to mark classes as Spring beans so the IoC container can automatically detect and manage them during classpath scanning. Under the hood, @Controller, @Service, and @Repository are all specialized variations of @Component. We use them to clarify the architectural role of a class and, in some cases, to trigger specific framework behaviors.

  • @Component: The generic base annotation. It is used to mark any general-purpose Spring-managed bean, such as utility classes, configuration helpers, or custom validation components.
  • @Controller: Used in the presentation layer. It marks a class as a Spring MVC controller responsible for handling incoming HTTP requests and returning responses or views.
  • @Service: Used in the business layer. It acts as a semantic marker to indicate that the class holds core business logic, performs calculations, or orchestrates calls between different repositories.
  • @Repository: Used in the persistence layer for Data Access Objects (DAOs). It marks classes that are directly responsible for interacting with the database to perform CRUD operations.

Interview Pro-Tip: Interviewers love asking if these annotations are only for readability. While @Service is largely just a semantic marker, point out that @Repository actually changes framework behavior! It triggers Spring’s exception translation mechanism, which catches vendor-specific database exceptions (like raw SQLExceptions) and translates them into Spring’s unified, unchecked DataAccessException hierarchy.


7. How are beans defined in Spring?

In Spring, beans are the foundational building blocks managed by the IoC container. There are three primary configuration styles used to define them:

  • XML-Based Configuration: The legacy approach where beans and their dependencies are explicitly defined in an XML file (e.g., applicationContext.xml) using <bean> tags.
<bean id="myBean" class="com.example.MyBean">
    <property name="someProperty" value="Some Value" />
</bean>
  • Java-Based Configuration: Introduced in Spring 3.0, this approach uses Java classes annotated with @Configuration. Inside these classes, methods annotated with @Bean act as factories to instantiate and configure the beans. This provides type safety and programmatic flexibility.
<!-- Java Configuration Example -->
@Configuration
public class AppConfig {
    
    @Bean
    public MyBean myBean() {
        MyBean myBean = new MyBean();
        myBean.setSomeProperty("Some Value");
        return myBean;
    }
}
  • Annotation-Based Configuration: Beans are declared by decorating the class itself with stereotype annotations like @Component, @Service, @Repository, or @Controller. Spring automatically detects and registers these beans during startup using classpath scanning (typically via @ComponentScan).

Modern Spring and Spring Boot applications almost exclusively use a combination of Java-based and Annotation-based configurations, leaving XML behind.

Interview Pro-Tip: Mention that while @Bean and @Component are standard, utilizing @Conditional annotations alongside them is what truly demonstrates senior-level mastery of modern Spring Boot auto-configuration.


8. What is the scope of Spring beans?

In Spring, bean scope defines the lifecycle and visibility of a bean instance within the IoC container. By default, beans are created as singletons, but Spring provides several scopes to control how beans are instantiated and shared based on architectural requirements. You can change a bean’s scope using the @Scope annotation.

The core scopes available in Spring are:

  • Singleton (Default): A single, shared instance is created per Spring IoC container. Every request for that specific bean yields the exact same object. This is highly efficient and ideal for stateless services, DAOs, and shared configuration.
  • Prototype: A brand-new, distinct instance is created every single time the bean is requested from the container. This is suitable for stateful beans that hold specific conversational data and cannot be safely shared across threads.
  • Request: A single instance is created for the lifecycle of an individual HTTP request. (Only valid in a web-aware Spring ApplicationContext).
  • Session: A single instance is created for the lifecycle of an HTTP Session, allowing you to store user-specific state. (Only valid in a web-aware Spring ApplicationContext).
  • Application: A single instance is created for the lifecycle of a ServletContext. It is similar to a singleton but is scoped at the web-application level rather than the Spring ApplicationContext level. (Note: This replaces the legacy “Global Session” scope which was historically used for portlets).

Interview Pro-Tip: Interviewers love asking the “gotcha” question: “What happens if you inject a Prototype bean into a Singleton bean?” The answer is that the Prototype effectively becomes a Singleton, because the singleton’s dependencies are only resolved once during its creation. Mentioning solutions to this problem, like using @Lookup method injection or ObjectFactory, will instantly prove your senior-level knowledge.


9. What are Spring profiles, and how are they used?

Spring Profiles provide a powerful way to segregate parts of your application configuration and make them available only in specific environments (such as dev, test, or prod). This allows you to safely manage different database connections, external API keys, or logging levels without modifying your core compiled codebase as the application moves through the deployment pipeline.

There are two primary ways to use profiles:

  1. Via Annotations: You can annotate a @Configuration class or a specific @Bean method with @Profile("dev"). Spring will only register these beans if the dev profile is currently active.
  2. Via Properties/YAML Files: In Spring Boot, you can create profile-specific configuration files (e.g., application-dev.yml or application-prod.properties) that automatically load when that specific profile is activated.
@Configuration
@Profile("dev")
public class DevConfig {
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(); // Development-specific database
    }
}

You can activate a profile by setting the spring.profiles.active property in your main application.properties, passing it as a JVM command-line argument (-Dspring.profiles.active=prod), or setting an OS environment variable.

Interview Pro-Tip: Give a practical example: Mention how you might use an in-memory H2 database for the test profile to run fast unit tests, but switch to a robust PostgreSQL connection pool for the prod profile—all without changing a single line of Java code.


10. What is the difference between singleton and prototype bean scopes?

In Spring, the singleton and prototype bean scopes define how bean instances are created and managed by the IoC container. Here is a breakdown of the key differences:

  • Singleton Scope (Default): The Spring container creates only one instance of the bean during its entire lifecycle. Every time the application requests this bean, the container returns the exact same shared instance. This is highly efficient and ideal for stateless components (like services, DAOs, or global configuration managers) where a single shared instance is required across the application.
  • Prototype Scope: The Spring container creates a brand-new instance of the bean every single time the application requests it. This is necessary for stateful beans that hold specific conversational data, where sharing an instance across threads would lead to data corruption (e.g., a bean that manages a unique user shopping cart or session).

Interview Pro-Tip: Be ready for the follow-up question: “Are Spring Singletons thread-safe?” The answer is no, not by default. It is entirely up to the developer to ensure a singleton bean doesn’t maintain mutable state across different threads.


11. What are the different ways to configure a Spring application?

Historically, Spring has evolved to offer three primary ways to configure an application. Modern applications typically use a combination of Java-based and Annotation-based configurations.

  • XML-Based Configuration: The legacy approach where beans and their dependencies are explicitly wired in an applicationContext.xml file using <bean> tags.
  • Annotation-Based Configuration: Introduced in Spring 2.5, this allows developers to use annotations like @Component, @Service, and @Autowired directly on Java classes. It relies on classpath scanning (e.g., @ComponentScan) to detect and register beans automatically.
  • Java-Based Configuration: Introduced in Spring 3.0 and the backbone of modern Spring Boot, this approach uses Java classes annotated with @Configuration and methods annotated with @Bean to define the application context in a type-safe, programmatic manner.

Interview Pro-Tip: Interviewers ask this to gauge your experience level. Mention that while Java-based and Annotation-based configurations are the modern standards, knowing how to read XML configuration is still a highly valued skill for migrating or maintaining older enterprise systems.


12. How do you define and use a custom bean in Spring?

A custom bean is simply a standard Java object that you configure the Spring IoC container to manage. While you can use legacy XML (<bean> tags), modern Spring applications define custom beans using one of two primary approaches:

1. Java-Based Configuration (@Bean) You can define a bean programmatically by writing a method that instantiates the object and annotating that method with @Bean inside a @Configuration class.

2. Annotation-Based Configuration (@Component) Alternatively, you can let Spring do the heavy lifting by decorating the class itself with @Component (or another stereotype like @Service). As long as @ComponentScan is configured for the correct package, Spring will automatically detect and register it.

How to Use the Custom Bean: Once defined, you use the bean by injecting it into dependent classes, typically via constructor injection using the @Autowired annotation (though @Autowired is optional if there is only one constructor). Alternatively, you can retrieve it manually from the context using applicationContext.getBean(MyCustomBean.class).

Interview Pro-Tip: Mention that when defining custom beans via @Bean in a @Configuration class, calling one @Bean method from another doesn’t create a new instance; Spring intercepts the call via CGLIB proxying to ensure singleton semantics are strictly maintained.


13. What is @Autowired, and how does it work?

In Spring, the @Autowired annotation is used to enable automatic dependency injection. When the Spring IoC container initializes a bean, it scans for this annotation and automatically resolves and injects the required dependencies by type.

You can apply @Autowired to three different places within a class:

  • Constructors: To inject dependencies at the time of bean instantiation.
  • Setter Methods: To inject dependencies after the bean has been instantiated.
  • Fields: To inject dependencies directly into private fields (using Reflection).

If Spring finds multiple beans of the same type, it will throw a NoUniqueBeanDefinitionException unless instructed otherwise (such as by using the @Qualifier annotation).

Interview Pro-Tip: Show that you are up-to-date by noting that as of Spring 4.3, if a class only has a single constructor, you can safely omit the @Autowired annotation entirely. It makes the code cleaner and strictly enforces constructor injection.


14. What is the role of the @Qualifier annotation?

The @Qualifier annotation is used to resolve ambiguity when multiple beans of the same type exist in the Spring application context. When using @Autowired, Spring attempts to resolve dependencies by type. If it discovers more than one matching bean, it cannot determine which one to inject and will fail at startup, throwing a NoUniqueBeanDefinitionException.

By pairing @Qualifier("beanName") with @Autowired, you explicitly instruct Spring which specific bean instance to inject, effectively switching the resolution mechanism from “by type” to “by name”.

Interview Pro-Tip: To avoid brittle code caused by string typos (like @Qualifier("db1")), mention that a senior practice is to create custom qualifier annotations (e.g., @ReadOnlyDatabase) for type-safe injection.


15. Explain the difference between constructor-based and setter-based DI.

While both are valid techniques for achieving Dependency Injection in Spring, they serve different architectural purposes and have distinct behaviors:

FeatureConstructor-Based DISetter-Based DI
Initialization PhaseInjects dependencies at the exact moment of bean instantiation.Injects dependencies after the bean has been instantiated via its default constructor.
Immutability & Thread SafetyAllows you to declare dependency fields as final, ensuring the bean is strictly immutable and thread-safe.Leaves beans mutable, meaning dependencies can technically be swapped out or changed at runtime (which is generally discouraged in stateless architectures).
Mandatory vs. OptionalIdeal for mandatory dependencies. The bean simply cannot be created if a required dependency is missing.Ideal for optional dependencies where the class can fall back on a reasonable default value if the dependency isn’t provided.
Flexibility vs. SafetyLess flexible (requires all dependencies upfront and struggles with circular dependencies) but significantly safer, preventing objects from existing in a partially initialized state.Highly flexible (can easily resolve circular dependencies), but risky, as calling a method on a bean before its setter is invoked will result in a NullPointerException.

Interview Pro-Tip: Always advocate for the “fail-fast” principle during an interview. Point out that Constructor Injection ensures that if a required dependency is missing, the application fails to start immediately, rather than silently starting up and throwing a NullPointerException hours later in production.


16. How can you make a Spring bean thread-safe?

By default, Spring beans are Singletons, meaning the exact same instance is shared across multiple concurrent threads. To make a Spring bean thread-safe, you must ensure it can handle this concurrent access without causing race conditions or data corruption. There are three primary strategies to achieve this:

  • Stateless Beans (Recommended): The most effective approach is to design the bean with no mutable internal state. Avoid using class-level instance variables to store data that changes across requests. If a bean is entirely stateless, multiple threads can execute its methods concurrently without any synchronization issues.
  • Immutable State: If the bean must maintain internal state, make that state immutable. By declaring instance fields as final and initializing them only via the constructor, you guarantee that the state cannot be modified after creation, making the bean inherently thread-safe.
  • Thread-Local Storage: If you need to store state that is specific to a single thread’s execution context (like a user context or transaction ID), use ThreadLocal<T>. This provides each thread with its own independent, isolated copy of the variable, preventing cross-thread conflicts.

Interview Pro-Tip: The absolute best way to make a bean thread-safe is to make it completely stateless. Tell the interviewer that you strictly enforce a rule to keep all variable data local to the method execution (on the thread stack) rather than in class-level fields (on the heap).


17. What is Spring Expression Language (SpEL), and where can it be used?

The Spring Expression Language (SpEL) is a powerful expression language that supports querying and manipulating an object graph at runtime. It provides a highly flexible way to inject dynamic behavior into Spring-based applications.

SpEL is primarily used for evaluating dynamic expressions across various Spring features, including annotations, XML/Java configurations, and method invocations. Common use cases include:

  • Dependency Injection: Injecting dynamically computed values, system properties, or references to other beans using the @Value annotation.
  • Spring Security: Dynamically evaluating complex access control rules for method-level security (e.g., using @PreAuthorize("hasRole('ADMIN') and #user.isActive()")).
  • Caching and Data: Evaluating expressions to dynamically generate cache keys in Spring Cache, or for conditional routing in Spring Integration.

Interview Pro-Tip: A common real-world use case for SpEL that interviewers love to hear about is providing default values if an environment variable is missing. Mention how you safely handle missing configurations using syntax like @Value("${my.api.key:defaultKey}").


18. How does Spring handle property injection using @Value?

The @Value annotation in Spring is used to inject externalized configuration values directly into a Spring bean’s fields, methods, or constructor parameters. By decoupling hardcoded values from the source code, it makes applications highly flexible and environment-agnostic.

Spring can resolve and inject values from several sources:

  • Property Files: Injecting standard keys defined in application.properties or application.yml using the ${...} placeholder syntax.
  • Environment Variables: Spring automatically checks OS-level environment variables and system properties if a key isn’t found in a properties file.
  • Spring Expression Language (SpEL): You can inject dynamically computed values at runtime using the #{...} SpEL syntax.
@Component
public class DatabaseConfig {

    // Injects a value from application.properties
    @Value("${db.url}")
    private String dbUrl;

    // Injects a value with a default fallback if the key is missing
    @Value("${db.timeout:3000}")
    private int timeout;

    // Evaluates a SpEL expression dynamically
    @Value("#{systemProperties['user.timezone']}")
    private String timeZone;
}

Interview Pro-Tip: For modern enterprise applications, point out that using @ConfigurationProperties is highly preferred over scattering dozens of @Value annotations across your codebase. Tell the interviewer that @ConfigurationProperties provides type safety, validation, and much better organization for complex configurations.


19. How do you resolve circular dependencies in Spring?

A circular dependency occurs when two or more beans depend on each other (e.g., Bean A requires Bean B, and Bean B requires Bean A), creating a closed loop in the dependency graph. When Spring encounters this during context initialization (especially with constructor injection), it cannot determine which bean to create first and throws a BeanCurrentlyInCreationException.

There are three primary ways to resolve a circular dependency:

  • Use the @Lazy Annotation: By applying @Lazy to one of the injected dependencies, Spring will inject a proxy object instead of the fully initialized bean. The actual bean is only instantiated and injected later when it is first accessed, effectively breaking the initialization loop.
  • Switch to Setter Injection: Constructor injection requires all dependencies to be fully initialized before the object can be created. By switching to setter injection, Spring can instantiate the beans first (using their default constructors) and then inject the dependencies in a secondary phase.
  • Redesign the Architecture (Best Practice): Extract the overlapping business logic into a third, independent component (Bean C) that both Bean A and Bean B can depend on without relying on each other.

Interview Pro-Tip: Using @Lazy or Setter Injection is a handy quick fix for circular dependencies, but during an interview, always mention that a circular dependency usually indicates a design flaw. The best long-term solution is to refactor the code and decouple the components.


20. What is the difference between @Configuration and @Component?

While both annotations are used to register beans in the Spring application context, they serve entirely different architectural purposes and behave differently under the hood:

  • @Component: This is a general-purpose stereotype annotation. It is used to mark a class so that Spring’s classpath scanning automatically detects it and registers it as a managed bean. It is typically applied to classes containing standard business logic, utilities, or helpers.
  • @Configuration: This is a specialized form of @Component used to declare configuration classes. These classes act as factories, containing methods annotated with @Bean that allow you to manually instantiate, configure, and wire dependencies together.

The Critical Technical Difference (CGLIB Proxying): The most significant difference is how Spring handles internal method calls. Spring wraps @Configuration classes in a CGLIB proxy at runtime (often called “Full” mode). This guarantees that if one @Bean method calls another @Bean method within the same class, Spring intercepts the call and returns the cached singleton instance from the IoC container.

If you were to declare @Bean methods inside a standard @Component class (often called “Lite” mode), calling one method from another would act like a standard Java method call. It would instantiate a brand-new, unmanaged object, completely breaking Spring’s singleton semantics.

Interview Pro-Tip: The key difference is proxying. When an interviewer asks this, immediately mention CGLIB proxies and singleton semantics. Explaining that @Configuration intercepts internal method calls to return cached beans is a guaranteed way to prove your senior-level understanding of the framework.


21. Explain the use of the @Lazy annotation.

In Spring, the ApplicationContext uses eager initialization for singleton beans by default, meaning they are created and configured immediately when the application starts. The @Lazy annotation alters this behavior, instructing the container to delay the initialization of the bean until the exact moment it is explicitly requested.

There are two primary reasons to use @Lazy:

  • Startup Optimization: For beans that are incredibly resource-intensive to create (like heavy cache warmers, large file parsers, or complex external API connections), lazy initialization can significantly reduce application startup time and initial memory footprint.
  • Breaking Circular Dependencies: If Bean A and Bean B tightly depend on each other, annotating one of the injected dependencies with @Lazy tells Spring to inject a proxy object instead of the fully instantiated bean. The actual bean is only created when a method is invoked on that proxy later on, effectively breaking the initialization loop.

Interview Pro-Tip: While @Lazy sounds great for performance, tell the interviewer that you generally avoid using it globally. A major benefit of Spring’s default eager initialization is the “fail-fast” principle—if a bean is misconfigured, the application crashes immediately on startup. Overusing @Lazy hides these configuration errors until the bean is first accessed at runtime, which could result in a catastrophic crash in production hours later.


22. What is a stereotype annotation in Spring?

In Spring, a stereotype annotation is a specialized semantic marker (found in the org.springframework.stereotype package) used to define a class’s architectural role within an application. Under the hood, all stereotype annotations are essentially meta-annotations of the base @Component interface.

They serve two primary purposes:

  1. Auto-Detection: They signal to the Spring IoC container that the class should be automatically detected during classpath scanning (via @ComponentScan) and registered as a managed bean.
  2. Architectural Clarity & Behavior: They clarify the intended function of the class to developers and, in the case of @Repository, trigger specific framework behaviors.

The core stereotypes include:

  • @Component: The generic base annotation for any Spring-managed component.
  • @Service: A semantic marker for the business logic layer.
  • @Controller: Marks the presentation layer, enabling Spring MVC to route HTTP requests.
  • @Repository: Marks the Data Access Object (DAO) layer. Crucially, this specific stereotype alters framework behavior by triggering Spring’s exception translation mechanism, which catches vendor-specific database errors (like SQLException) and translates them into Spring’s unified, unchecked DataAccessException hierarchy.

Interview Pro-Tip: Stand out by mentioning Custom Stereotypes. Tell the interviewer that in large enterprise applications, you don’t just have to rely on Spring’s defaults. You can create your own custom stereotypes (like @UseCase or @WebAdapter) simply by creating a new interface and meta-annotating it with @Component. This shows a deep understanding of how Spring’s annotation processing actually works.

23. How does Spring handle externalized configuration?

Spring embraces the “12-Factor App” methodology, which states that configuration should be strictly separated from code. This allows you to deploy the exact same compiled application across multiple environments (Dev, QA, Prod) simply by swapping out the external configuration.

Spring handles this through a highly flexible Environment abstraction and a robust PropertySource mechanism.

Common Sources of External Configuration:

  • Properties/YAML Files: Standard application.properties or application.yml files packaged within the application, or externalized on the host system.
  • Environment Variables: OS-level environment variables (highly common in containerized environments like Docker/Kubernetes).
  • Command-Line Arguments: Arguments passed directly to the JVM at startup (e.g., --server.port=8081).

How to Consume External Configuration:

  • @Value Annotation: Injects individual property values directly into bean fields (supports SpEL and default fallbacks).
  • @ConfigurationProperties: Binds a hierarchical group of properties to a strongly-typed Java POJO. This is the modern best practice for complex configurations because it provides type safety and validation.
  • Environment Interface: You can inject Spring’s Environment object directly to fetch properties programmatically (e.g., env.getProperty("my.key")).

Interview Pro-Tip: Interviewers love asking about the Order of Precedence. You should mention that Spring evaluates these sources in a specific, strict order. For example, Command-Line Arguments will always override OS Environment Variables, which will always override values found in an application.properties file.


24. What is the use of the @Primary annotation, and when would you use it?

The @Primary annotation is used to designate a default bean when multiple beans of the same type exist in the Spring application context.

Normally, if Spring encounters multiple candidate beans for an @Autowired injection point, it cannot resolve the ambiguity and throws a NoUniqueBeanDefinitionException. By marking exactly one of those candidate beans with @Primary, you are telling the IoC container: “If there is ambiguity, always pick this one by default.”

When to use @Primary vs. @Qualifier:

  • Use @Primary when you have a clear, system-wide default implementation. For example, if you have multiple DataSource beans, you would mark the main production database as @Primary, and only use the secondary databases in specific edge cases.
  • Use @Qualifier when you need granular control at a specific injection point. @Qualifier acts as a local override to specify exactly which bean you want, regardless of the default.

Interview Pro-Tip: Interviewers will almost always follow this up by asking: “What happens if you use both @Primary and @Qualifier together?” The answer is that @Qualifier always wins. @Primary establishes the global default, but @Qualifier provides a specific, localized override that takes precedence.


25. What is the @Conditional annotation, and how does it enhance bean registration?

The @Conditional annotation provides a way to conditionally register beans in the Spring IoC container based on dynamic, runtime evaluations. If the specified condition evaluates to true, the bean is created and registered; if false, the bean is completely ignored.

This greatly enhances flexibility by allowing developers to enable or disable features based on the environment without changing the source code.

How it works: Under the hood, @Conditional relies on a custom class that implements Spring’s Condition interface. The framework invokes the matches() method on this class, which contains the logic to return true or false based on environment variables, system properties, or class availability.

Common Use Cases (via Spring Boot): While you can write custom conditions, Spring Boot provides a massive suite of built-in @Conditional derivatives that power its Auto-Configuration engine, such as:

  • @ConditionalOnProperty: Loads a bean only if a specific property is set (e.g., feature.toggle.enabled=true).
  • @ConditionalOnClass: Loads a bean only if a specific class is present on the classpath.
  • @ConditionalOnMissingBean: Loads a default bean only if the developer hasn’t already defined a bean of that same type.

Interview Pro-Tip: When asked this question, immediately pivot to Spring Boot Auto-Configuration. Tell the interviewer that @Conditional is the absolute backbone of Spring Boot. It is the exact mechanism that allows Boot to automatically configure a Tomcat server or an in-memory database simply by detecting those libraries on the classpath.


26. What is the purpose of the @DependsOn annotation in Spring? When should it be used?

The @DependsOn annotation is used to force the Spring IoC container to initialize one or more specific beans before the bean currently being created.

While Spring is generally smart enough to automatically calculate the correct initialization order based on your @Autowired or constructor injections, @DependsOn becomes necessary when you have implicit dependencies (also known as indirect dependencies).

When to use it: You use @DependsOn when Bean A relies on Bean B completing some setup or side effect, but Bean A does not directly inject Bean B. Common scenarios include:

  • Database Initialization: Ensuring a database schema is created or migrated (e.g., via Liquibase or Flyway) before the EntityManager or DAO beans attempt to connect to it.
  • Static Caches: Forcing a configuration bean to load and populate a static cache or system properties before another bean tries to read those values during its @PostConstruct phase.

Interview Pro-Tip: Interviewers look for developers who know when not to use a feature. Tell them that while @DependsOn is a useful tool, you treat it as a last resort. In modern Spring applications, relying on implicit dependencies or global static state is often a sign of poor architectural design.


27. What is the @PropertySource annotation, and how is it used to load properties files?

In Spring, the @PropertySource annotation provides a convenient, declarative mechanism for adding custom property files to Spring’s global Environment.

While Spring Boot automatically loads application.properties by default, you use @PropertySource when you want to externalize specific configurations into separate, custom files (e.g., database.properties or email.properties) and inject those values into your beans using the @Value annotation.

Example Usage:

1. The Properties File (custom.properties):

# custom.properties
custom.dir=MyDir
custom.file=readme

2. The Configuration Class:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.beans.factory.annotation.Value;

@Configuration
@PropertySource("classpath:custom.properties")  // Specify the path to the properties file
public class AppConfig {

    @Value("${custom.dir}")
    private String dirName;

    @Value("${custom.file}")
    private String fileName;

    public void printFileDetails() {
        System.out.println("Dir Name: " + dirName);
        System.out.println("File Name: " + fileName);
    }
}

Interview Pro-Tip: A great detail to mention during an interview is the ignoreResourceNotFound attribute. By default, if the file specified in @PropertySource is missing, the application will crash on startup. You can tell the interviewer that you use @PropertySource(value = "classpath:custom.properties", ignoreResourceNotFound = true) to prevent crashes if that specific file is optional for the current environment.


28. What is @ConfigurationProperties, how you bind the external properties to Java Object?

The @ConfigurationProperties annotation in Spring is used to map, or “bind,” a hierarchical group of external properties (from application.properties or application.yml) into a strongly-typed Java POJO.

Unlike the @Value annotation—which injects properties one by one—@ConfigurationProperties provides a structured, type-safe, and highly maintainable way to manage complex configuration data.

How to bind external properties: To achieve this, you define a prefix in the annotation that matches the property structure, and Spring will automatically map the nested properties to the class fields using standard Java setters.

1. External Properties (application.properties):

#application.yml

app:
  name: MyApp
  version: 1.0.0
  features:
    enable: true
    maxUsers: 100

dev:
  port: 3030

2. The Java Object:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {

    private String name;
    private String version;
    private Features features;

    public static class Features {
        private boolean enable;
        private int maxUsers;

        // Getters and setters
    }

    // Getters and setters for name, version, and features
}

Interview Pro-Tip: A massive advantage of @ConfigurationProperties over @Value is Validation. Tell the interviewer that you combine @ConfigurationProperties with @Validated and standard JSR-303 annotations (like @NotNull, @Min, @Max) directly on the POJO fields. This ensures the application adheres to the “fail-fast” principle by crashing immediately on startup if a critical configuration value is missing or formatted incorrectly in the production environment.


29. What are the differences between @qualifier vs @primary

Both annotations are used to solve the NoUniqueBeanDefinitionException—which occurs when Spring finds multiple beans of the same type during auto-wiring and doesn’t know which one to inject. However, they solve the problem from different angles.

How they work in practice:

  • @Primary: Tells Spring, “If a component asks for this type of dependency and doesn’t specify a name, provide this exact bean by default.”
  • @Qualifier: Tells Spring, “I don’t care what the default is; I specifically want the bean named X.”

Interview Pro-Tip: A classic enterprise scenario for these annotations is database routing. Use @Primary for your main read/write master database so developers don’t have to qualify every standard injection, and use @Qualifier specifically when a reporting service needs to connect to the read-only replica.


We hope that this list of interview questions and responses has strengthened your grasp of the framework. Make sure to continue your exploration, work with real-world examples, and keep up with the most recent advancements in Spring. Happy coding and best of luck on your Spring Core interview.

Acknowledgments
The content of this article is inspired by the official Spring Framework documentation. I appreciate the comprehensive resources provided by the Spring team, which greatly helped in creating this list of interview questions.

For a deeper understanding of Spring, consider enrolling in our Online Spring Framework Training

Filed Under: Spring Tagged With: Spring Core Interview Questions

Reader Interactions

Comments

  1. Akash Shinde says

    March 13, 2026 at 2:12 pm

    Very Useful.

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

Mr Chinmay

Chinmay Patel
Online Java Tutor-Demo Class

Phone & Whatsapp +919853166385
javatution@gmail.com

Recent Posts

  • Learn Java in One Day: 1-on-1 Private Crash Course
  • Constructor in Java and Overloaded Constructor Example Program
  • Important Interview Questions on Java Multithreading
  • React Spring Boot Web Services Integration
  • Spring Boot RESTful Web Services Example
  • Top Spring MVC Interview Questions and Answers for Developers
  • Top Spring Core Interview Questions and Answers for Developers
  • Host Java Web Apps for Free on Mobile with Tomcat and Termux
  • How to Deploy Java Web Application on Aws EC2 with Elastic IP
  • Simple Jsp Servlet Jdbc User Registration using Tomcat Mysql and Eclipse
Copyright © 2026 JavaTutorOnline