Learnitweb

@Inject Annotation in Spring Boot

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
OriginJSR-330 (javax.inject.Inject)Spring-specific
Required DependencyAlways required (no required flag)Has required flag (optional deps)
Default behaviorInject by typeInject by type
Support for QualifiersYes, with @NamedYes, with @Qualifier
Preferred in…Framework-independent codeSpring-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