Spring Boot - Dependency Injection and Spring Beans
Last Updated :
28 Aug, 2024
Spring Boot is a powerful framework for building RESTful APIs and microservices with minimal configuration. Two fundamental concepts within Spring Boot are Dependency Injection (DI) and Spring Beans. Dependency Injection is a design pattern used to implement Inversion of Control (IoC), allowing the framework to manage object creation and dependencies. Spring Beans are objects managed by the Spring IoC container, forming the backbone of any Spring application.
Dependency Injection and Spring Beans
Dependency Injection (DI)
Dependency Injection is a design pattern that allows the creation of dependent objects to be managed by an external source rather than the object managing its dependencies itself. This pattern promotes loose coupling, enhancing flexibility and making code easier to maintain and test.
In a Spring application, Dependency Injection can be achieved in three main ways:
1. Constructor Injection
Dependencies are provided through the class constructor. This method ensures that dependencies are provided at the time of object creation, making the object immutable.
Example:
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MyServiceClass {
private final Dependency dependency;
// Constructor Injection
@Autowired
public MyServiceClass(Dependency dependency) {
this.dependency = dependency;
}
// Getter method (optional)
public Dependency getDependency() {
return dependency;
}
}
@Service
: Marks this class as a Spring Bean.@Autowired
: Injects the Dependency
object into the constructor.- Constructor injection ensures that the dependency is required for the object to be created.
2. Setter Injection
Dependencies are provided through setter methods. This method allows for optional dependencies and the ability to change dependencies after the object is created.
Example:
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MyService {
private Dependency dependency;
// Setter Injection
@Autowired
public void setDependency(Dependency dependency) {
this.dependency = dependency;
}
// Getter method (optional)
public Dependency getDependency() {
return dependency;
}
}
@Service
: Marks this class as a Spring Bean.@Autowired
: Injects the Dependency
object into the setter method.- Setter injection allows the dependency to be set after object creation.
3. Field Injection
Dependencies are directly injected into fields using annotations like @Autowired
. This method is concise but generally discouraged as it hides dependencies, making the code less clear and harder to test.
Example:
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MyService {
// Field Injection
@Autowired
private Dependency dependency;
// Getter method (optional)
public Dependency getDependency() {
return dependency;
}
}
@Service
: Marks this class as a Spring Bean.@Autowired
: Injects the Dependency
object directly into the field.- Field injection can make the code harder to test and maintain due to the lack of visibility of dependencies.
Spring Beans
Spring Beans are objects managed by the Spring IoC container. A bean is typically an instance of a class that is managed by Spring, and its lifecycle (creation, initialization, and destruction) is managed by the container. Beans can be configured using annotations or XML configuration files.
Defining Beans:
1. Using the Annotations
@Component
: A general-purpose annotation to mark a class as a Spring Bean.@Service
: Specialized for service-layer classes.@Repository
: Specialized for persistence-layer classes.@Controller
: Specialized for controller classes in Spring MVC.
Example:
@Service
public class MyService {
public String serve() {
return "Service is running!";
}
}
@Service
: Marks this class as a Spring Bean specifically for the service layer.- The
serve
method provides functionality for the service.
2. Using the @Bean Annotation
Beans can also be defined using the @Bean
annotation within a configuration class. This method provides more control over the bean creation process.
Example:
@Configuration
public class AppConfig {
// Define a bean of type MyService
@Bean
public MyService myService() {
return new MyService();
}
}
@Configuration
: Indicates that this class contains bean definitions.@Bean
: Defines a bean method, allowing more control over bean creation.
Bean Scopes:
Spring supports several bean scopes:
- Singleton: A single instance of the bean is created and shared across the application.
- Prototype: A new instance of the bean is created each time it is requested.
- Request: A single instance of the bean is created for each HTTP request, typically used in web applications.
- Session: A single instance is created for each HTTP session (used in web applications).
Step-by-step Implementation with Example
Let's create a simple Spring Boot project to demonstrate Dependency Injection and Spring Beans.
Step 1: Create the Spring Boot Project
Create a new Spring Boot project using IntelliJ IDEA with the following options:
- Name: spring-inject-demo
- Language: Java
- Type: Maven
- Packaging: Jar
Click on the Next button.
Step 2: Add Dependencies
Add the following dependencies into the Spring Boot project.
spring-boot-starter-web
: Includes dependencies for building web applications.spring-boot-devtools
: Provides development-time tools like automatic restarts.lombok
: A library that reduces boilerplate code (optional).spring-boot-starter-test
: Provides testing dependencies.
Project Structure
After creating the project, the file structure will look like this:
Step 4: Define the Service Interface
Create an interface named GreetingService
to define a method for greeting.
Java
package com.gfg.springinjectdemo;
public interface GreetingService {
String greet();
}
This interface defines a single method greet
, which will be implemented by service classes.
Step 5: Implement the Service Interface
Create a class EnglishGreetingService
that implements the GreetingService
interface.
Java
package com.gfg.springinjectdemo;
import org.springframework.stereotype.Service;
@Service
public class EnglishGreetingService implements GreetingService {
@Override
public String greet() {
return "Hello, World!";
}
}
Explanation:
@Service
: Marks this class as a Spring Bean and registers it with the Spring context.greet()
: Provides a greeting message.
Step 6: Create the Controller to Use the Service
Create a GreetingController
to use the GreetingService
.
Java
package com.gfg.springinjectdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
private final GreetingService greetingService;
// Constructor Injection
@Autowired
public GreetingController(GreetingService greetingService) {
this.greetingService = greetingService;
}
// Endpoint to return greeting message
@GetMapping("/greet")
public String greet() {
return greetingService.greet();
}
}
Explanation:
@RestController
: Marks this class as a REST controller.@Autowired
: Injects the GreetingService
into the constructor.@GetMapping("/greet")
: Maps the /greet
URL to the greet
method, which returns the greeting message.
Step 7: Main Class
The main class remains unchanged.
Java
package com.gfg.springinjectdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringInjectDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringInjectDemoApplication.class, args);
}
}
@SpringBootApplication
: Indicates that this is a Spring Boot application.main()
: The entry point of the application.
pom.xml file:
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>spring-inject-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-inject-demo</name>
<description>spring-inject-demo</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 8: Run the application
After completion of the project, now run the application and it will start at port 8080.
Step 9: Test the Application
Now, we will test the endpoint in the browser and see the output below:
http://localhost:8080/greet
Output:
This project demonstrates the Dependency Injection and Spring Beans of the Spring Boot Application.
Similar Reads
Spring - Difference Between Inversion of Control and Dependency Injection
Understanding the difference between Inversion of Control (IoC) and Dependency Injection (DI) is very important for mastering the Spring framework. Both concepts are closely related, they serve different purposes in the context of Spring. The main difference between IoC and DI is listed below:Invers
3 min read
Spring - Dependency Injection by Setter Method
Dependency Injection is one of the core features of the Spring Framework Inversion of Control (IOC) container. It reduces the need for classes to create their own objects by allowing the Spring IOC container to do it for them. This approach makes the code more flexible, easier to test, and simpler t
5 min read
Spring - Difference Between Dependency Injection and Factory Pattern
Dependency Injection and Factory Pattern are almost similar in the sense that they both follow the interface-driven programming approach and create the instance of classes. A. Factory Pattern In Factory Pattern, the client class is still responsible for getting the instance of products by class getI
4 min read
Spring Dependency Injection: @Autowired vs Constructor Injection
In Spring framework, dependency injection is a key idea that lets you inject dependencies into a class in preference to hard coding them. This provides loose coupling and makes the code extra maintainable and testable. There are distinct methods to perform dependency injection.Common Approaches to
4 min read
Spring Dependency Injection with Example
Dependency Injection is the main functionality provided by Spring IOC(Inversion of Control). The Spring-Core module is responsible for injecting dependencies through either Constructor or Setter methods. The design principle of Inversion of Control emphasizes keeping the Java classes independent of
7 min read
Spring - When to Use @Qualifier and @Autowired For Dependency Injection
In the world of Spring Framework, managing dependencies is a fundamental aspect of building robust and maintainable applications. Spring offers two primary annotations to facilitate dependency injection: @Autowired and @Qualifier. Understanding when and how to use these annotations is crucial for ef
6 min read
Spring - Constructor Injection with Dependent Object
In the constructor injection, the dependency injection will be injected with the help of constructors. Now to set the dependency injection as constructor dependency injection(CDI) in bean, it is done through the bean-configuration file For this, the property to be set with the constructor dependency
3 min read
Spring Boot - Dependency Management
Spring Boot framework is the most popular web development framework. No doubt, it provides an abundance of essential features and a convenient way to handle those features. At the heart of Spring Boot is the 'Dependency Management' feature. Importance of Dependency ManagementCentralized Dependency M
6 min read
Spring Boot Interview Questions and Answers
Spring Boot is a Java-based framework used to develop stand-alone, production-ready applications with minimal configuration. Introduced by Pivotal in 2014, it simplifies the development of Spring applications by offering embedded servers, auto-configuration, and fast startup. Many top companies, inc
15+ min read
Spring Boot - Consuming and Producing JSON
Spring Boot is one of the famous frameworks for developing web applications and this framework provides a lot of features like auto-configuration, Spring Integration, Dependency management, and other features are available in Spring Boot framework. In this article, we will explain Spring Boot Consum
3 min read