0% found this document useful (0 votes)
255 views60 pages

Spring Boot Interview Questions

The document provides an overview of Spring Boot and Spring MVC, highlighting its advantages such as simplified deployment, embedded servers, and opinionated starter POMs. It details the steps to create a Spring Boot application using Maven, including project setup, configuration, and running the application. Additionally, it covers cross-questions that may arise during interviews related to Spring Boot functionalities and deployment options.

Uploaded by

gayathri Jayalal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
255 views60 pages

Spring Boot Interview Questions

The document provides an overview of Spring Boot and Spring MVC, highlighting its advantages such as simplified deployment, embedded servers, and opinionated starter POMs. It details the steps to create a Spring Boot application using Maven, including project setup, configuration, and running the application. Additionally, it covers cross-questions that may arise during interviews related to Spring Boot functionalities and deployment options.

Uploaded by

gayathri Jayalal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 60

SPRING BOOT/SPRING MVC INTERVIEW QUESTIONS

 Spring Boot is a Spring module which provides RAD (Rapid Application Development) feature
to Spring framework.
 It is used to create standalone spring based application that you can just run because it
needs very little spring configuration.
 In Spring Boot, annotations are used to simplify configuration without extensive XML
configuration.

2) What are the advantages of Spring Boot?

o Create stand-alone Spring applications that can be started using java -jar.
o Embed Tomcat, Jetty or Undertow directly. You don't need to deploy WAR files.
o It provides opinionated 'starter' POMs to simplify your Maven configuration.
o It automatically configure Spring whenever possible.
Notes:
1. Embedded Servers:
o Traditionally, in a Java EE application, you'd deploy a WAR file to a separate web
server (like Tomcat or Jetty). The web server runs independently, and the WAR file
is deployed to it.
o In Spring Boot, the server is embedded directly into the application. This means
that when you run the application, it automatically starts an embedded server
(e.g., Tomcat, Jetty, or Undertow) to serve the application. You don't need a
separate server running or deployment step.
2. No Need for WAR Deployment:
o In a traditional Spring MVC application, you would build your project as a WAR
file and deploy it to an external web server. With Spring Boot, you can package
the application as a JAR file and it will run with its own embedded web server,
without the need for a WAR file or an external web container.
o This simplifies deployment since you don't need to configure the server
separately.
Benefits:
1. Simplified Deployment: No need to worry about managing separate application servers
or deploying to them. You just run your application with java -jar and it handles
everything.
2. Standalone Applications: With an embedded server, your Spring Boot application is
completely self-contained and can be executed directly as a standalone application.
3. Ease of Use: Spring Boot makes it simple to configure and customize the embedded
server using properties in the application.properties or application.yml.

Example: Spring Boot Application with Embedded Tomcat


When you create a Spring Boot application, by default, it uses Tomcat as the embedded web
server. Here’s an example of how it works:
1. Spring Boot Application (Main class):
@SpringBootApplication
public class MySpringBootApp {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApp.class, args);
}
}
In this example, when you run java -jar MySpringBootApp.jar, Tomcat is automatically started
within the application to handle HTTP requests.
2. Configuration (Optional): You can configure the embedded server in application.properties or
application.yml.
For example, to change the port number:
server.port=8081
This will make your application run on port 8081 instead of the default 8080.

Cross Questions:
1. What if we want to use Jetty or Undertow instead of Tomcat?
o Answer: "Spring Boot allows you to easily switch between different embedded
servers by adding the corresponding dependency. For example, to use Jetty, you
can add spring-boot-starter-jetty instead of spring-boot-starter-tomcat in your
pom.xml."
2. Can we still deploy a Spring Boot app as a WAR file if needed?
o Answer: "Yes, Spring Boot supports both JAR (with embedded server) and WAR
deployment. If you need to deploy it to an external server, you can package it as a
WAR file and deploy it like a traditional Spring application."
3. What is the difference between using a JAR with an embedded server vs. a WAR file?
o Answer: "A JAR file with an embedded server is self-contained and can be
executed directly, while a WAR file needs to be deployed to an external server like
Tomcat or Jetty. The embedded approach is easier for microservices and cloud-
native applications because it avoids the need for external server setup."

Opinionated 'starter' POMs:


In Spring Boot, "opinionated 'starter' POMs" refers to pre-configured Maven POM (Project
Object Model) files that simplify your project setup. These "starters" are essentially predefined
Maven dependencies that help you get started quickly with commonly used features in Spring
Boot applications, without having to manually configure every dependency.
Example of Spring Boot Starter POMs:
1. spring-boot-starter-web:
o This starter is used for creating web applications, including RESTful applications.
o It brings in Spring MVC, Jackson (for JSON binding), and the Tomcat embedded
container.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
By adding this one starter dependency, you don't need to manually configure Spring MVC,
Jackson, or the web server. These dependencies will be included automatically.
2. spring-boot-starter-data-jpa:
o This starter includes everything you need to use Spring Data JPA with Hibernate.
o It automatically configures your application to work with databases using JPA.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
3. spring-boot-starter-thymeleaf:
o This starter is used for Thymeleaf templates (a server-side Java template engine
for web applications).
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

 What is an "opinionated 'starter' POM" in Spring Boot?


o "In Spring Boot, an opinionated 'starter' POM refers to a pre-configured set of
Maven dependencies that simplify your project setup. These starters are
designed to include all the necessary libraries for specific features, like web
development or JPA, without requiring the developer to manually specify each
dependency. For example, spring-boot-starter-web will automatically configure
all dependencies required for a web application, including Spring MVC, Jackson,
and Tomcat, making the setup process very easy."
 Why is it useful?
o "It saves a lot of time by eliminating the need to manually add dependencies for
features you commonly use. Spring Boot's starters are designed to provide a
quick way to get your application up and running with minimal configuration."

Cross-Questions in Interviews:
1. Can you customize the dependencies in a Spring Boot starter?
o Answer: "Yes, although Spring Boot provides opinionated defaults, you can
always exclude or override the default dependencies in a starter if you need
more control. For example, if you want to use a different version of a library or
a different implementation, you can customize it in your pom.xml file."
2. What would happen if you didn't use a starter POM?
o Answer: "If you don’t use a starter POM, you would need to manually configure
each dependency for the libraries you need in your application. This could make
the configuration much more complex and error-prone, especially as the project
grows."
3. Is it possible to use more than one starter in a Spring Boot application?
o Answer: "Yes, you can include multiple starters in a Spring Boot application. For
example, you might use spring-boot-starter-web for web development and
spring-boot-starter-data-jpa for data persistence. You can combine them to
achieve the desired functionality."
4. What is the difference between spring-boot-starter-web and spring-boot-starter-
webflux?
o Answer: "spring-boot-starter-web is used for building traditional servlet-based
web applications using Spring MVC, whereas spring-boot-starter-webflux is used
for reactive programming with Spring WebFlux, which supports non-blocking,
event-driven applications."

4) How to create Spring Boot application using Maven?


There are multiple approaches to create Spring Boot project. We can use any of the following
approach to create application.
o Spring Maven Project
o Spring Starter Project Wizard
o Spring Initializr
o Spring Boot CLI

How to create a Spring Boot project from scratch?


Step-by-Step Explanation:
1. Set up the Project:
o Use the Spring Initializer, a web-based tool provided by Spring to bootstrap a
project.
o Steps:
1. Go to start.spring.io.
2. Select:
 Project Type: Maven (default) or Gradle.
 Spring Boot Version: Choose the version suitable for your
application (usually the latest stable version).
 Dependencies: Add starters based on your needs, such as:
 Spring Web for web applications.
 Spring Data JPA for database operations.
 Spring Boot DevTools for development convenience.
3. Download the project as a zip file and extract it.
Alternative: Use an IDE like IntelliJ IDEA or Eclipse, which supports Spring Boot project creation
via their Spring Boot plugin.

2. Import the Project into Your IDE:


o Open your IDE (e.g., IntelliJ, Eclipse, or VS Code).
o Import the project as a Maven or Gradle project.
o Wait for the IDE to download dependencies based on the pom.xml or
build.gradle.

3. Configure the Application:


o Set Up application.properties or application.yml: Add properties for
configuration, like:
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=pass123
spring.jpa.hibernate.ddl-auto=update

4. Write the Code:


o Create a Main Class: The main class is automatically generated by the Spring
Initializer. It contains the @SpringBootApplication annotation.
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
o Create Controller Layer: Example of a simple REST controller:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, Spring Boot!";
}
}
o Create the Repository and Service Layers (if needed): For a database, define an
entity, repository, and service.

5. Run the Application:


o Use your IDE or run the application from the command line:
mvn spring-boot:run
o Verify it runs by accessing the endpoint in a browser or using tools like Postman.

6. Test the Application:


o Use tools like Postman or curl to test your endpoints.
o Write unit tests using JUnit and Spring Boot’s testing support.
Interview Follow-up and Cross Questions:
1. Can you switch to Gradle instead of Maven?
o Answer: "Yes, the Spring Initializer allows you to choose Gradle as the build tool
instead of Maven. The build process and dependency management will use
Gradle instead, but the rest of the project setup remains the same."
2. What if I want to deploy the application as a WAR file?
o Answer: "To deploy a WAR file, I would modify the pom.xml to include the spring-
boot-starter-tomcat as provided scope and extend the main class with
SpringBootServletInitializer. This prepares the application for deployment to an
external server."
3. How do you secure your Spring Boot application?
o Answer: "I would use spring-boot-starter-security for basic authentication and
authorization. For more advanced security, I would integrate OAuth2 or JWT-
based security."
4. What is the purpose of the @SpringBootApplication annotation?
o Answer: "The @SpringBootApplication annotation is a combination of
@Configuration, @EnableAutoConfiguration, and @ComponentScan. It simplifies
configuration by enabling auto-configuration and scanning for Spring
components."
5. How do you manage different environments like dev, test, and prod?
o Answer: "Spring Boot supports profiles. I would use application-dev.properties,
application-test.properties, and application-prod.properties to specify
environment-specific configurations and activate them using
spring.profiles.active."

Steps to Convert a Spring Boot Application to a WAR File:


1. Modify pom.xml:
o Update your pom.xml to change the packaging type to war and include the
spring-boot-starter-tomcat dependency with provided scope.

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-boot-war-example</artifactId>
<version>1.0</version>
<packaging>war</packaging> <!-- Change packaging type to WAR -->

<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Tomcat dependency with provided scope -->


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope> <!-- Mark it as provided -->
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

2. Extend the Main Class:


o Extend your main application class from SpringBootServletInitializer and override
the configure() method. This ensures the application is deployable as a WAR.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class SpringBootWarExampleApplication extends SpringBootServletInitializer {

public static void main(String[] args) {


SpringApplication.run(SpringBootWarExampleApplication.class, args);
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringBootWarExampleApplication.class);
}
}

3. Build the WAR File:


o Use Maven to package the application into a WAR file:
mvn clean package
o This will generate a WAR file in the target directory (e.g., target/spring-boot-war-
example-1.0.war).

4. Deploy the WAR File to an External Server:


o Copy the generated WAR file to the deployment directory of your servlet
container (e.g., the webapps folder in Tomcat).
o Start the servlet container, and your Spring Boot application will be deployed.

Explanation of Changes:
1. packaging set to war:
o Tells Maven to generate a WAR file instead of the default JAR file.
2. spring-boot-starter-tomcat with provided scope:
o Ensures that the embedded Tomcat is not included in the WAR file since the
external servlet container will provide it.
3. Extending SpringBootServletInitializer:
o Configures the Spring Boot application to work as a traditional WAR that can be
deployed to an external servlet container.

Example Output:
 Access URL: Once deployed, you can access the application at:
http://localhost:8080/spring-boot-war-example

Spring Maven Project setup: https://www.javatpoint.com/spring-maven-project


https://www.javatpoint.com/spring-boot-application
Spring Initializer description: https://www.javatpoint.com/spring-initializr
Spring Boot Annotations:
In Spring Boot, annotations are used to simplify configuration, define application behavior, and
enable functionalities without extensive XML configuration.

1. Core Annotations
@SpringBootApplication
 Purpose: Main annotation to bootstrap a Spring Boot application.
 Explanation: Combines three annotations:
o @Configuration: Marks the class as a source of bean definitions.
o @EnableAutoConfiguration: Enables Spring Boot’s auto-configuration
mechanism.
o @ComponentScan: Scans the specified package for Spring components.
Example:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}

2. Bean Management Annotations


@Component
 Purpose: Marks a class as a Spring-managed component.
 Use Case: General-purpose Spring component.
@Service
 Purpose: Indicates a service layer class.
 Use Case: Used in the business logic layer.
@Repository
 Purpose: Indicates a DAO (Data Access Object) class.
 Use Case: For database operations.
@Controller
 Purpose: Marks a class as a Spring MVC controller.
 Use Case: Handles HTTP requests.
Example:
@Component
class MyComponent {}

@Service
class MyService {}

@Repository
class MyRepository {}

@Controller
class MyController {}

3. Dependency Injection Annotations


@Autowired
 Purpose: Automatically injects dependencies by type.
 Use Case: Eliminates manual instantiation.
Example:
@Service
class MyService {
private final MyRepository repository;
@Autowired
public MyService(MyRepository repository) {
this.repository = repository;
}
}
@Qualifier
 Purpose: Resolves ambiguity when multiple beans of the same type exist.
Example:
@Autowired
@Qualifier("specificBean")
private MyComponent myComponent;
@Value
 Purpose: Injects values from properties or environment variables.
Example:
@Value("${app.name}")
private String appName;

4. Spring Boot Web Annotations


@RestController
 Purpose: Combines @Controller and @ResponseBody. Used for REST APIs.
Example:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/greet")
public String greet() {
return "Hello, World!";
}
}
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping
 Purpose: Shortcuts for HTTP method-specific mappings.
Example:
@GetMapping("/user/{id}")
public User getUser(@PathVariable int id) {
return userService.findById(id);
}
@RequestParam and @PathVariable
 Purpose: Handle query parameters and path variables.
Example:
@GetMapping("/search")
public String search(@RequestParam String keyword) {
return "Search keyword: " + keyword;
}

@GetMapping("/user/{id}")
public String getUser(@PathVariable int id) {
return "User ID: " + id;
}

5. Configuration Annotations
@Configuration
 Purpose: Marks a class as a source of bean definitions.
@Bean
 Purpose: Declares a Spring-managed bean.
Example:
@Configuration
class MyConfig {
@Bean
public MyService myService() {
return new MyService();
}
}

6. Transaction Management
@Transactional
 Purpose: Declares transactional boundaries.
Example:
@Service
@Transactional
public class UserService {
public void saveUser(User user) {
userRepository.save(user);
}
}

7. Testing Annotations
@SpringBootTest
 Purpose: Used for integration tests.
@MockBean
 Purpose: Creates a mock of a bean for testing.
Example:
@SpringBootTest
public class MyServiceTest {
@MockBean
private MyRepository repository;

@Autowired
private MyService service;
}

How to Answer in an Interview


1. Explain the Purpose: Clearly define what the annotation does and why it's useful.
o Example: "@SpringBootApplication is the entry point of any Spring Boot
application. It simplifies configuration by combining @Configuration,
@EnableAutoConfiguration, and @ComponentScan."
2. Provide Practical Use Cases:
o Example: "@RestController is commonly used for building REST APIs. For
instance, to expose a GET endpoint, we use @GetMapping inside the controller."
3. Highlight Benefits:
o Example: "@Transactional ensures that all operations within a method are
atomic. If one operation fails, the transaction is rolled back."
4. Connect to Real-World Scenarios:
o Example: "In my current project, we used @Qualifier to differentiate between
two beans of the same type, ensuring the right one was injected."

Cross Questions
1. What’s the difference between @Component, @Service, and @Repository?
o Answer: Functionally similar, but they are semantically categorized for readability
and use case differentiation.
2. How does @SpringBootApplication differ from @EnableAutoConfiguration?
o Answer: @SpringBootApplication includes @EnableAutoConfiguration but also
enables component scanning and Java-based configuration.
3. Can @RestController be replaced with @Controller?
o Answer: Yes, but you’ll need to use @ResponseBody on each method.
4. How does @Transactional work under the hood?
o Answer: It uses proxies to manage transactions at the method level. On method
entry, a transaction begins, and it commits or rolls back depending on the
outcome.

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


In Spring Boot, both @Controller and @RestController are used to define controllers that handle HTTP
requests.

1. @Controller

 Purpose: Used to define a controller in a Spring MVC application that returns views (e.g., JSP,
Thymeleaf) or responses based on view resolvers.

 Behavior:

o Methods in a @Controller class typically return view names that map to a template
(e.g., return "home" for home.html).

o If a method needs to return a JSON or XML response, you must annotate it with
@ResponseBody to indicate that the return value is the response body, not a view name.

 Example:

@Controller

public class MyController {

@GetMapping("/welcome")

public String welcomePage() {

return "welcome"; // Maps to welcome.html or welcome.jsp

@GetMapping("/api/data")
@ResponseBody

public String getData() {

return "Hello, World!"; // Returns as a response body

2. @RestController

 Purpose: A specialized version of @Controller used to create RESTful web services that return
data (like JSON or XML) directly in the HTTP response body.

 Behavior:

o Combines @Controller and @ResponseBody into one annotation.

o Methods in a @RestController return data directly, without the need to annotate each
method with @ResponseBody.

 Example:

@RestController

public class MyRestController {

@GetMapping("/api/data")

public String getData() {

return "Hello, World!"; // Returns JSON or plain text response

Key Differences

Feature @Controller @RestController

For rendering views (HTML, JSP, For building REST APIs (JSON/XML
Primary Use
Thymeleaf). responses).

Returns view names (mapped to Directly returns data as the HTTP


Response Behavior
templates). response.

Requires
Yes, for returning response data. No, it's built-in.
@ResponseBody
When to Use @ResponseBody Instead of @RestController
1. If your class primarily serves views but has a few endpoints that return JSON or XML, use
@ResponseBody for those specific methods.
2. If your class is focused on building REST APIs, use @RestController to avoid adding
@ResponseBody to every method.
3. @GetMapping, @PostMapping, @PutMapping, @DeleteMapping
 Purpose: Shortcut annotations for HTTP methods like GET, POST, PUT, DELETE.
 Use Case: To define specific endpoints for different HTTP operations.
 Example:

@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users")
public List<User> getUsers() {
return userService.findAll();
}

@PostMapping("/users")
public User createUser(@RequestBody User user) {
return userService.save(user);
}
}
 Cross Questions:
o Can @RequestMapping replace these annotations?
o How to handle different HTTP methods on the same endpoint?
4. @RequestMapping
 Purpose: General mapping annotation for defining routes. Can handle multiple HTTP
methods.
 Use Case: When you need flexible mappings with multiple HTTP methods or complex
URLs.
 Example:
@RestController
@RequestMapping("/api")
public class ProductController {
@RequestMapping(value = "/products", method = RequestMethod.GET)
public List<Product> getProducts() {
return productService.findAll();
}
}
In a traditional Spring MVC application (prior to the introduction of the shortcut annotations
like @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping), you would use the
@RequestMapping annotation and explicitly specify the HTTP method using the method
attribute.
Here's how it was done:

Traditional Spring MVC (@RequestMapping)


package com.example.demo.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyController {

@RequestMapping(value = "/getExample", method = RequestMethod.GET)


@ResponseBody
public String getExample() {
return "GET request received";
}

@RequestMapping(value = "/postExample", method = RequestMethod.POST)


@ResponseBody
public String postExample() {
return "POST request received";
}

@RequestMapping(value = "/putExample", method = RequestMethod.PUT)


@ResponseBody
public String putExample() {
return "PUT request received";
}

@RequestMapping(value = "/deleteExample", method = RequestMethod.DELETE)


@ResponseBody
public String deleteExample() {
return "DELETE request received";
}
}
With Shortcut Annotations (Modern Spring Boot)
Spring Boot introduced shortcut annotations (@GetMapping, @PostMapping, etc.) for better
readability and simplicity.
package com.example.demo.controllers;
import org.springframework.web.bind.annotation.*;

@RestController
public class MyRestController {

@GetMapping("/getExample")
public String getExample() {
return "GET request received";
}

@PostMapping("/postExample")
public String postExample() {
return "POST request received";
}

@PutMapping("/putExample")
public String putExample() {
return "PUT request received";
}

@DeleteMapping("/deleteExample")
public String deleteExample() {
return "DELETE request received";
}
}

Key Differences

Shortcut Annotations
Feature @RequestMapping (Traditional)
(@GetMapping, etc.)

Requires explicitly specifying the HTTP


Simplicity Directly indicates the HTTP method.
method.

Readability More verbose and less intuitive. Cleaner and more readable.

Supports multiple HTTP methods in one Specific to one HTTP method per
Flexibility
annotation. annotation.

When to Use What?


 Use @RequestMapping if you need flexibility (e.g., supporting multiple HTTP methods
for the same endpoint):
@RequestMapping(value = "/example", method = {RequestMethod.GET, RequestMethod.POST})
public String example() {
return "Handled GET and POST!";
}
 Use shortcut annotations (@GetMapping, etc.) for most scenarios where a single HTTP
method is sufficient.

5. @Service
 Purpose: Marks a class as a service (business logic layer). Internally uses @Component.
 Use Case: To separate business logic from the controller layer.
 Example:
@Service
public class UserService {
public List<User> findAll() {
// Business logic here
}
}
 Cross Questions:
o Difference between @Service and @Component?
o Can we use @Service without @Autowired?

Difference Between @Service and @Component


@Service and @Component are both Spring stereotypes used to define beans that Spring
manages.

1. @Component
 Purpose: A generic stereotype used to denote any Spring-managed component.
 Usage:
o Applied to classes that act as general components in the application, such as
utility classes or any custom-defined beans.
o Serves as the parent stereotype for other specific annotations like @Service,
@Controller, and @Repository.
 Example:
@Component
public class MyUtility {
public String process() {
return "Utility processing...";
}
}

2. @Service
 Purpose: A specialization of @Component, specifically intended for service-layer classes.
 Usage:
o Indicates that a class contains business logic or service methods.
o May be used in conjunction with AOP (Aspect-Oriented Programming) features
like transactions.
 Example:
@Service
public class MyService {
public String performService() {
return "Service logic executed!";
}
}

Key Differences

Feature @Component @Service

Semantics Generic stereotype. Specialized for business logic classes.

Purpose Any Spring-managed bean. Indicates service layer logic.

Readability Less specific. More descriptive for services.

Behavior No extra behavior. Same as @Component with semantic clarity.

Can We Use @Service Without @Autowired?


Yes, you can use @Service without @Autowired. Here’s why:
 Automatic Dependency Injection:
When you annotate a class with @Service, Spring automatically registers it as a bean in
the application context. Other beans that need this service can have it injected via
@Autowired or constructor injection.
 Manual Invocation:
If you’re not using @Autowired, you can manually retrieve the @Service bean from the
application context, or you might instantiate it yourself (not recommended in Spring-
managed environments).
 Example Without @Autowired:
@Service
public class MyService {
public String performTask() {
return "Task performed!";
}
}

@Component
public class MyComponent {
private final MyService myService = new MyService(); // Manual instantiation (not ideal)

public void execute() {


System.out.println(myService.performTask());
}
}
 Recommended Practice: Use @Autowired or constructor injection to let Spring handle
the dependencies:
@Component
public class MyComponent {
private final MyService myService;

public MyComponent(MyService myService) { // Constructor Injection


this.myService = myService;
}

public void execute() {


System.out.println(myService.performTask());
}
}

When to Use @Service vs. @Component?


 Use @Service for service layer classes that contain business logic.
 Use @Component for general-purpose classes that don’t fit into service, repository, or
controller layers.

6. @Repository
 Purpose: Specialization of @Component. Used for the persistence layer, such as
database interaction.
 Use Case: To define DAO (Data Access Object) components.
 Example:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByName(String name);
}
 Cross Questions:
o Why do we need @Repository when @Component exists?
o What happens if we don't use @Repository on a DAO class?
The @Repository annotation in Spring is a specialization of @Component with additional
semantics and behaviors tailored for Data Access Object (DAO) classes. While both @Repository
and @Component result in a Spring-managed bean, there are specific reasons why @Repository
is preferred for DAO classes.

Why Do We Need @Repository When @Component Exists?


1. Semantic Clarity:
o @Repository explicitly indicates that the class is part of the persistence layer and
is responsible for interacting with the database.
o Improves code readability and structure by differentiating DAO classes from
generic components or service-layer beans.
2. Persistence Exception Translation:
o When a class is annotated with @Repository, Spring applies automatic exception
translation through the PersistenceExceptionTranslationPostProcessor.
o This means low-level database exceptions (like SQLException) are translated into
Spring's DataAccessException hierarchy, making the exceptions consistent and
easier to handle.
o Example:
 Without @Repository: Throws SQLException.
 With @Repository: Throws DataAccessException.

What Happens If We Don't Use @Repository on a DAO Class?


1. Bean Registration:
o The class will still function as a Spring-managed bean if annotated with
@Component instead of @Repository, so dependency injection will work
normally.
o Example:
@Component
public class UserDao {
// DAO logic here
}
2. Exception Translation:
o Will Not Happen Automatically:
 Without @Repository, Spring will not apply the exception translation
mechanism for DAO methods.
 You’ll have to handle raw exceptions (like SQLException) manually.
 To enable exception translation, you would need to configure
PersistenceExceptionTranslationPostProcessor explicitly and ensure DAO
methods are proxied.
3. Semantic Mismatch:
o Using @Component instead of @Repository might cause confusion for
developers as it doesn’t clearly convey the purpose of the class.

Example of Using @Repository


DAO Class with @Repository:
import org.springframework.stereotype.Repository;
import org.springframework.jdbc.core.JdbcTemplate;

@Repository
public class UserDao {

private final JdbcTemplate jdbcTemplate;

public UserDao(JdbcTemplate jdbcTemplate) {


this.jdbcTemplate = jdbcTemplate;
}

public String findUsernameById(int id) {


String sql = "SELECT username FROM users WHERE id = ?";
return jdbcTemplate.queryForObject(sql, String.class, id);
}
}
Exception Translation in Action:
try {
userDao.findUsernameById(1); // DAO method
} catch (DataAccessException ex) {
System.out.println("Handled by Spring: " + ex.getMessage());
}
Without @Repository:
 If SQLException occurs, it will not be translated automatically, and you’ll need to handle
it manually.

When to Use @Repository?


 Always use @Repository for classes that directly interact with the database (DAOs).
 It’s not only a best practice but also enables Spring to provide additional benefits like
exception translation.

7. @Component
 Purpose: Marks a class as a Spring-managed component (generic stereotype).
 Use Case: When a class doesn’t fit into a specific stereotype like @Service or
@Repository.
 Example:
@Component
public class EmailNotificationService {
public void sendEmail(String message) {
// Logic for sending emails
}
}
 Cross Questions:
o How does Spring discover classes with @Component?
o Can you replace @Component with other annotations?

How Does Spring Discover Classes with @Component?


Spring discovers classes annotated with @Component (and its specializations, such as @Service,
@Controller, and @Repository) through a process called Component Scanning.
1. Component Scanning Process
 Spring Configuration:
o Spring scans the application’s classpath for classes annotated with @Component
or its derived stereotypes. This scanning is triggered by specific configuration.
 Annotation-Driven:
o Classes annotated with @Component, @Service, @Controller, or @Repository
are registered as Spring-managed beans in the application context.

2. Enabling Component Scanning


Component scanning is typically enabled in two ways:
a) XML Configuration (Legacy):
<context:component-scan base-package="com.example.demo" />
 Spring will scan all classes under the specified base-package for @Component and
related annotations.
b) Annotation-Based Configuration (Modern):
 Use @ComponentScan or rely on @SpringBootApplication, which implicitly includes
@ComponentScan.
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
 @SpringBootApplication scans all packages under com.example.demo by default.

3. Default Scanning Scope


 Base Package: By default, Spring scans the package where the main application class
resides and its sub-packages.
 Custom Scope: You can customize the scope using @ComponentScan:
@ComponentScan(basePackages = {"com.example.service", "com.example.dao"})
public class AppConfig {
}

Can You Replace @Component with Other Annotations?


Yes, you can replace @Component with its specialized annotations (@Service, @Controller,
@Repository) or even create custom annotations.

1. Specialized Annotations
 @Controller: Indicates a web controller in the MVC layer.
 @Service: Indicates a service layer component containing business logic.
 @Repository: Indicates a persistence layer component (DAO) and enables exception
translation.
These annotations are functionally equivalent to @Component but provide additional semantics
and readability.

2. Custom Stereotype Annotations


You can create custom annotations that act as a replacement for @Component.
Example:
import org.springframework.stereotype.Component;

@Component
public @interface MyCustomAnnotation {
// Add additional metadata if required
}
Usage:
@MyCustomAnnotation
public class MyBean {
public void doSomething() {
System.out.println("Custom annotation works!");
}
}
Spring treats the custom annotation as a @Component because it is meta-annotated with
@Component.

3. Example of Replacement with Custom Annotations


import org.springframework.stereotype.Component;

@Component
public @interface TaskHandler {
// Custom annotation for task-related beans
}
Usage:
@TaskHandler
public class TaskManager {
public void manageTask() {
System.out.println("Managing tasks...");
}
}

8. @Autowired
 Purpose: Used to inject dependencies into a class.
 Use Case: To achieve dependency injection without manually creating objects.
 Example:
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;

public List<Order> getAllOrders() {


return orderRepository.findAll();
}
}
 Cross Questions:
o What is the difference between field injection and constructor injection?
o What happens if a required bean is not found?

1. What is the difference between field injection and constructor injection?


Field Injection:
 Definition: Directly injects dependencies into class fields using @Autowired.
 Example:
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
}
 Advantages:
o Easy to use and concise.
o No need to write constructors or setters.
 Disadvantages:
o Difficult to test as dependencies are hidden.
o Violates immutability as fields can be reassigned.
o No way to make fields final.

Constructor Injection:
 Definition: Dependencies are injected through the constructor of the class.
 Example:
@Service
public class OrderService {
private final OrderRepository orderRepository;

public OrderService(OrderRepository orderRepository) {


this.orderRepository = orderRepository;
}
}
 Advantages:
o Encourages immutability (final fields).
o Easier to test (dependencies are explicitly visible).
o Ensures that all required dependencies are provided at initialization time.
 Disadvantages:
o Slightly more verbose than field injection.

Key Differences:

Aspect Field Injection Constructor Injection

Visibility Dependencies are hidden. Dependencies are explicit.


Aspect Field Injection Constructor Injection

Testing Harder to test. Easier to test.

Immutability Fields cannot be final. Fields can be final.

Null Safety Dependencies can be missing. Dependencies are enforced.

Preferred Usage For simple projects. For complex, maintainable code.

Cross Questions:
 Which type of injection is recommended in Spring?
o Constructor injection is recommended because it promotes immutability and
makes dependencies explicit.
 Can you mix field and constructor injection in the same class?
o Yes, but it's generally discouraged as it can lead to inconsistent and harder-to-
maintain code.

2. What happens if a required bean is not found?


 Default Behavior:
o Spring throws a NoSuchBeanDefinitionException if a required bean is missing,
and the application context fails to start.

Scenarios:
1. Using @Autowired:
o By default, @Autowired is required. If the bean is not found, Spring throws:
UnsatisfiedDependencyException: Error creating bean with name [...]
o Solution: Use @Autowired(required = false) if the dependency is optional:
@Autowired(required = false)
private SomeService someService;
2. Using @Qualifier:
o If multiple beans of the same type exist but no specific bean is qualified, Spring
throws:
NoUniqueBeanDefinitionException
o Solution: Specify the desired bean explicitly using @Qualifier:
@Autowired
@Qualifier("specificBeanName")
private SomeService someService;
3. Using Constructor Injection:
o If a required constructor dependency is missing, the application fails to start with:
UnsatisfiedDependencyException
o Solution: Ensure all required beans are defined in the context.
4. Using Optional:
o Mark the dependency as optional to handle cases where the bean might not be
present:
@Autowired
private Optional<SomeService> someService;

Cross Questions:
 What happens if two beans of the same type are present?
o Spring throws a NoUniqueBeanDefinitionException.
o Solution: Use @Primary or @Qualifier.
 What is the use of @Primary in Spring?
o @Primary marks a bean as the default choice when multiple candidates are
available:
@Primary
@Bean
public SomeService someServiceImpl() {
return new SomeServiceImpl();
}
 What are the alternatives to @Autowired?
o Alternatives include @Inject (from JSR-330) and XML-based configuration.

9. @Configuration
 Purpose: Indicates that a class contains bean definitions and configuration settings.
 Use Case: To define application-specific beans.
 Example:
@Configuration
public class AppConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
 Cross Questions:
o Difference between @Configuration and @Component?
o Can a class annotated with @Configuration contain @ComponentScan?

Feature @Configuration @Component

Used for defining Spring configuration


A generic stereotype used to define
Purpose classes that define beans explicitly using
any Spring-managed component.
@Bean methods.

Bean Typically used to declare multiple beans Generally used for components like
Declaration using @Bean annotated methods. services, controllers, or repositories.
Feature @Configuration @Component

Classes annotated with @Configuration Classes annotated with


Proxy Behavior are enhanced by Spring to ensure @Component are not proxied unless
singleton beans (CGLIB proxying). explicitly needed (e.g., with AOP).

Beans are typically autodetected and


Explicit Bean Allows the manual declaration of beans
registered through component
Definition with custom configurations.
scanning.

Indicates a generic Spring-managed


Semantic Indicates a configuration class that
class, not necessarily for
Intent provides bean definitions.
configurations.

10. @Bean
 Purpose: Used to define a bean within @Configuration classes.
 Use Case: To manually define and control bean lifecycles.
 Example:
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
 Cross Questions:
o What is the default scope of a bean?
o Can a bean method have parameters?

1. What is the default scope of a bean in Spring?


Default Scope: singleton
 In Spring, the default scope of a bean is singleton, meaning a single instance of the bean
is created and shared across the entire application context.
 This ensures that the same instance is used wherever the bean is injected.

Key Points about singleton Scope:


 A single instance is created per Spring container.
 The bean is initialized when the container is started (eager initialization).
 Shared across all requests or injections.

Example:
@Component
public class MySingletonBean {
public void doSomething() {
System.out.println("Singleton instance invoked!");
}
}

@RestController
public class TestController {
@Autowired
private MySingletonBean mySingletonBean1;

@Autowired
private MySingletonBean mySingletonBean2;

@GetMapping("/test")
public String testSingleton() {
System.out.println(mySingletonBean1 == mySingletonBean2); // Prints: true
return "Check console for output";
}
}

Cross Questions:
 What are the other scopes available in Spring?
1. prototype: Creates a new instance each time the bean is requested.
2. request: One instance per HTTP request (web applications).
3. session: One instance per HTTP session (web applications).
4. application: One instance per ServletContext.
5. websocket: One instance per WebSocket lifecycle.
 When should you use prototype over singleton?
o Use prototype when each bean instance requires a different state, such as in
stateful components like HTTP requests or threads.
 Can a singleton bean depend on a prototype bean?
o Yes, but it requires special handling, typically using the @Lookup annotation or a
Provider.

11. @EnableAutoConfiguration
 Purpose: Enables Spring Boot’s auto-configuration feature.
 Use Case: Automatically configures components like data sources, message queues, etc.,
based on dependencies in the classpath.
 Example:
@SpringBootApplication
public class Application {
}
(Included implicitly in @SpringBootApplication)
 Cross Questions:
o What if I want to exclude a specific auto-configuration?
o Can we use @EnableAutoConfiguration without @SpringBootApplication?

1. What if I want to exclude a specific auto-configuration?


Answer:
 You can exclude a specific auto-configuration class using the exclude or excludeName
attributes of the @SpringBootApplication or @EnableAutoConfiguration annotations.

Example: Excluding Specific Auto-Configuration


@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
 Explanation:
o The above example disables the DataSourceAutoConfiguration, which is used to
auto-configure database-related beans.
o This is useful when your application doesn't use a database or if you want to
manually configure database beans.

Using excludeName:
 You can also use the fully qualified name of the auto-configuration class:
@SpringBootApplication(excludeName =
"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration")
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}

Cross Questions:
 How do I find the list of auto-configurations in Spring Boot?
o Use the --debug flag when starting the application. It will log all enabled and
excluded auto-configurations.
java -jar myapp.jar --debug
 What happens if you exclude a required auto-configuration?
o If you exclude a critical auto-configuration, the application context may fail to
start due to missing required beans.

2. Can we use @EnableAutoConfiguration without @SpringBootApplication?


Answer: Yes
 The @SpringBootApplication annotation is a composite annotation that includes
@EnableAutoConfiguration, @ComponentScan, and @Configuration.
 You can use @EnableAutoConfiguration independently, but you’ll need to manually
configure other necessary annotations like @ComponentScan or @Configuration.

Example: Using @EnableAutoConfiguration Without @SpringBootApplication


@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = "com.example")
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
 Explanation:
o Here, @EnableAutoConfiguration is used to enable Spring Boot's auto-
configuration features.
o @ComponentScan is added to scan for components, services, and repositories in
the specified package.

Cross Questions:
 What’s the difference between @EnableAutoConfiguration and
@SpringBootApplication?
o @SpringBootApplication is a convenience annotation that combines:
1. @EnableAutoConfiguration - Enables auto-configuration.
2. @ComponentScan - Scans for components, services, and repositories.
3. @Configuration - Marks the class as a source of bean definitions.
 Why would you use @EnableAutoConfiguration without @SpringBootApplication?
o In scenarios where you want finer control over the application context or do not
want to include all the default behaviors provided by @SpringBootApplication.
 Can I use custom packages for scanning with @EnableAutoConfiguration?
o No, @EnableAutoConfiguration only configures beans. Use @ComponentScan to
specify custom packages.

12. @Transactional
 Purpose: Manages database transactions, ensuring atomicity and rollback on failure.
 Use Case: To handle operations involving multiple database calls.
 Example:
@Service
public class AccountService {
@Transactional
public void transferFunds(Long fromAccount, Long toAccount, Double amount) {
debit(fromAccount, amount);
credit(toAccount, amount);
}
}
 Cross Questions:
o How does Spring manage transactions under the hood?
o What happens if you annotate a private method with @Transactional?

1. How does Spring manage transactions under the hood?


Answer:
Spring manages transactions using the AOP (Aspect-Oriented Programming) approach. It uses
proxies to wrap transactional methods and intercept method calls to apply transactional
behavior.

How It Works:
1. Proxy Creation:
o Spring creates a proxy object for the bean containing the transactional method.
o This proxy intercepts method calls and applies transactional logic before and
after the method execution.
2. Transaction Interception:
o When a method annotated with @Transactional is invoked, the proxy:
 Opens a transaction (if none exists).
 Executes the method within the transactional context.
 Commits the transaction if the method executes successfully.
 Rolls back the transaction in case of an exception.
3. Transaction Management:
o Spring uses a PlatformTransactionManager to coordinate the transaction with
the underlying database.
o Common implementations include:
 DataSourceTransactionManager (JDBC transactions).
 JpaTransactionManager (JPA or Hibernate transactions).

Example:
@Service
public class OrderService {
@Transactional
public void placeOrder(Order order) {
// Transaction starts here
orderRepository.save(order);
paymentService.processPayment(order);
// Transaction commits here
}
}

Cross Questions:
 What is propagation in transactions?
o Transaction propagation defines how transactions interact when a
transactional method calls another transactional method.
o Example: REQUIRED, REQUIRES_NEW, NESTED.
 How does Spring determine the rollback policy?
o By default, Spring rolls back transactions for unchecked exceptions
(RuntimeException or subclasses).
o To roll back for checked exceptions, explicitly configure
@Transactional(rollbackFor = Exception.class).
 What are isolation levels in transactions?
o Isolation levels define how transactions interact with each other, e.g.,
READ_COMMITTED, REPEATABLE_READ, etc.

2. What happens if you annotate a private method with @Transactional?


Answer:
 @Transactional has no effect on private methods.
 Spring's transaction management relies on proxies (created using AOP). These proxies
can only intercept public or protected methods because they require a method call from
an external class or a different method within the same class.

Why Private Methods Are Ignored:


 When a private method is called:
o The call doesn't go through the proxy.
o Transactional logic is not applied because the proxy cannot intercept the method.

Example:
@Service
public class OrderService {
@Transactional
public void placeOrder(Order order) {
saveOrder(order); // Transactional logic applies here
}

@Transactional
private void saveOrder(Order order) {
orderRepository.save(order); // This is ignored by Spring
}
}
 Result: The saveOrder method will not be executed within a transaction context because
it's private.

Cross Questions:
 How do you handle transactional logic for private methods?
o Refactor the private method to be public or protected.
o Use programmatic transaction management with TransactionTemplate.
 What are the limitations of Spring's proxy-based AOP?
o Cannot intercept calls to private methods.
o Self-invocation (calling another method within the same class) bypasses proxies
and doesn't apply AOP logic.
 Can we use @Transactional on interfaces?
o Yes, Spring AOP works at the interface level when using JDK dynamic proxies. For
class-based proxies, it works on class methods.

What is Inversion of Control (IoC)?


Inversion of Control (IoC) is a design principle where the control of object creation,
configuration, and lifecycle management is transferred from the application code to a container
or framework. In simpler terms, IoC means that objects do not create other objects on which
they depend. Instead, they get the objects they need from an external source (the IoC
container).
IoC helps in decoupling the application components, making the code more modular, testable,
and maintainable. Spring’s IoC container is responsible for instantiating, configuring, and
assembling objects known as beans.

What is Dependency Injection (DI)?


Dependency Injection (DI) is a design pattern and a core part of IoC. DI is a technique whereby
one object supplies the dependencies of another object. In Spring, the IoC container injects
dependencies into a bean at runtime, rather than the bean creating or looking up dependencies
itself.
There are three common ways to inject dependencies in Spring:
1. Constructor Injection: Dependencies are provided through a class constructor.
2. Setter Injection: Dependencies are provided through setter methods.
3. Field Injection: Dependencies are injected directly into fields using annotations.
Practical Example: A Simple Spring Application
To understand IoC and DI better, let’s consider a simple Spring application. We’ll create a basic
service that provides messages and demonstrate how to inject dependencies using Spring’s IoC
container.
Step 1: Setting Up the Project
First, we’ll create a Maven project and include the necessary Spring dependencies in
the pom.xml file.
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version>
</dependency>
</dependencies>
Step 2: Defining the Service Interface and Implementation
Let’s define a service interface MessageService and its implementation EmailMessageService.
// MessageService.java
public interface MessageService {
String getMessage();
}

// EmailMessageService.java
public class EmailMessageService implements MessageService {
@Override
public String getMessage() {
return "Email Message Service";
}
}
Step 3: Creating the Consumer Class
Now, we’ll create a consumer class MessagePrinter that depends on MessageService.
// MessagePrinter.java
public class MessagePrinter {
private MessageService messageService;

// Constructor for Constructor Injection


public MessagePrinter(MessageService messageService) {
this.messageService = messageService;
}

public void printMessage() {


System.out.println(messageService.getMessage());
}
}
Step 4: Configuring Spring Beans
We’ll configure the Spring beans in an XML configuration file beans.xml.
<!-- beans.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="emailMessageService" class="com.example.EmailMessageService" />


<bean id="messagePrinter" class="com.example.MessagePrinter">
<constructor-arg ref="emailMessageService" />
</bean>
</beans>
Step 5: Running the Application
Finally, we’ll create a main class to load the Spring context and run the application.
// Application.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Application {


public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
MessagePrinter printer = context.getBean(MessagePrinter.class);
printer.printMessage();
}
}
Explanation
In this example:
1. IoC Container: Spring’s IoC container is configured via the beans.xml file.
2. Dependency Injection: The MessagePrinter class does not create an instance
of MessageService. Instead, the Spring IoC container injects
the EmailMessageService dependency into MessagePrinter via constructor injection.
Practical Example: A Simple Spring Application Using Annotations
Step 1: Setting Up the Project
First, we’ll create a Maven project and include the necessary Spring dependencies in
the pom.xml file.
Step 2: Defining the Service Interface and Implementation
Let’s define a service interface MessageService and its implementation EmailMessageService.
// MessageService.java
public interface MessageService {
String getMessage();
}

// EmailMessageService.java
import org.springframework.stereotype.Service;

@Service
public class EmailMessageService implements MessageService {
@Override
public String getMessage() {
return "Email Message Service";
}
}
Step 3: Creating the Consumer Class
Now, we’ll create a consumer class MessagePrinter that depends on MessageService.
// MessagePrinter.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MessagePrinter {
private final MessageService messageService;

// Constructor Injection
@Autowired
public MessagePrinter(MessageService messageService) {
this.messageService = messageService;
}

public void printMessage() {


System.out.println(messageService.getMessage());
}
}
Step 4: Configuring Spring with Annotations
We’ll use annotation-based configuration instead of XML. For this, we’ll create a configuration
class.
// AppConfig.java
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}
Step 5: Running the Application
Finally, we’ll create a main class to load the Spring context and run the application.
// Application.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Application {


public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MessagePrinter printer = context.getBean(MessagePrinter.class);
printer.printMessage();
}
}
Explanation
In this example:
1. IoC Container: Spring’s IoC container is configured using
the @Configuration and @ComponentScan annotations in AppConfig.
2. Dependency Injection: The MessagePrinter class does not create an instance
of MessageService. Instead, Spring injects the EmailMessageService dependency
into MessagePrinter via constructor injection using the @Autowired annotation.
Benefits of IoC and DI
 Decoupling: Dependencies are managed by the container, promoting loose coupling
between classes.
 Testability: Objects can be easily mocked or stubbed for testing purposes.
 Maintainability: Changes to the configuration or implementation of dependencies do
not require changes in the dependent classes.
How DI Works:
 The dependencies required by a class are provided by an IoC container (like Spring)
instead of the class instantiating them directly.
IoC Container in Spring:
 The Spring Framework provides an IoC container that:
o Manages the lifecycle of objects (beans).
o Resolves dependencies between objects automatically.
o Configures and wires beans via XML, annotations, or Java-based configuration.

How can we call third party API in java spring boot appln?
To call a third-party API in a Spring Boot application, you typically use a HTTP client library to
make the request and handle the response. Spring Boot provides built-in support for HTTP
clients like RestTemplate and WebClient.

1. Using RestTemplate (Simpler Option)


RestTemplate is a synchronous client provided by Spring for RESTful API calls. Although it's being
gradually replaced by WebClient, it’s still widely used.
Steps:
1. Add the RestTemplate bean to your application.
2. Use it to send GET, POST, PUT, DELETE requests to the third-party API.
Example: Call a third-party API using RestTemplate
Dependencies (if not already included):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Code Implementation:
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class ApiService {

private final RestTemplate restTemplate;

public ApiService(RestTemplate restTemplate) {


this.restTemplate = restTemplate;
}

public String getWeatherData(String city) {


String url = "https://api.openweathermap.org/data/2.5/weather?q=" + city +
"&appid=your_api_key";
return restTemplate.getForObject(url, String.class); // Makes the GET request
}
}
Configuration Class for RestTemplate:
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();
}
}
Usage in Controller:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WeatherController {

private final ApiService apiService;

public WeatherController(ApiService apiService) {


this.apiService = apiService;
}

@GetMapping("/weather")
public String getWeather(@RequestParam String city) {
return apiService.getWeatherData(city);
}
}
2. Using WebClient (Modern, Reactive Option)
WebClient is a reactive, non-blocking HTTP client introduced in Spring WebFlux. It is suitable for
both synchronous and asynchronous requests.
Steps:
1. Add the WebClient bean to your application.
2. Use it to send GET, POST, PUT, DELETE requests to the third-party API.
Example: Call a third-party API using WebClient
Dependencies (if not already included):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Code Implementation:
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

@Service
public class ApiService {

private final WebClient webClient;

public ApiService(WebClient.Builder webClientBuilder) {


this.webClient =
webClientBuilder.baseUrl("https://api.openweathermap.org/data/2.5").build();
}

public String getWeatherData(String city) {


return webClient.get()
.uri(uriBuilder -> uriBuilder
.path("/weather")
.queryParam("q", city)
.queryParam("appid", "your_api_key")
.build())
.retrieve()
.bodyToMono(String.class) // Asynchronous response
.block(); // Blocks to make it synchronous
}
}
Configuration Class for WebClient:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class AppConfig {
@Bean
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
Usage in Controller:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WeatherController {

private final ApiService apiService;

public WeatherController(ApiService apiService) {


this.apiService = apiService;
}

@GetMapping("/weather")
public String getWeather(@RequestParam String city) {
return apiService.getWeatherData(city);
}
}

3. When to Use RestTemplate vs WebClient

Aspect RestTemplate WebClient

Blocking Synchronous, blocking requests Non-blocking, asynchronous requests

Recommended For Legacy applications, simple APIs Modern applications, high concurrency

Performance Less efficient under high load Better scalability for concurrent calls

Availability Still available but legacy Recommended by Spring for new projects

4. Best Practices
 Handle Errors Gracefully: Use try-catch blocks or exchange() for error handling.
 Use DTOs: Map the API responses to Data Transfer Objects (DTOs) for better structure.
 Externalize Configurations: Store API URLs and keys in application.properties or
application.yml.
api.base.url=https://api.openweathermap.org/data/2.5
api.key=your_api_key

You might also like