Spring and Spring Boot Interview Questions
Q1. What is Dependency Injection?
Definition: Dependency Injection (DI) is a design pattern in which an object receives other objects that it depends on, known as dependencies, from an external entity rather than creating them itself.
Dependency Injection (DI) is a design pattern used in object-oriented programming to achieve Inversion of Control (IoC) between classes and their dependencies. Instead of a class creating its own dependencies, those dependencies are provided by an external framework (in this case, Spring), promoting loose coupling and easier testing.
In simpler terms, DI allows an object to receive its dependencies from the outside rather than creating them internally. This promotes flexibility and modularity.
Q2. Why is Dependency Injection Important?
Loose Coupling: Classes are decoupled from their dependencies, making the code more modular and easier to maintain.
Testability: It allows for easy mocking of dependencies during unit testing since the dependencies are injected externally.
Simplified Code: The class doesn't have to manage the creation or lifecycle of dependencies, which reduces boilerplate code and simplifies the design.
Maintainability: Since dependencies are passed in from the outside, the code becomes more adaptable to change.
Q3. How can you implement Dependency Injection in Spring?
In Spring, Dependency Injection (DI) can be implemented in three different ways:
Constructor Injection
Setter Injection
Field Injection
Each approach has its own advantages and trade-offs, and the choice of which to use depends on the design and structure of your application. Let's dive into each of them in detail.
Constructor Injection
Constructor Injection is when dependencies are provided to a class through its constructor. Spring resolves and injects the necessary dependencies when it creates the bean.
How it Works:
Spring automatically calls the constructor of the bean and injects the required dependencies as constructor parameters.
Dependencies are mandatory (since constructors can't be called without providing arguments).
Example:
@Component
public class UserService {
private final UserRepository userRepository;
// Constructor Injection
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void performService() {
// logic
}
}
In this case:
UserService depends on UserRepository.
The UserService class receives its UserRepository dependency through the constructor.
Advantages of Constructor Injection:
Immutability: Dependencies are provided when the object is created, which promotes immutability (a good practice in modern programming).
Mandatory Dependencies: The class cannot be instantiated without its dependencies, ensuring that all required dependencies are provided.
Easier Testing: Dependencies are clearly visible and can be easily mocked or substituted in tests.
Recommended Practice: It’s generally considered a best practice to use constructor injection, especially for mandatory dependencies.
Disadvantages:
If a class has many dependencies, the constructor may become cluttered with too many parameters (constructor bloat).
Setter Injection
Setter Injection involves injecting dependencies into a class using setter methods. Spring calls the setter methods after the object is created to inject the dependencies.
How it Works:
Dependencies are injected through setter methods.
Dependencies are optional, meaning you can create the object even if some dependencies are not yet set.
Example:
@Component
public class UserService {
private UserRepository userRepository;
// Setter Injection
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void performService() {
// logic
}
}
In this case:
UserService has a setter method setUserRepository() that allows Spring to inject the UserRepository dependency.
Advantages of Setter Injection:
Flexibility: Allows you to set or change dependencies after object creation, which can be useful if the dependency is optional or can be replaced later.
Clearer for Optional Dependencies: It’s easier to communicate that a dependency is optional through setter methods.
Disadvantages:
State Mutability: Since dependencies can be set after object creation, it leads to a mutable state, which can cause issues if the object is used before all dependencies are set.
Lack of Mandatory Dependency Enforcement: The class may be instantiated in an incomplete state if the setters are not called, leading to potential runtime errors.
Field Injection
Field Injection is when Spring directly injects dependencies into a class’s fields (member variables) without using constructors or setters. This is done using the @Autowired annotation directly on the field.
How it Works:
Spring injects the required dependencies directly into the fields, without using constructor or setter methods.
Example:
@Component
public class UserService {
@Autowired
private UserRepository userRepository;
public void performService() {
// logic
}
}
In this case:
The @Autowired annotation is used directly on the userRepository field, and Spring injects the dependency into this field.
Advantages of Field Injection:
Simplicity: Reduces boilerplate code, as there’s no need for setter or constructor methods.
Less Code: The code is cleaner since dependencies are injected directly into fields.
Disadvantages:
Hidden Dependencies: Dependencies are not as visible, making it harder to identify required dependencies for the class.
Testability Issues: Field Injection is more difficult to test, as you have to use reflection or frameworks like Mockito to inject mocks into private fields.
Violation of SOLID Principles: Field Injection can violate the Single Responsibility Principle and the Dependency Inversion Principle, as classes are no longer responsible for managing their own dependencies.
Not Recommended for Mandatory Dependencies: Constructor Injection is preferred for mandatory dependencies because Field Injection can make it difficult to ensure that all required dependencies are properly initialized.
Best Practices and When to Use Each Approach
Constructor Injection:
Best for mandatory dependencies. It promotes clean code, immutability, and is easier to test.
Use it whenever the object must have its dependencies when it’s created.
Setter Injection:
Best for optional dependencies or when you might want to change dependencies after object creation.
Use it if you have optional or mutable dependencies and flexibility is needed in the lifecycle.
Field Injection:
Use it sparingly for simple use cases where testability and loose coupling are not concerns.
Avoid using it for mandatory or critical dependencies. It's generally discouraged due to testability and visibility concerns.
Conclusion
Constructor Injection is recommended for mandatory dependencies, where objects should not exist without all their dependencies. It also promotes immutability.
Setter Injection is more suited for optional dependencies or cases where dependencies may change after the object is created.
Field Injection is less visible and harder to test, which is why it’s generally discouraged, but it may simplify code for small projects or components with minimal dependencies.
In modern Spring development, Constructor Injection is the preferred approach due to its clarity, immutability, and ease of testing.
Q4. What are Beans?
Definition: A bean is an object managed by the Spring IoC (Inversion of Control) container. Spring beans are defined and instantiated by the container and injected into dependent objects. These beans form the backbone of a Spring application, representing the components that get instantiated, configured, and assembled by the container at runtime. Beans are typically defined using annotations or in XML configuration, and Spring manages their life cycle, from creation to destruction.
Q5. How Do You Define a Bean in Spring?
There are several ways to define a bean in Spring:
Using @Bean Annotation in a Configuration Class
A method annotated with @Bean inside a class marked with @Configuration defines a Spring bean.
Example:
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
Here, userService() defines a bean named userService of type UserService. The Spring container will manage the life cycle of this object.
Using @Component Annotation
Another way to define a bean is by annotating a class with @Component, which automatically registers it as a Spring bean.
Example:
@Component
public class UserService {
// business logic
}
When you annotate a class with @Component, Spring will automatically detect and register this class as a bean if component scanning is enabled using @ComponentScan.
Other Stereotype Annotations
In addition to @Component, other annotations like @Service, @Repository, and @Controller are specializations of @Component and are used to denote specific roles in the application:
@Service: Used for service classes.
@Repository: Used for DAO classes (data access layer).
@Controller/@RestController: Used for web controllers.
Q6. What are the different scopes available for beans?
Bean Scopes in Spring defines the life cycle and visibility of the bean.
There are five scopes in Spring, with two being the most commonly used (singleton and prototype).
Singleton (Default Scope)
Definition: Only one instance of the bean is created per Spring IoC container. This instance is shared across the application.
When to Use: When the bean is stateless or needs to be shared across the application.
Example:
@Bean
@Scope("singleton") // Optional, as "singleton" is the default
public UserService userService() {
return new UserService();
}
Prototype
Definition: A new instance is created each time the bean is requested.
When to Use: For beans that are stateful or need to maintain unique instances per request.
Example:
@Bean
@Scope("prototype")
public UserService userService() {
return new UserService();
}
Request
Definition: A new instance of the bean is created for each HTTP request. This scope is typically used in web applications.
When to Use: For beans that need to have unique instances per HTTP request.
Example:
@Bean
@Scope("request")
public UserService userService() {
return new UserService();
}
Session
Definition: A new instance of the bean is created for each HTTP session.
When to Use: For beans that need to store session-specific data.
Example:
@Bean
@Scope("session")
public UserService userService() {
return new UserService();
}
Application
Definition: A single instance is created for the entire application across all HTTP requests and sessions.
When to Use: For beans that need to maintain application-wide state.
Example:
@Bean
@Scope("application")
public UserService userService() {
return new UserService();
}
Q7. How Does Spring Manage Bean Life Cycle?
Creation: Spring creates the bean using either the @Bean method or via component scanning (@Component, @Service, etc.).
Initialization: The bean undergoes initialization via the @PostConstruct method or through an InitializingBean implementation.
Use: The bean is injected into other components where needed, such as via @Autowired.
Destruction: Spring manages the bean's destruction (especially in the case of singleton) using methods like @PreDestroy or DisposableBean.
Q8. What are Annotations?
Definition: Annotations in Spring provide metadata for classes and methods, guiding Spring on how to configure and handle them.
Q9. Can you explain some commonly used annotations in Spring and their purposes?
Common Annotations:
@Component, @Service, @Repository, @Controller: Define Spring-managed components.
@Autowired: Enables DI by injecting the required bean into a class.
@Configuration, @Bean: Define and configure beans programmatically.
@RestController: Combines @Controller and @ResponseBody for REST APIs.
Q10. What is the difference between Spring and Spring Boot?
Spring is a full-fledged comprehensive framework providing infrastructure support for developing Java applications with extensive manual configurations for web applications, security, AOP, data access, etc.
Spring Boot is an extension of Spring, aimed at reducing boilerplate code, simplifying application configuration and development. It provides embedded servers (like Tomcat, Jetty), auto-configuration, and opinionated starter dependencies.
Q11. How does Spring Boot simplify application development compared to Spring?
Spring Boot simplifies application development significantly compared to the traditional Spring Framework by providing a suite of tools, pre-configurations, and conventions that minimize the need for manual setup. Here's a detailed look at how Spring Boot simplifies things:
1. Opinionated Defaults and Auto-Configuration
Spring requires extensive configuration (XML or annotations) to wire up dependencies, configure data sources, manage transactions, set up MVC, etc. Spring Boot takes an opinionated approach by providing sensible defaults and auto-configuration to reduce manual configuration.
Auto-Configuration: Spring Boot automatically configures components like database connections, web servers, and security settings based on the dependencies included in the project. For example, if you add the Spring Data JPA dependency, Spring Boot automatically configures Hibernate and the datasource.
Example: You don’t need to write explicit configurations for a DataSource or EntityManagerFactory; Spring Boot handles that based on the classpath.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
2. Embedded Web Server
Spring applications typically require a separate web server like Tomcat or Jetty, and you need to deploy the WAR file manually. Spring Boot embeds the web server within the application itself, allowing you to create standalone JAR files that can be run directly with java -jar.
Embedded Tomcat/Jetty/Undertow: Spring Boot comes with an embedded Tomcat by default, but you can switch to Jetty or Undertow if needed. This means no need for external web servers.
java -jar myapp.jar
Advantage: Simplifies deployment and testing, as you can run the application directly without the need to install a web server separately.
3. Reduced Boilerplate Code
Spring applications require writing boilerplate code for configuring MVC, security, and database layers (DAO, repository, etc.). In contrast, Spring Boot eliminates the need for boilerplate setup.
Starters: Spring Boot provides Starter POMs (predefined Maven/Gradle dependencies) for various functionalities like Spring Data, Spring Security, Thymeleaf, etc. These starters bundle the necessary libraries and handle the configuration for you.
Example: Adding the spring-boot-starter-web dependency automatically sets up the entire web layer.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
This includes:
DispatcherServlet
Embedded Tomcat
Default error handling
4. No XML Configuration Required
Traditional Spring requires a lot of XML-based configuration (applicationContext.xml, dispatcher-servlet.xml). Spring Boot, however, encourages annotation-based configuration using Java.
Annotations like @Configuration, @ComponentScan, and @EnableAutoConfiguration enable a fully Java-based configuration, eliminating the need for XML files.
@SpringBootApplication // Combines @Configuration, @EnableAutoConfiguration, and @ComponentScan
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
5. Production-Ready Features
Spring Boot includes production-ready features out of the box, allowing you to monitor, secure, and optimize your application easily.
Spring Boot Actuator: Provides built-in endpoints to monitor and manage the application, including health checks, metrics, logging, environment properties, and more.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Common endpoints include /actuator/health, /actuator/metrics, etc.
This makes it easier to integrate monitoring tools like Prometheus or Grafana.
6. Opinionated Development Practices
Spring Boot encourages best practices with a focus on convention over configuration. It comes pre-configured with sensible defaults, allowing you to avoid manual setup for common components (like security, databases, logging, etc.).
Built-in Profiles: It includes built-in support for different environments (e.g., dev, test, prod) through Spring Profiles. This allows you to load different configurations based on the active profile.
# application-dev.properties
spring.datasource.url=jdbc:mysql://localhost:3306/devdb
spring.datasource.username=dev_user
spring.datasource.password=dev_pass
# application-prod.properties
spring.datasource.url=jdbc:mysql://prod-db-server:3306/proddb
spring.datasource.username=prod_user
spring.datasource.password=prod_pass
7. Built-in Security
Spring Security can be complex to configure in traditional Spring applications. Spring Boot simplifies this by automatically applying basic security configurations.
By simply adding the spring-boot-starter-security dependency, Spring Boot enables basic security with form-based login and CSRF protection.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
It also provides default configurations, such as a generated password for the user, so you don’t have to configure everything manually.
8. Externalized Configuration
Spring Boot simplifies external configuration using the application.properties or application.yml files. Instead of hardcoding configuration values like URLs, database details, or API keys, you can externalize them into properties files, making them environment-specific and easier to manage.
Example: In application.properties or application.yml, you can define various properties like server port, database URL, etc.
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=secret
This makes applications more portable and configurable without recompilation.
9. Streamlined Dependency Management
Spring Boot handles dependency management through its parent POM or BOM (Bill of Materials). Instead of managing multiple library versions, Spring Boot provides a well-tested, consistent stack of libraries and dependencies.
Spring Boot's starters automatically pull in compatible dependencies.
The spring-boot-starter-parent automatically provides versioning for Spring libraries and ensures that all libraries are compatible with each other.
10. Faster Development and Prototyping
Spring Boot CLI allows developers to write Groovy scripts and quickly create Spring applications without needing a full-fledged Java IDE or Maven/Gradle setup.
Rapid Application Development: Developers can prototype applications quickly with minimal boilerplate code.
Embedded Servers and Automatic Restart: Tools like Spring Boot DevTools enable automatic restarts during development, speeding up the process.
Q12. What is the Starting Point of a Spring Boot Application?
The starting point of a Spring Boot application is the main class that contains the main method. This class is annotated with @SpringBootApplication, which triggers the auto-configuration and component scanning features of Spring Boot.
Breakdown of the Starting Point:
@SpringBootApplication Annotation:
The class containing the main method is typically annotated with @SpringBootApplication. This annotation is a convenience annotation that combines the functionality of:
@Configuration: Marks the class as a source of bean definitions.
@EnableAutoConfiguration: Enables Spring Boot’s auto-configuration mechanism, which automatically configures beans based on the classpath.
@ComponentScan: Enables component scanning, allowing Spring to detect components, configurations, and services.
Here's an example:
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
main() Method:
The main method is the entry point of the Java application. It calls the SpringApplication.run() method, which launches the Spring Boot application.
SpringApplication.run():
Sets up the application context.
Loads all the necessary configurations.
Starts the embedded server (if it's a web application).
Initializes all Spring Beans.
Example:
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
SpringApplication Class:
The SpringApplication class is responsible for:
Bootstrapping the application.
Starting the Spring application context.
Starting the embedded server (e.g., Tomcat, Jetty, Undertow) if it's a web application.
Running lifecycle hooks such as listeners or initializers.
The run() method also returns an instance of ConfigurableApplicationContext, which can be used to interact with the Spring context.
Additional Details:
Auto-Configuration: Spring Boot auto-configures components based on the classpath and environment. For example, if you have spring-boot-starter-web in your project, Spring Boot will configure a web server (e.g., Tomcat) and the MVC framework automatically.
Embedded Web Server: If it’s a web application, the embedded server (Tomcat, Jetty, or Undertow) is started automatically, and the application is ready to serve HTTP requests.
Example Spring Boot Main Class:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
Summary:
The starting point of a Spring Boot application is the @SpringBootApplication-annotated class containing the main method.
The SpringApplication.run() method starts the Spring context and, if applicable, the embedded web server.
This simple structure allows for rapid application development with minimal configuration.
Q13. What is Singleton Design Pattern?
The Singleton Design Pattern ensures that a class has only one instance and provides a global point of access to that instance. In other words, no matter how many times a class is accessed or called, it will always return the same instance.
Key Features of Singleton Design Pattern:
Single Instance: Only one instance of the class exists in the application.
Global Access Point: The single instance is accessible globally throughout the application.
Controlled Instantiation: The class controls how and when the instance is created, often through lazy initialization or early instantiation (eager loading).
Example:
public class Singleton {
private static Singleton instance;
// Private constructor to restrict instantiation
private Singleton() {}
// Method to return the single instance (lazy initialization)
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
In Spring, the default scope of a bean is singleton, meaning Spring will create only one instance of the bean per Spring container, regardless of how many times it is injected or accessed.
Q14. Are Spring Beans Thread-Safe? How does Spring handle concurrency in Singleton beans?
No, Spring beans are not inherently thread-safe, especially when using the singleton scope (the default scope). Since the singleton scope ensures a single instance of a bean is shared across multiple threads, it can lead to concurrency issues if the bean maintains any mutable state. This is a concern for shared resources like variables, collections, or external services that the singleton instance might manipulate.
Why Spring Singleton Beans Are Not Thread-Safe:
Single Instance Across Threads: A singleton bean means only one instance of the bean exists and is shared by multiple threads. If two threads try to access or modify mutable data in that instance concurrently, race conditions or data inconsistencies can occur.
No Concurrency Management by Default: Spring does not provide built-in mechanisms to make beans thread-safe out of the box. Developers need to implement thread-safety mechanisms (e.g., synchronization or immutability) in their code.
When is Thread-Safety a Concern?
Thread-safety is only a concern if the bean has mutable state. Stateless beans, where each method invocation is independent and doesn’t alter any shared fields, are naturally thread-safe.
Example:
Thread-Safe: A service that processes data and returns a result without changing any internal state is thread-safe.
Not Thread-Safe: A service that writes to a shared resource or maintains an internal state (like a cache) that multiple threads can modify is not thread-safe.
How does Spring handle concurrency in Singleton beans
Since singleton beans are shared across multiple threads, Spring does not automatically manage concurrency for singleton beans. Instead, Spring provides tools and patterns that allow you to handle concurrency explicitly:
1. Immutability (Preferred Option):
A common strategy for dealing with concurrency in singleton beans is to design them to be stateless or immutable. Immutable objects are inherently thread-safe because their state cannot change after creation.
Example:
@Service
public class MyService {
public String processData(String input) {
return input.toUpperCase();
}
}
In this case, the processData method does not modify any shared state, so it's inherently thread-safe.
2. Synchronized Blocks/Methods:
You can manually handle concurrency by synchronizing methods or blocks of code that access shared mutable state. However, this can degrade performance due to thread contention.
Example:
@Service
public class MyService {
private List<String> sharedList = new ArrayList<>();
public synchronized void addData(String data) {
sharedList.add(data);
}
}
The addData method is synchronized to ensure that only one thread can modify sharedList at a time, preventing race conditions.
3. Thread-Local Variables:
Another approach is using ThreadLocal to maintain separate instances of variables for each thread, thus preventing shared mutable state.
Example:
private ThreadLocal<String> threadLocal = new ThreadLocal<>();
public void setValue(String value) {
threadLocal.set(value);
}
public String getValue() {
return threadLocal.get();
}
This ensures that each thread has its own independent copy of the data, preventing cross-thread interference.
4. Prototype Scope for Stateful Beans:
If you need a stateful bean where each thread needs its own instance, you can use the prototype scope. In this case, Spring will create a new instance of the bean every time it is requested.
Example:
@Scope("prototype")
@Component
public class StatefulService {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return this.state;
}
}
By using prototype scope, each thread or client will get a different instance of the StatefulService, which avoids thread-safety issues.
5. Concurrency Libraries:
For more complex scenarios, you can use Java’s built-in concurrency utilities, such as ConcurrentHashMap, AtomicInteger, ReentrantLock, or more advanced structures from java.util.concurrent. These utilities help ensure safe concurrent access to shared resources.
Example using ConcurrentHashMap:
@Service
public class ConcurrentService {
private ConcurrentMap<String, String> cache = new ConcurrentHashMap<>();
public String getData(String key) {
return cache.get(key);
}
public void putData(String key, String value) {
cache.put(key, value);
}
}
Q15. What is the Difference between @RequestMapping and @GetMapping? Can you provide examples of when to use each?
@RequestMapping: A generic annotation that can be used for mapping any HTTP method (GET, POST, PUT, DELETE, etc.) to a method.
@GetMapping: A specialized version of @RequestMapping specifically for HTTP GET requests.
Example:
@GetMapping("/users") // Equivalent to @RequestMapping(value = "/users", method = RequestMethod.GET)
Q16. Difference between @Controller and @RestController: How does the response type differ between the two?
@Controller: Used for returning views (typically HTML) in MVC web applications. It works with view templates like Thymeleaf, JSP, etc.
@RestController: Combines @Controller and @ResponseBody. It returns the data (like JSON or XML) directly as a response, suitable for RESTful web services.
Q17. What is Logging? What is springboots default logging framework?
Logging is used to save the information for monitoring and debugging
Spring Boot uses SLF4J (Simple Logging Facade for Java) along with Logback as the default logging framework.
Q18. What are Levels of Logging?
Logging Levels (in increasing order of severity):
TRACE: Provides very detailed information, mainly used for debugging purposes.
DEBUG: Provides detailed information about the flow of the application, used in development.
INFO: General information about the state of the application, typically used in production environments.
WARN: Indicates a potential issue that doesn’t stop the application.
ERROR: Indicates a serious issue that prevents part of the application from working.
FATAL
Q19. How do you configure logging in a Spring Boot application?
Configure logging
Configure logging in application.properties or application.yml:
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.file.name=logs/spring-boot-application.log
Logback Configuration: You can customize the logging behavior by using a logback-spring.xml file.
Example:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
Q20. What other Logging Tools are used for logging?
Tools like ELK Stack (Elasticsearch, Logstash, Kibana) are used to log Spring Boot applications. ELK Stack is a popular open-source log management toolchain used for aggregating, parsing, and visualizing logs.
Elasticsearch: Stores logs.
Logstash: Collects and processes logs.
Kibana: Visualizes the logs through dashboards.
Q21. What is @ComponentScan Annotation? What happens if you don’t specify a @ComponentScan?
Purpose: Used to specify base packages that Spring should scan for components like @Component, @Service, @Repository, etc.
If not specified, Spring automatically scans the package of the class annotated with @SpringBootApplication.
Q22. Build Tools (Maven, Gradle): How do Maven and Gradle differ in terms of dependency management?
Maven:
XML-based.
Uses pom.xml for dependency management.
Example:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Gradle:
Groovy or Kotlin-based DSL.
Faster and more flexible.
Example (Groovy):
implementation 'org.springframework.boot:spring-boot-starter-web'
Q23. Can we create Non-Web Applications in Spring Boot?
Yes. Spring Boot isn't limited to web applications. You can build standalone, non-web applications (e.g., command-line tools, batch processing applications).
Example: You can disable the web server and run a console-based application by excluding spring-boot-starter-web and using only core Spring features.
Configuration:
In application.properties:
spring.main.web-application-type=none
In your main class:
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
Q24. What is RestTemplate?
Definition: RestTemplate is a synchronous client to perform HTTP requests, returning data as a response. It is part of Spring's HTTP client library and can handle CRUD operations via RESTful web services.
Common Methods: GET, POST, PUT, DELETE.
Example of RestTemplate Usage:
@RestController
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/get-user")
public String getUser() {
String url = "https://api.example.com/users/1";
return restTemplate.getForObject(url, String.class);
}
}
Q25. What is Swagger?
Definition: Swagger is a framework used for documenting RESTful APIs. With Swagger, you can automatically generate API documentation and provide a user interface for interacting with the API.
Q26. How to Integrate Swagger with Spring Boot?
Swagger is a widely-used tool for generating interactive API documentation for RESTful web services. It allows you to visualize and test APIs directly from the browser. In a Spring Boot application, you can easily integrate Swagger using Springfox or Springdoc OpenAPI (recommended for recent Spring Boot versions).
Here's a step-by-step guide to integrating Swagger with Spring Boot using Springdoc OpenAPI, which supports the latest Spring Boot versions:
1. Add the Springdoc OpenAPI Dependency
First, you need to add the springdoc-openapi-ui dependency to your pom.xml (for Maven) or build.gradle (for Gradle).
Maven:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
Gradle:
implementation 'org.springdoc:springdoc-openapi-ui:1.7.0'
This dependency includes both OpenAPI and Swagger UI.
2. Annotate Your Controllers
Swagger automatically generates documentation for all endpoints in your Spring Boot application that are exposed via @RestController or @Controller. You don’t need to annotate your controller classes or methods specifically for Swagger unless you want to customize the documentation.
Here’s an example of a simple REST controller:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users")
public List<User> getAllUsers() {
// Logic to return a list of users
}
@PostMapping("/users")
public User createUser(@RequestBody User user) {
// Logic to create a new user
}
}
Swagger will automatically detect these endpoints and include them in the generated API documentation.
3. Access the Swagger UI
Once the application is running, you can access the Swagger UI at the following URL:
http://localhost:8080/swagger-ui.html
This interface provides a graphical representation of your API, allowing you to test each endpoint, view request/response schemas, and understand input parameters and response types.
4. Customizing Swagger Documentation
You can further customize the Swagger documentation by using annotations like @Operation, @ApiResponses, and @ApiResponse from the OpenAPI annotations.
For example:
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
@RestController
@RequestMapping("/api")
public class UserController {
@Operation(summary = "Get all users", description = "Fetch all users from the system")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved list of users"),
@ApiResponse(responseCode = "404", description = "Users not found")
})
@GetMapping("/users")
public List<User> getAllUsers() {
// Logic to return a list of users
}
}
5. Customizing API Info (Optional)
You can customize the API information (e.g., title, description, version) by adding a configuration class.
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.OpenAPI;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("My API")
.version("1.0")
.description("This is a sample Spring Boot API documentation"));
}
}
6. Additional Features of Springdoc OpenAPI:
API Grouping: You can group APIs by tags using the @Tag annotation to categorize your API endpoints.
Security Schemes: Springdoc supports OpenAPI security schemes (e.g., JWT, OAuth2) which can be configured for authentication in your API documentation.
API Versioning: You can configure different API versions and provide versioned documentation.
Key URLs After Integration:
Swagger UI: http://localhost:8080/swagger-ui.html – A visual interface to explore and interact with your APIs.
OpenAPI JSON: http://localhost:8080/v3/api-docs – This generates the OpenAPI 3.0 JSON documentation of your API.
Example Application with Swagger:
Here's a full example integrating Swagger with Spring Boot:
pom.xml Dependency:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
UserController.java:
import org.springframework.web.bind.annotation.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import java.util.List;
@RestController
@RequestMapping("/api")
public class UserController {
@Operation(summary = "Get all users", description = "Fetch all users from the system")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved list of users"),
@ApiResponse(responseCode = "404", description = "Users not found")
})
@GetMapping("/users")
public List<User> getAllUsers() {
// Logic to return a list of users
}
@PostMapping("/users")
public User createUser(@RequestBody User user) {
// Logic to create a new user
}
}
SwaggerConfig.java (Optional):
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info().title("User Management API").version("1.0").description("API for managing users"));
}
}
Conclusion:
Integrating Swagger with Spring Boot using Springdoc OpenAPI is simple and powerful. It automatically generates API documentation for your controllers and exposes a user-friendly UI for exploring and interacting with your API. This setup also supports customization through annotations, making it a valuable tool for API development and testing.
Q27. What are Spring Profiles? What is the purpose of spring.profiles.active?
Spring Profiles allow developers to segregate parts of the application configuration based on different environments (e.g., development, testing, production). They enable switching between different configurations (such as database settings, API credentials, or external service endpoints) without changing the source code, making the application more flexible and maintainable.
Profiles in Spring are essentially a way to organize and isolate beans and configurations so that they are only active in a specific environment.
Key Use Cases:
Environment-Specific Configurations: You may want different configurations for development, staging, and production environments. For example, use an embedded H2 database for development and a PostgreSQL or MySQL database for production.
Testing: Spring profiles can be used to mock or simulate services in the test environment.
Feature Toggling: Enable or disable certain features or functionality in the application by setting profiles.
How to Define and Use Profiles in Spring?
1. Defining Beans with Profiles:
You can annotate beans with @Profile to specify that they should only be created when a specific profile is active.
Example:
@Configuration
public class DataSourceConfig {
@Bean
@Profile("dev")
public DataSource devDataSource() {
// Configuration for development database (e.g., H2)
return new H2DataSource();
}
@Bean
@Profile("prod")
public DataSource prodDataSource() {
// Configuration for production database (e.g., PostgreSQL)
return new PostgreSQLDataSource();
}
}
In this example:
When the dev profile is active, Spring will create the devDataSource bean.
When the prod profile is active, Spring will create the prodDataSource bean.
2. Application Properties for Profiles:
You can create profile-specific properties files to configure environment-specific settings, such as application port, database URLs, or logging levels.
application-dev.properties: Used when the dev profile is active.
application-prod.properties: Used when the prod profile is active.
Example:
application-dev.properties
server.port=8081
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
application-prod.properties
server.port=8080
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=prod_user
spring.datasource.password=prod_password
What is spring.profiles.active?
The spring.profiles.active property is used to activate one or more profiles in Spring. This property tells Spring which profile(s) should be active during the application runtime.
You can set spring.profiles.active in multiple ways, such as:
In the application properties file:
spring.profiles.active=dev
This would activate the dev profile and apply the application-dev.properties configuration.
As a JVM System Property: You can pass the profile while starting the application:
java -jar myapp.jar --spring.profiles.active=prod
As an Environment Variable: Set an environment variable to activate the profile:
export SPRING_PROFILES_ACTIVE=prod
Programmatically: You can activate profiles in Java code.
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApplication.class);
app.setAdditionalProfiles("prod");
app.run(args);
}
Multiple Profiles:
You can activate multiple profiles by comma-separating them:
spring.profiles.active=dev,aws
In this case, both the dev and aws profiles will be active, and beans or configurations related to both profiles will be loaded.
Example Scenario:
Consider a scenario where you need different configurations for development, test, and production environments.
1. application-dev.properties:
server.port=8081
spring.datasource.url=jdbc:h2:mem:testdb
logging.level.root=DEBUG
2. application-prod.properties:
server.port=8080
spring.datasource.url=jdbc:postgresql://localhost:5432/prod_db
logging.level.root=INFO
3. Activate the Profile:
To run the application in production mode, you can set spring.profiles.active to prod:
spring.profiles.active=prod
This ensures that the production settings from application-prod.properties are applied.
Benefits of Using Spring Profiles:
Environment Flexibility: Easily switch between different configurations based on the environment.
Code Reusability: Use the same code base for different environments by isolating configuration differences.
Simplified Testing: Activate a test profile to run your tests with different configurations.
Feature Management: Profiles can be used to toggle features or services on or off depending on the active profile.
Security: Keep sensitive information (like credentials) environment-specific without hardcoding it into the code.
Conclusion:
Spring Profiles allow for environment-specific configurations, making it easier to handle different environments (development, testing, production).
The spring.profiles.active property enables you to specify which profile should be active at runtime.
This feature helps you to maintain clean and manageable configurations, eliminating the need for multiple branches or significant code changes when switching environments.
Q28. What is the Default Application Server of Spring Boot. Can we replace Apache Tomcat with some other App Server?
Default Server: Spring Boot comes with an embedded Tomcat server by default.
Replacing Tomcat:
You can replace it with other servers like Jetty or Undertow by excluding Tomcat from the classpath and including the desired server’s dependency.
Example (using Jetty):
In pom.xml, exclude Tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
Add the Jetty dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Q29. What are Cascade Types and Examples with Pros and Cons?
Cascade Types: Cascade types define how persistence operations (e.g., save, delete) should propagate from a parent entity to its associated child entities during certain operations like persist, merge, delete, etc..
Common Cascade Types:
PERSIST: Saves the child entity when the parent is saved.
MERGE: Merges changes to the child when the parent is merged.
REMOVE: Deletes the child when the parent is deleted.
DETACH: Detaches the child when the parent is detached.
ALL: Applies all of the above cascades.
Example:
import javax.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(cascade = CascadeType.PERSIST) // Persist operations will cascade
private List<Order> orders;
}
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderId;
// Other fields
}
Pros: Simplifies persistence operations by automatically propagating changes.
Cons: Can lead to unintended data manipulation (e.g., accidentally deleting child records).
Q30. How to handle Transactional Management in Spring Boot?
Definition: Spring Boot uses @Transactional to handle transaction management, ensuring that operations complete successfully or roll back in case of an exception in order to enforce atomicity.
Example:
@Transactional
public void saveUser(User user) {
userRepository.save(user);
// Any additional operations on the database
}
Spring supports declarative transaction management, where transactions are configured with annotations and XML.
Q31. Explain Transactional Propagation and Its Types with Examples:
Propagation: Defines how transactions should behave in relation to other transactions. Spring supports several types of transaction propagation:
REQUIRED: Joins the current transaction or creates a new one if none exists.
REQUIRES_NEW: Always creates a new transaction, suspending the existing one.
MANDATORY: Throws an exception if no existing transaction is found.
NESTED: Creates a nested transaction within the current one.
Example:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createUser(User user) {
userRepository.save(user);
}
@Transactional(propagation = Propagation.REQUIRED)
public void updateUser(User user) { ... }
Q32. Flow of API Requests in Spring:
Steps:
Client Request: A client sends an HTTP request (e.g., GET, POST) to a specific endpoint.
DispatcherServlet: The request is handled by the DispatcherServlet, which acts as the central controller.
Handler Mapping: The request is forwarded to the appropriate controller method based on the URL mapping.
Controller Processing: The controller processes the request and interacts with the service layer.
Service and Repository Layers: The service layer calls the repository to fetch or manipulate data from the database.
Response: The controller returns a response (e.g., JSON, HTML) to the client.
Q33. What are Fetch Types (EAGER and LAZY) and Their Use Cases?
Fetch types determine how related entities are fetched from the database: eagerly (immediately) or lazily (on demand).
EAGER Fetching: Data is loaded immediately when the parent entity is fetched.
Use Case:
Use EAGER when you need the related entities frequently.
Use when you always need the associated data.
Example:
import javax.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(fetch = FetchType.EAGER) // Will load User's Orders beforehand
private List<Order> orders;
}
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderId;
// Other fields
}
LAZY Fetching: Data is fetched only when it is explicitly accessed.
Use Case:
Use LAZY when the related entities are needed only occasionally to optimize performance.
Use for performance optimization when associated data is large or rarely accessed.
Example:
import javax.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(fetch = FetchType.LAZY) // Will load User's Orders on demand
private List<Order> orders;
}
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderId;
// Other fields
}
Q34. Explain @Autowired:
Purpose: @Autowired is used for automatic dependency injection by Spring. Spring resolves the dependency by injecting the appropriate bean from the context.
Usage: It can be applied to constructors, setters, or fields.
Q35. What is Global Exception Handling? Explain @ExceptionHandler and @ControllerAdvice:
Global Exception Handling in Spring is managed by @ControllerAdvice and @ExceptionHandler. You can define a class with @ControllerAdvice and use @ExceptionHandler to handle exceptions globally
@ExceptionHandler: Used to handle exceptions thrown by controller methods.
@ControllerAdvice:
Used to define global exception handling logic for all controllers.
It allows you to centralize error handling logic rather than duplicating it in individual controllers.
Example:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException ex) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), "Resource Not Found");
return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleGlobalException(Exception ex) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), "Internal Server Error");
return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
You can define a custom exception like ResourceNotFoundException to handle scenarios where a resource is not found:
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
Q36. What are REST API Properties and HTTP Verbs? What is the difference between PUT and PATCH Mapping:
REST APIs are stateless, cacheable, and scalable, following the HTTP request/response model.
HTTP Verbs:
GET: Retrieves data.
POST: Creates a new resource.
PUT: Updates or replaces a resource.
PATCH: Partially updates a resource.
DELETE: Deletes a resource.
PUT is used to update a resource completely. It replaces the entire resource with the provided data. Whereas PATCH is used to partially update a resource. Only the provided fields are updated.
Q37. Explain SOLID Design Principles:
S.O.L.I.D is an acronym for five design principles that improve software's modularity, readability, and flexibility:
Single Responsibility Principle (SRP): A class should have only one reason to change, meaning it should have only one responsibility.
Open/Closed Principle (OCP): Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.
Liskov Substitution Principle (LSP): Objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program.
Interface Segregation Principle (ISP): A client should not be forced to depend on interfaces it does not use. Prefer smaller, specific interfaces.
Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules; both should depend on abstractions.
Q38. Explain following Design Patterns - Singleton, Factory, Decorator, Strategy, Observable, Adapter, Flyweight, Command, Chain of Responsibility:
Singleton: Ensures a class has only one instance.
Factory: Creates objects without exposing the instantiation logic.
Decorator: Adds new functionality to an object without altering its structure.
Strategy: Defines a family of algorithms and makes them interchangeable at runtime.
Observable: A pattern where an object (subject) notifies other objects (observers) of state changes.
Adapter: Allows incompatible interfaces to work together.
Flyweight: Reduces memory usage by sharing as much data as possible with similar objects.
Command: Encapsulates requests as objects, allowing parameterization of clients.
Chain of Responsibility: Passes a request along a chain of handlers, and each handler processes or passes the request further.
Q39. Multithreading with Singleton Bean:
Problem: Spring Beans are by default singleton, which may lead to issues in multithreaded environments because multiple threads might access and modify the bean concurrently.
Solution: To make Singleton beans thread-safe:
Use stateless beans.
Use synchronization or thread-local storage.
Ensure that shared resources are properly synchronized.
Q40. Explain Immutability:
Immutability: An immutable object is one whose state cannot be modified after it has been created. It ensures thread safety because immutable objects can be safely shared between threads.
Example in Java:
public final class ImmutableUser {
private final String name;
public ImmutableUser(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Q41. Explain Streaming?
Streaming: Refers to real-time data flow processing. Spring supports streaming using:
Spring Cloud Stream: Built on top of messaging platforms like Kafka or RabbitMQ, it enables event-driven microservices.
Q42. Explain Messaging:
Messaging: Refers to passing messages asynchronously between systems. Spring provides:
JMS (Java Message Service): Used for messaging between distributed systems.
Kafka/RabbitMQ: Supported via Spring's messaging abstraction layer.
Q43. Caching:
Definition: Caching stores the results of expensive operations (e.g., database queries) so that future requests can be served faster.
Spring Caching Abstraction:
Annotations like @Cacheable, @CacheEvict, and @CachePut are used to manage caching.
Example:
@Cacheable("users")
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
Q44. Explain Security - SSL, JWT, OAuth:
SSL (Secure Sockets Layer):
Provides secure communication by encrypting data between the client and server. In Spring Boot, SSL can be enabled by configuring the application.properties:
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=password
JWT (JSON Web Token):
A compact and self-contained way of securely transmitting information between parties as a JSON object.
JWT is widely used in RESTful services to authenticate users.
Example with Spring Security:
Users are authenticated and provided with a JWT, which is sent with each request.
OAuth (Open Authorization):
OAuth2 is a protocol for delegated authorization. Spring Boot integrates OAuth2 to allow third-party services (like Google or GitHub) to access your application securely.
Q45. How to Create a Customized Starter in Spring Boot:
Definition: A Spring Boot starter is a specialized Maven/Gradle dependency that simplifies adding new functionality (e.g., spring-boot-starter-web).
Steps to Create a Custom Starter:
Create a new Maven project.
Add spring-boot-autoconfigure as a dependency.
Implement an AutoConfiguration class using @Configuration.
Package it as a JAR and include it in the pom.xml of another project.
Q46. What are Spring Boot Peer Technologies?
Spring Cloud: A framework for building resilient, distributed systems using microservices architecture (supports service discovery, configuration management, circuit breakers).
Spring WebFlux: A reactive programming framework that supports non-blocking, asynchronous operations.
Spring Batch: Provides batch processing capabilities for large-scale processing tasks (e.g., reading and writing large datasets).
Q47. How to implement Paging and Sorting with Pageable and Sort?
Paging refers to dividing large datasets into smaller chunks (pages) to retrieve them efficiently. Sorting refers to arranging data in ascending or descending order. Pagination and Sorting are critical for efficiently handling large datasets in REST APIs. Spring Data JPA provides the Pageable and Sort interfaces to handle pagination and sorting.
Using Pageable: Pageable is used to specify the page size, the current page number, and the sorting order(optional).
@GetMapping("/users")
public Page<User> getUsers() {
Pageable pageable = PageRequest.of(0, 10); // Page 0 with 10 items per page
return userRepository.findAll(pageable);
}
Using Sort: You can specify sorting criteria using the Sort class.
@GetMapping("/users")
public List<User> getUsers(Sort sort) {
return userRepository.findAll(sort);
}
Pagination and sorting can be combined with Pageable to fetch sorted data in pages.
Pageable pageable = PageRequest.of(0, 10, Sort.by("lastName").ascending());
Page<User> users = userRepository.findAll(pageable);
Q48. What is @Entity Annotation
@Entity marks a class as a JPA entity, which maps it to a table in the database. The @Entity annotation must be used along with a @Id to denote the primary key of the entity.
Example
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Other fields and getters/setters
}
Q49. What is a Spring Configuration Class
A configuration class is annotated with @Configuration and is used to define beans and other Spring configurations.
Example
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
}
Q50. What is Datasource Bean
A DataSource bean defines the database connection properties and is used to establish a connection with the database.
Example
You can define a DataSource bean in your configuration class:
@Bean
public DataSource dataSource() {
DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url("jdbc:mysql://localhost:3306/mydb");
dataSourceBuilder.username("root");
dataSourceBuilder.password("password");
return dataSourceBuilder.build();
}
Q51. What is @Query Annotation
The @Query annotation allows you to write custom JPQL or native SQL queries within your repository methods.
Example
@Query("SELECT u FROM User u WHERE u.email = ?1")
User findByEmail(String email);
You can also use native queries:
@Query(value = "SELECT * FROM users WHERE email = ?1", nativeQuery = true)
User findByEmailNative(String email);
Q52. What is Eureka Server
Eureka is a service registry used in microservices architecture. It allows services to register themselves and discover other services.
Configuring Eureka
Add the following dependency to your pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
Enable Eureka Server
Annotate your main application class with @EnableEurekaServer:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication { ... }
Q53. What is Docker? What are the Benefits of Docker
Docker is used for containerizing applications, making them portable and easy to deploy across environments.
Docker is a platform that allows you to package an application and its dependencies into a standardized unit called a container. Containers are lightweight and isolated from each other, making them ideal for deploying applications in different environments without compatibility issues.
Benefits of Docker:
Portability: Containers can run consistently across multiple environments (development, testing, production).
Isolation: Each container runs in its own environment, isolated from others.
Scalability: Containers can be scaled up or down based on demand.
Q54. What are the steps of Dockerizing a Spring Boot Application
Steps to Dockerize a Spring Boot application:
Create a Dockerfile: This file contains instructions on how to build a Docker image for the Spring Boot app.
Example Dockerfile:
FROM openjdk:17-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Build the Docker image:
Run the following command in the directory containing the Dockerfile:
docker build -t my-spring-boot-app .
Run the Docker container:
To run the app inside a Docker container:
docker run -p 8080:8080 my-spring-boot-app
Q55. What is Docker Compose
Docker Compose is used to define and run multi-container Docker applications (e.g., running your Spring Boot app along with a database).
Example docker-compose.yml for running a Spring Boot app with a MySQL database:
version: '3'
services:
app:
image: my-spring-boot-app
ports:
- "8080:8080"
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
Run both services using: docker-compose up
Q56. What is Kubernetes
Kubernetes is used for orchestrating and managing containers in a clustered environment.
Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. It’s commonly used to manage Docker containers in a distributed environment.
Kubernetes Components:
Pods: The smallest deployable units in Kubernetes, which contain one or more containers.
Services: Expose your application to external traffic.
Deployments: Automate the creation, scaling, and management of application Pods.
Q57. What are the steps of Deploying Spring Boot on Kubernetes
Steps to Deploy a Spring Boot App:
Create a Kubernetes Deployment YAML file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-deployment
spec:
replicas: 3
selector:
matchLabels:
app: spring-boot
template:
metadata:
labels:
app: spring-boot
spec:
containers:
- name: spring-boot-container
image: my-spring-boot-app
ports:
- containerPort: 8080
Create a Kubernetes Service YAML file:
apiVersion: v1
kind: Service
metadata:
name: spring-boot-service
spec:
selector:
app: spring-boot
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: LoadBalancer
Deploy on Kubernetes:
Apply the deployment and service files:
kubectl apply -f deployment.yml
kubectl apply -f service.yml
Q58. How can we Scale Spring Boot application in Kubernetes
Kubernetes automatically scales your Spring Boot application based on demand. For instance, you can scale your app by increasing the number of replicas:
kubectl scale deployment spring-boot-deployment --replicas=5
Q59. What is the purpose of Health Monitoring?
Purpose: Health monitoring ensures the continuous availability and performance of a Spring Boot application by tracking key metrics.
Health Checks: Spring Boot Actuator provides health indicators that show the status of databases, caches, and other components.
Alerts: Monitoring tools like Prometheus can be integrated with alerting systems to notify teams about application issues in real-time.
Q60. What are some Monitoring Tools
Monitoring Tools:
Prometheus: Monitors and collects metrics from Kubernetes clusters.
Grafana: Visualizes these metrics on customizable dashboards.
Kubernetes Dashboard: A web-based UI for monitoring and managing Kubernetes clusters.
Q61. What is Spring Boot Actuator?
Actuator provides production-ready features in Spring Boot applications, such as monitoring and managing applications through HTTP endpoints.
Provides built-in health checks for databases, caches, messaging systems, and custom health indicators.
Integration with Monitoring Tools: Actuator can be integrated with monitoring tools like Prometheus, Grafana and Kubernetes Dashboard for visualization of metrics.
Common Actuator Endpoints:
/health: Provides health status of the application.
/metrics: Shows application metrics (e.g., memory usage, active threads).
/info: Displays arbitrary application information.
/httptrace: Shows HTTP request-response traces.
You can enable Actuator by adding it to your pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Q62. How will you integrate Prometheus and Grafana in your SpringBoot Application
Prometheus collects metrics from your Spring Boot application, and Grafana visualizes them.
Steps:
Add the Micrometer dependency in your pom.xml:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
Expose metrics at /actuator/prometheus and configure Prometheus to scrape these metrics.
Visualize the metrics using Grafana.
Q63. Docker + Kubernetes Integration with CI/CD
CI/CD Pipeline with Docker and Kubernetes:
Integrating Docker and Kubernetes with a Continuous Integration/Continuous Deployment (CI/CD) pipeline automates the build, testing, and deployment processes.
Jenkins, GitLab CI, or CircleCI can be used to automate:
Building the Docker image of a Spring Boot application.
Pushing the image to a Docker registry (like DockerHub).
Deploying the image to a Kubernetes cluster.
Example CI/CD pipeline with Jenkins:
Jenkins builds the Docker image and pushes it to DockerHub.
Jenkins triggers a Kubernetes deployment that pulls the latest Docker image and deploys it to the cluster.
Q64. What is MappedSuperClass? Explain with code
MappedSuperclass is a class that provides common mappings to its subclasses. It’s not an entity itself but allows shared fields in subclasses.
Example Code:
import javax.persistence.*;
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String createdAt;
private String updatedAt;
// Getters and Setters
}
@Entity
public class User extends BaseEntity {
private String username;
}
@Entity
public class Product extends BaseEntity {
private String productName;
}
Q65. What is @RestController and @RequestMapping? Explain with code
@RestController is a specialized version of the @Controller annotation that combines @ResponseBody and @Controller, making it suitable for RESTful web services.
@RequestMapping is used to map HTTP requests to handler methods in your controller.
Example Code:
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/products")
public class ProductController {
@GetMapping
public List<Product> getAllProducts() {
// Logic to fetch products
return productService.fetchProducts();
}
@PostMapping
public Product createProduct(@RequestBody Product product) {
// Logic to create a new product
return productService.saveProduct(product);
}
}
Q66. Fetch a list of products from a third-party API using RestTemplate. Once the products are retrieved, you need to store them in your local database.
Here’s a complete structure to fetch products and store them in a local database using Spring Boot:
Project Structure:
src
└── main
├── java
│ └── com
│ └── example
│ ├── ProductApplication.java
│ ├── controller
│ │ └── ProductController.java
│ ├── entity
│ │ └── Product.java
│ ├── repository
│ │ └── ProductRepository.java
│ └── service
│ └── ProductService.java
└── resources
└── application.properties
1. ProductApplication.java:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
2. Product.java (Entity):
import javax.persistence.*;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
// Getters and Setters
}
3. ProductRepository.java (Repository):
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProductRepository extends JpaRepository<Product, Long> {
}
4. ProductService.java (Service):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Service
public class ProductService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private ProductRepository productRepository;
public void fetchAndStoreProducts() {
String url = "https://api.example.com/products"; // Replace with actual API URL
Product[] products = restTemplate.getForObject(url, Product[].class);
if (products != null) {
for (Product product : products) {
productRepository.save(product);
}
}
}
}
5. ProductController.java (Controller):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping("/fetch")
public void fetchProducts() {
productService.fetchAndStoreProducts();
}
}
6. application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/your_database
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=update
7. RestTemplate Configuration:
You need to configure RestTemplate as a bean:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Summary
This complete structure includes fetching a list of products from a third-party API using RestTemplate and saving them into a local database using Spring Boot. Make sure to replace the API URL and database configuration with actual values.