Spring Core Interview Questions
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 simplify the building of enterprise level applications. It supports features like dependency injection, aspect-oriented programming (AOP), and transaction management. These features make the code easier to maintain, loosely coupled, and simple to test. Spring also integrates well with other frameworks and tools with less effort.
2. Explain Inversion of Control (IoC).
IoC (Inversion of Control) is a design principle where the control of creating an object is managed by the Spring container. This is done with the help of dependency injection, where Spring automatically injects the dependencies into the dependent class, instead of creating it by itself. This makes the code more flexible and loosely coupled.
For a deeper understanding of Spring, consider enrolling in our Online Spring Framework Training
3. Explain Dependency Injection (DI). What are the different types of Dependency Injection in Spring?
Dependency Injection is a method used by the container implementing the Inversion of Control design pattern to resolve the dependencies of the classes. In this, dependencies are injected into a class by using constructor injection, setter injection, or the field injection.
Constructor-based dependency injection –
- In this way spring container resolve the dependencies of the class by providing it through its constructor.
- This is the most preferred method, as it ensures that the required dependencies are available during bean creation.
Setter-based dependency injection –
- In setter based injection, dependencies are set using setter methods after the bean is instantiated.
- It is used when a dependency is optional or when the object may need to be reconfigured after initialization.
- To overcome the circular dependency issue.
Field-based dependency injection –
- This way dependencies are injected directly into the fields of the class.
- This is the most concise method, but it’s not recommended for production code because it bypasses encapsulation.
- It is often used with annotations like
@Autowired
.
4. What are ApplicationContext and BeanFactory and how they differ?
ApplicationContext and BeanFactory are both IoC containers in the Spring Framework responsible for managing the life cycle of beans. These containers are implementations of the Inversion of Control (IoC) design pattern. They uses dependency Injection techniques like constructor injection, field injection, and setter injection to resolve the dependencies of dependent classes. We generally prefer to use ApplicationContext because it extends BeanFactory and provides other additional features.
BeanFactory –
- This is the basic container in Spring that provides fundamental bean management capabilities.
- It is used where memory consumption is critical, as it initializes beans only when required.
ApplicationContext –
- This container extends
BeanFactory
and adds more advanced features, such as event propagation, AOP, and support for internationalization. - It immediately initializes beans by default and it is more commonly used in Spring based applications.
5. How does the Spring IoC container work? *
The Spring IoC (Inversion of Control) container is responsible for managing the lifecycle and dependencies of beans in a Spring application. It works based on the principle of Dependency Injection (DI), where the container creates and manages objects (beans) and injects their dependencies. Here’s how it works:
- Bean Definition: Beans are defined in the container either through XML configuration, Java-based configuration, or annotation-based configuration. Each bean can be configured with dependencies, lifecycle methods, and other properties.
- Bean Creation: The container creates the beans by reading the configuration and instantiating the classes based on the defined bean definitions. It handles the lifecycle of beans, from creation to destruction.
- Dependency Injection: Once the beans are created, the container injects their required dependencies, either via constructor, setter methods, or field injection. This is where Spring manages the relationships between objects and ensures that beans are properly initialized with their dependencies.
- Bean Lifecycle: The container manages the lifecycle of beans, which includes calling any init methods (like those annotated with @PostConstruct) and handling destruction (like methods annotated with @PreDestroy). For singleton beans, the container creates them only once, whereas for prototype beans, a new instance is created every time they are requested.
- Scope Management: Spring allows you to define bean scopes (e.g., singleton, prototype) that determine the lifespan and sharing behavior of beans within the container.
- IoC Container: The IoC container in Spring effectively handles the creation, configuration, and management of beans, decoupling application components and making it easier to maintain, test, and extend.
6. What is the difference between @Component
, @Controller
, @Service
, and @Repository
annotations?
In Spring, these annotations are used to mark classes as Spring beans, which means that they’re managed by the Spring IoC container. These annotations are variations of @Component
, and each serves a different purpose depending on the role of the class in the application.
@Component
:- This is a generic annotation in the Spring framework used to mark a class as a Spring managed bean, registering it in the application context.
- We can use it for any type of component in the application, like utility classes or helper functions as it doesn’t suggest any specific role.
@Controller
:- This one is a specialized version of
@Component
, and it’s used for controller classes in a Spring MVC based web application. - It indicates that the class is responsible for handling HTTP requests and responses.
- This one is a specialized version of
@Service
:- This annotation is also a specialized form of
@Component
. We use it to mark service classes that hold business logic. - It is used to indicate that this class is responsible for handling core business operations, like processing payments, managing users or interacting with for DAO classes.
- This annotation is also a specialized form of
@Repository
:- This is another specialization of
@Component
, it is used to mark classes responsible for data access, like interacting with a database. - We use it to define the persistence layer of an application, where we handle things like querying the database or performing CRUD operations.
- This is another specialization of
We use them to clarify the intent of the class and its role within the application. This makes the code more organized and easier to understand.
7. How are beans defined in Spring? *
In Spring, there are multiple ways to define the beans based on the configuration style being used. The most common methods for defining beans are through XML configuration, Java based configuration, and annotation based configuration. In all cases, Spring’s IoC container manages the lifecycle of these beans, handling their creation, initialization, and dependency injection based on the configuration provided.
XML Configuration:
- This XMl one is a traditional approach, beans are defined in an XML file (
applicationContext.xml
or similar). You specify the class and its properties (such as dependencies) within<bean>
tags. - 123<bean id="myBean" class="com.example.MyBean"><property name="someProperty" value="Some Value" /></bean>
Java-based Configuration (using @Configuration
and @Bean
):
- In Java based configuration, beans are defined in a Java class annotated with
@Configuration
. Inside this class, we use the@Bean
annotation to declare methods that return bean objects. This approach allows more flexibility and avoids XML. - 1234567891011<!-- Java Configuration Example -->@Configurationpublic class AppConfig {@Beanpublic MyBean myBean() {MyBean myBean = new MyBean();myBean.setSomeProperty("Some Value");return myBean;}}
Annotation-based Configuration:
- Beans can be defined directly in the class by using annotations like
@Component
,@Service
,@Repository
, or@Controller
. These annotations mark the class as a Spring-managed bean, and Spring will automatically detect and register it through classpath scanning (typically with@ComponentScan
)
In modern spring we generally use annotation based and java based configuration together.
8. What is the scope of Spring beans? *
In Spring these scopes allow us to control how beans are created and shared, depending on the requirements of the application. For example, Singleton
is useful for stateless services, while Prototype
is suitable for stateful or independent objects. This is done with the help of @Scope
annotation.
- Singleton: A single instance is created for the entire Spring container. This is the default scope and is useful for stateless services and shared resources.
- Prototype: A new instance is created every time the bean is requested. This is suitable for stateful or independent objects that are not shared across the application.
- Request: A single instance is created for each HTTP request. This scope is applicable only in a web-aware Spring ApplicationContext.
- Session: A single instance is created for each HTTP session. This scope is also applicable only in a web-aware Spring ApplicationContext.
- Global Session: A single instance is created for the entire global HTTP session. This scope is less commonly used and is intended for use in portlet-based web applications.
9. What are Spring profiles, and how are they used?
Spring profiles allow us to define different configurations for various environments, such as development, testing, or production. By using profiles, we can ensure that the application uses different configurations based on the environment it is running in, without changing any code.
For example, we can have a dev profile for development purpose which has its own set of configuration for database and one for production which is more optimised for better performance.
We can define these settings in Java classes with the help of the @Profile
annotation and by setting spring.profiles.active
to the desired profile in the application.properties
file.
1 2 3 4 5 6 7 8 | @Configuration @Profile("dev") public class DevConfig { @Bean public DataSource dataSource() { return new HikariDataSource(); // Development-specific database } } |
10. What is the difference between singleton and prototype bean scopes? *
In Spring, the singleton and prototype bean scopes define how beans (objects) are created and managed in the Spring container. Here’s a breakdown of the key differences:
- Singleton Scope:
- A singleton bean is created only once during the entire lifecycle of the Spring container.
- Every time the application requests the bean, the same instance is returned.
- This is the default scope in Spring.
- It’s useful when you want to share a single instance of a bean across the entire application (like a service or database connection).
- Prototype Scope:
- A prototype bean is created every time the application requests it.
- Each request results in a new instance of the bean.
- This is helpful when the bean needs to be stateful or when you want different configurations every time the bean is accessed.
11. What are the different ways to configure a Spring application?
12. How do you define and use a custom bean in Spring?
There are multiple ways to define the custom bean in Spring, we can define it using Java based configuration by annotating a method with @Bean
inside a @Configuration
class or using annotation based configuration by marking the class with @Component
. We can also use the traditional method to define the beans like using the bean tag in xml.
In Java configuration, we can create a method like @Bean public MyCustomBean myCustomBean() { return new MyCustomBean(); }
or we can simply annotate a class with @Component
or with its specialized version of annotation. Now to inject those custom bean to object or dependent class, we use @Autowired
or we can also manually retrieve it from the ApplicationContext
with context.getBean(MyCustomBean.class)
. This allows us to define and use the custom bean across our Spring application.
Make sure the @ComponentScan
annotation is configured to locate all bean classes, especially those that depend on the beans defined in your configuration class.
13. What is @Autowired
, and how does it work?
In Spring, @Autowired
annotation is used to automate the injection of dependencies. This annotation is useful when we are using field injection, setter injection, or when we have multiple constructors (well not in case of single constructor). When we use @Autowired
on a field, constructor, or setter method, Spring automatically resolves and injects the appropriate bean from the Spring container.
14. What is the role of the @Qualifier
annotation?
We use @Qualifier
annotation in Spring to resolve ambiguity when there are multiple beans of the same type, and we need to specify which one should be injected. When we use @Autowired
to inject a dependency, if multiple beans of the same type are available, Spring won’t know which one to choose and will throw an exception. By using @Qualifier
, we can explicitly tell Spring which bean to inject.
15. Explain the difference between constructor-based and setter-based DI.
Both are the common technique of dependency injection but there are some differences like –
- Initialization:
- Constructor based DI initializes the dependencies at the time of bean creation.
- But setter based DI set the dependencies after the bean is created.
- Immutability:
- Constructor based DI helps in making the bean immutable by setting final fields.
- But, setter based DI allows for mutable beans as dependencies can be changed after instantiation.
- Required Dependencies:
- Constructor based DI is suitable for mandatory dependencies.
- But, setter based DI is useful for optional dependencies.
- Flexibility:
- Constructor based DI is less flexibility as all dependencies must be available at bean creation.
- But in case of setter based DI, It provides more flexibility as dependencies can be set or changed later.
16. How can you make a Spring bean thread-safe? *
To make a Spring bean thread safe, we need to ensure that it can handle concurrent access from multiple threads without causing issues like race conditions. There are multiple ways for achieving thread safety in Spring beans…
- Stateless Beans: We can make sure that the bean doesn’t keep any internal state, like storing data in instance variables that might be shared between threads. If the bean is stateless, multiple threads can access it at the same time without running into synchronization issues.
- Immutable State: If the bean must maintain state, the state should be immutable, which means once created, its state shouldn’t be changed. This makes the bean automatically thread safe.
- Thread-local Storage: We can also use
ThreadLocal<T>
, this will allows each thread to have its own independent copy of data, preventing conflicts between threads accessing shared resources.
17. What is Spring Expression Language (SpEL), and where can it be used?
Spring Expression Language (SpEL) is a expression language used by Spring Framework. It allows developers to query and manipulate the objects at runtime, this provides a way to embed dynamic behavior into Spring based applications. We use SpEL for evaluating expressions with various Spring features like annotations, configuration files, and method invocations.
SpEL can be used to inject values into Spring beans using the @Value
annotation. It can also be used with Spring security to evaluate access control dynamically for method security or authorization checks.
18. How does Spring handle property injection using @Value
?
Spring uses the @Value
annotation to inject values directly into Spring beans from various sources, such as property files. This allows for dynamic configuration, making the application more flexible by decoupling hardcoded values from the code.
It also support computing dynamic values using SpEL at runtime or fetching environment variables.
19. How do you resolve circular dependencies in Spring?
In Spring, circular dependencies occur when two or more Spring beans depend on each other, either directly or indirectly. This create a loop in the dependency graph. In such case, Spring throws an exception if it is not able to resolve the dependencies.
There are several ways to resolve this circular dependencies problem:
- Setter Injection: We can resolve it by switching from constructor based injection to setter-based injection. With setter injection, Spring can create the beans first and then inject the dependencies afterward.
-
@Lazy
Annotation: We can also use@Lazy
annotation in some cases to break the circular dependency by telling Spring to lazily initialize the bean only when it’s required.
20. What is the difference between @Configuration
and @Component
?
@Component
and @Configuration
annotations in Spring both help define beans, but they have different purposes. @Component
is a general annotation used to mark any class as a Spring-managed bean. When we use it, Spring automatically scans for that class and registers it as a bean, allowing Spring to handle its lifecycle and dependencies.
@Configuration
, on the other hand, is a more specialized form of @Component
designed specifically for configuration classes. These classes are meant to define and configure beans using methods annotated with @Bean
. With @Configuration
, we have have fine control over how beans are created and how their dependencies are set up. Spring also creates a proxy for classes annotated with @Configuration
to ensure that beans defined in them are properly managed.
21. Explain the use of the @Lazy
annotation.
@Lazy
annotation in Spring delays the initialization of a bean until it is actually needed. By default, beans are eagerly initialized, but when we mark a bean with @Lazy
, it is only created when accessed for the first time. This helps improve startup performance and reduces resource consumption, as the bean isn’t created immediately. We generally use it to resolve circular dependency problems.
22. What is a stereotype annotation in Spring?
In Spring, a stereotype annotation is a type of annotation used to define a class as a Spring bean, indicating its role in the application. These annotations are specialized forms of @Component
, providing class intended function. We can import stereotype from package org.springframework.stereotype
Some common stereotypes are –
@Component
: It is a general purpose annotation marking a class as a Spring managed bean.@Service
: Used to mark service layer beans that hold business logic.@Repository
: Used for DAO (Data Access Object) beans, marking them for exception translation (If there any db error then it will be translated into Java exception e.g., DataAccessException)@Controller
: Used for web controllers in Spring MVC and REST API for handling HTTP requests and responses.
23. How does Spring handle externalized configuration?
Spring handles externalized configuration through application.properties
or application.yml
files, environment variables, and command-line arguments. These methods allow application settings to be managed outside the code, making it easier to adapt the application to different environments. The @Value
annotation and @ConfigurationProperties
are commonly used to inject these external values into the application.
24. What is the use of the @Primary annotation, and when would you use it?
We use @Primary
annotation in Spring to specify a default bean that need to be injected when multiple beans of the same type are available in the application context. If no specific bean is qualified by @Qualifier
, the one we marked with @Primary
will be used.
25. What is the @Conditional annotation, and how does it enhance bean registration?
The @Conditional
annotation in Spring controls bean creation based on specific conditions. For example, it can load a bean only if a particular class is present or a property is set in the environment, making the application more flexible.
26. What is the purpose of the @DependsOn annotation in Spring? When should it be used?
The @DependsOn
annotation in Spring is used to specify the order in which beans should be initialized. It ensures that one bean is created before another. We should use it when one bean depends on another for proper initialization.
But In most cases, we don’t need to use @DependsOn
because Spring manages the order of bean initialization automatically based on dependencies.
26. What is the @PropertySource annotation, and how is it used to load properties files?
In Spring, we use the @PropertySource
annotation to specify the location of properties files that contain configuration values of our application. It allows us to load external property files into the Spring Environment, so that we could access those values within your beans.
1 2 3 | # custom.properties custom.dir=MyDir custom.file=readme |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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); } } |
27. What is @ConfigurationProperties, how you bind the external properties to Java Object?
We use @ConfigurationProperties
annotation in Spring to bind external properties (from .properties
or .yml
files) to a Java object. This provides a structured and type-safe way to load configuration values in our application.
How to Bind External Properties to a Java Object Using –
- Create a POJO (Plain Old Java Object) class to represent configuration properties, annotated with
@ConfigurationProperties
, where the prefix specifies which properties should be mapped to the fields in the POJO. - If you haven’t used it with any stereotype annotation, you need to use
@EnableConfigurationProperties
in the class that is supposed to use this property object. In Spring Boot, this is automatically enabled.
1 2 3 4 5 6 7 8 9 10 11 | #application.yml app: name: MyApp version: 1.0.0 features: enable: true maxUsers: 100 dev: port: 3030 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 } |
prefix
in @ConfigurationProperties
specifies that only the properties starting with the given prefix should be bound to the annotated class. If no prefix is provided then it will try to bind with all the properties of that file.
28. What are the differences between @qualifier vs @primary
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.
Leave a Reply