1. Introduction
The @Inject
annotation is part of Java’s standard dependency injection specification, defined in JSR-330 (Java Specification Request). It allows you to inject dependencies into Spring-managed beans in a way that’s decoupled from the Spring framework itself.
2. What is @Inject
?
@Inject
is a standard annotation provided by Javax Dependency Injection API (javax.inject.Inject
) for constructor, field, or setter-based dependency injection.
It was introduced to standardize dependency injection across Java frameworks like Spring, Google Guice, etc.
Package:
import javax.inject.Inject;
To use it, your project must include the JSR-330 dependency (Spring Boot includes this transitively through Spring Core).
3. Comparison: @Inject
vs @Autowired
Feature | @Inject | @Autowired |
Origin | JSR-330 (javax.inject.Inject) | Spring-specific |
Required Dependency | Always required (no required flag) | Has required flag (optional deps) |
Default behavior | Inject by type | Inject by type |
Support for Qualifiers | Yes, with @Named | Yes, with @Qualifier |
Preferred in… | Framework-independent code | Spring-specific applications |
4. When to Use @Inject
Use @Inject
when:
- You want to write framework-agnostic code
- You want to promote clean architecture (not tightly coupled with Spring)
- You’re building libraries or components that might be used with Guice, Spring, or other DI frameworks
5. How to Use @Inject
in Spring Boot
Spring Boot supports @Inject
just like @Autowired
, thanks to Spring’s support for the JSR-330 standard.
A. Field Injection
@Component public class NotificationService { @Inject private EmailService emailService; public void send(String to, String message) { emailService.sendEmail(to, message); } }
B. Constructor Injection (Recommended)
@Component public class NotificationService { private final EmailService emailService; @Inject public NotificationService(EmailService emailService) { this.emailService = emailService; } public void send(String to, String message) { emailService.sendEmail(to, message); } }
Constructor injection is preferred because:
- It makes dependencies explicit
- Enables better testability
- Ensures immutability of fields
C. Setter Injection
@Component public class NotificationService { private EmailService emailService; @Inject public void setEmailService(EmailService emailService) { this.emailService = emailService; } }
6. Using @Named
with @Inject
(Like @Qualifier
)
If you have multiple beans of the same type, use @Named
to specify which one to inject:
@Component @Named("email") public class EmailService implements MessageService { public void sendMessage(String msg) { System.out.println("Email: " + msg); } } @Component @Named("sms") public class SMSService implements MessageService { public void sendMessage(String msg) { System.out.println("SMS: " + msg); } } @Component public class NotificationService { @Inject @Named("sms") private MessageService messageService; public void notify(String msg) { messageService.sendMessage(msg); } }
7. Requirements for Using @Inject
Spring Boot includes support for @Inject
out of the box.
If you’re using plain Spring (not Boot), you may need to add this dependency:
<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
In Spring Boot, this is already included via spring-boot-starter
.
8. Best Practices
- Prefer constructor injection: Clearer and better for testing
- Use
@Inject
for portability: Especially in reusable libraries - Use
@Named
with@Inject
carefully: It’s equivalent to@Qualifier
, but less powerful - Avoid mixing
@Inject
and@Autowired
unless there’s a specific reason - Stick to one style across your codebase for consistency