Beans & dependency injection
How Spring creates and wires objects, @Component/@Service and constructor injection.
Spring manages objects called beans. Instead of writing new EmailService() inside your classes, you declare what a class needs and Spring passes it in. This is dependency injection (DI).
- Mark classes with
@Component, or the more specific@Service,@Repositoryor@RestController. - Use constructor injection: list dependencies as constructor parameters and make the fields
final. With one constructor, no annotation is needed. - Use
@Beanmethods in a@Configurationclass for objects from libraries you can't annotate.
DI keeps classes loosely coupled — in tests you can pass a fake implementation instead of the real one.
Example code
Spring Boot 3 · Java 17+public interface Notifier {
String send(String to, String message);
}
@Service
class EmailNotifier implements Notifier {
public String send(String to, String message) {
return "Email to " + to + ": " + message;
}
}
@Service
class ApplicationService {
private final Notifier notifier;
ApplicationService(Notifier notifier) { // injected by Spring
this.notifier = notifier;
}
String apply(String email, String jobTitle) {
return notifier.send(email, "Applied for " + jobTitle);
}
}
// somewhere at startup:
// System.out.println(applicationService.apply("anu@example.com", "Java Developer"));
Output / API response
Email to anu@example.com: Applied for Java Developer
Generate a project at start.spring.io (Maven, Java 17+, dependencies: Spring Web, Spring Data JPA, H2, Validation), add the code, and run ./mvnw spring-boot:run. Learn the Java tutorial first if you're new to Java. Data is fictional.
Key points
- Beans are objects created and managed by Spring.
- Prefer constructor injection with final fields.
- @Service, @Repository and @RestController are specialised @Components.
- DI makes classes easy to test with fake dependencies.
Quick check
Which injection style is recommended?
Constructor injection makes dependencies explicit, allows final fields and makes classes easy to construct in unit tests.
Practice task
Add a second Notifier implementation (SmsNotifier) and see the startup error; then fix it by marking one with @Primary.
Interview corner
What is dependency injection and why use it?
A design where an object's dependencies are provided from outside (by the Spring container) rather than created inside it. It reduces coupling, makes code easier to test with mocks and lets you swap implementations.
What happens if two beans implement the same interface?
Spring can't decide which to inject and fails at startup. Resolve it with @Primary on one bean, or @Qualifier("name") at the injection point.
Further reading
Official documentation, linked for deeper study. These are outside sites; this lesson's text is our own.
Original lesson written by the InfoparkDaily team · © 2026 InfoparkDaily · Free to learn — no paid course or subscription.