Expert · Spring Boot basics · topic 51 of 60 · 25 min
Spring and dependency injection
Explanation
The problem: new everywhere
public class OrderService {
private final PaymentGateway gateway = new RazorpayGateway("live-key"); // hard-wired
private final SmsSender sms = new TwilioSmsSender(); // hard-wired
}OrderService decides which payment gateway and SMS provider to use, creates them itself, and even holds a key. To test it without charging real cards, or to switch providers, you must edit OrderService. The classes are tightly coupled.
Dependency injection
Dependency injection (DI) means a class RECEIVES the objects it depends on, usually through its constructor, instead of creating them. Something outside (in Spring's case, the container) decides which implementation to pass. You already did this by hand with OtpService(SmsSender) in module 5.
@Service
public class OrderService {
private final PaymentGateway gateway;
private final SmsSender sms;
public OrderService(PaymentGateway gateway, SmsSender sms) { // constructor injection
this.gateway = gateway;
this.sms = sms;
}
}
@Component
public class RazorpayGateway implements PaymentGateway { … } // Spring creates this bean
@Component
public class SmsGatewaySender implements SmsSender { … }The container and beans
At start-up, Spring scans your packages for classes annotated as components, creates one object (a bean) of each by default (singleton scope), works out which beans need which others, and wires them together. This is Inversion of Control: the framework controls object creation, not your code.
| Annotation | Meaning |
|---|---|
| @Component | A general Spring-managed bean |
| @Service | A bean holding business logic (same as @Component, clearer intent) |
| @Repository | A bean that accesses data (also translates database exceptions) |
| @RestController | A bean that handles HTTP requests (topic 3) |
| @Configuration + @Bean | Create beans in code, for example for third-party classes |
@Configuration
public class ClockConfig {
@Bean
public java.time.Clock clock() {
return java.time.Clock.system(java.time.ZoneId.of("Asia/Kolkata")); // a bean you can inject anywhere
}
}Constructor versus field injection
You will see @Autowired on fields in older code (@Autowired private SmsSender sms;). Prefer constructor injection: the fields can be final, the dependencies are obvious, the object can never exist half-initialised, and tests can simply call new OrderService(fakeGateway, fakeSms) without Spring.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Spring and dependency injection · 1/6
In this lesson you will learn the core idea of Spring: dependency injection.
Prefer a video by a teacher? Find free videos on “spring dependency injection ioc container explained constructor injection” on YouTube ↗
In real life: Swapping SMS providers without touching business code
A clinic-booking startup moved from one SMS provider to another because of pricing. Because BookingService only depended on the SmsSender interface and received it through its constructor, the change was one new @Component class and marking it @Primary; BookingService and its tests did not change.
@Component
@Primary
public class NewProviderSmsSender implements SmsSender {
public void send(String phone, String text) { /* call the new provider's API */ }
}Practice (0/3 done)
What is Inversion of Control in Spring?
Two classes implement PaymentGateway and both are @Component. OrderService needs a PaymentGateway. What happens at start-up?
Without Spring, refactor a class ReportService that does "new EmailSender()" inside a method so that it receives a Sender interface through its constructor. Write a FakeSender for a test, and a main method that wires the real EmailSender by hand. Then explain in two sentences how Spring would do the wiring for you.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Creating a Spring Boot appSpring Boot basics · same module
- Building a REST APISpring Boot basics · same module
- Layers: controller, service and repositorySpring Boot basics · same module
- Dependency injection and service lifetimesC# and .NET · Web APIs with ASP.NET Core and EF Core
- Dependency injection with HiltKotlin and Android App Development · Navigation and app architecture
- Common design patternsDesign patterns, JVM internals and interviews
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What is a Spring bean?
Answer: An object created and managed by the Spring container
Beans are container-managed objects.
Which injection style is recommended?
Answer: Constructor injection
Constructor injection gives final fields and easy tests.
What is the default scope of a Spring bean?
Answer: Singleton: one shared instance per container
Singleton by default.
Which annotation creates a bean from a method in a configuration class?
Answer: @Bean
@Bean methods inside @Configuration classes.
What is dependency injection?Related
Answer: Giving a class its dependencies from outside instead of it creating them
Dependencies are supplied, usually via the constructor.
What does @Inject constructor do?Related
Answer: Tells Hilt how to create the class
Hilt calls it with the needed dependencies.
Which server is embedded by default with spring-boot-starter-web?Related
Spring implements @Transactional by wrapping beans in a…Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 4 more topics in “Spring Boot basics” before its exam: Creating a Spring Boot app, Building a REST API, Layers: controller, service and repository, JPA and Spring Data repositories.
- Module 11 exam: Spring Boot basics · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Design patterns, JVM internals and interviews. 60 topics left in the course before the final exam.