1. 介绍
@Inject注解是JSR330规范中提供的注解,在@Inject注解中不提供任何属性,可以配合@Qualifier注解使用。
存在多个类型相同的Bean时,通过@Qualifier注解可以明确指定注入哪个Bean。
2. 场景
@Inject注解和@Autowired注解的使用场景基本相同,如果需要将Bean装配到类中的方法、构造方法和字段中,可以使用@Inject注解实现。
3. 源码
@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}
4. Demo
- 构造器注入
import javax.inject.Inject;
public class UserService {
private final UserRepository userRepository;
@Inject
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser(String username) {
userRepository.save(username);
}
}
- Setter方法注入
import javax.inject.Inject;
public class UserService {
private UserRepository userRepository;
@Inject
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser(String username) {
userRepository.save(username);
}
}
- 字段注解
import javax.inject.Inject;
public class UserService {
@Inject
private UserRepository userRepository;
public void registerUser(String username) {
userRepository.save(username);
}
}
- 指定Bean名称
import javax.inject.Inject;
import javax.inject.Named;
public class PaymentService {
private final PaymentGateway paymentGateway;
@Inject
public PaymentService(@Named("creditCardGateway") PaymentGateway paymentGateway) {
this.paymentGateway = paymentGateway;
}
public void processPayment(double amount) {
paymentGateway.charge(amount);
}
}
5. @Inject
&& @Autowired
&& @Resource
@Inject
- 来源: JSR 330 (Dependency Injection for Java)
- 适用范围: 可以在Java EE和CDI(Contexts and Dependency Injection)环境中使用,也可以通过像Google Guice这样的库在独立的应用程序中使用。
- 默认行为: 默认按照类型来注入依赖。如果存在多个相同类型的bean,则需要使用
@Qualifier
或@Named
等限定符来指定具体的bean。
- 生命周期管理: 通常由CDI容器管理bean的生命周期。
@Resource
- 来源: JSR 250 (Common Annotations for the Java Platform)
- 适用范围: 主要用于Java EE环境,尤其是EJB和JPA。
- 默认行为: 默认按照名称来查找资源。如果没有指定名称,它会尝试使用字段名或方法名作为默认名称。如果找不到匹配的名称,则按类型查找。
- 生命周期管理: 通常由应用服务器提供的资源管理器来管理资源的生命周期。
@Autowired
- 来源: Spring Framework
- 适用范围: 专用于Spring框架。
- 默认行为: 默认按照类型来注入依赖。如果存在多个相同类型的bean,则可以使用
@Qualifier
注解来指定具体的bean。如果只有一个构造函数,那么可以省略@Autowired
注解,因为Spring会自动将其视为注入点。
- 生命周期管理: 由Spring IoC容器管理bean的生命周期。
比较总结
- 兼容性:
@Inject
是标准的一部分,因此更通用,可以在多种环境中使用。
@Resource
主要用于Java EE环境。
@Autowired
仅适用于Spring框架。
- 查找策略:
@Inject
默认按类型查找。
@Resource
默认按名称查找,没有找到时再按类型查找。
@Autowired
默认按类型查找,如果有歧义则可以通过@Qualifier
解决。
- 灵活性:
@Inject
和@Autowired
提供了更多的灵活性,尤其是在处理复杂的依赖关系时。
@Resource
更加简单直接,但在某些情况下可能不够灵活。
- 工具支持:
@Inject
得到了广泛的IDE和工具支持。
@Autowired
有强大的Spring生态系统的支持。
@Resource
也有良好的IDE支持,特别是在Java EE项目中。
6. 补充
JSR 175: A Metadata Facility for the Java Programming Language
@Override
:标记方法重写了父类的方法。
@Deprecated
:表示该元素已过时,不建议使用。
@SuppressWarnings
:用于抑制编译器警告。
JSR 305: Annotations for Software Defect Detection
虽然这个JSR最终没有完成,但是它的注解被广泛采用,并且包含在一些库如FindBugs或Checker Framework中:
@Nullable
@Nonnull
@CheckForNull
JSR 308: Annotations on Java Types
允许将注解放置在任何类型使用的地方,而不仅仅是在声明上。这扩展了JSR 175的功能。尽管JSR 308本身并没有引入新的标准注解,但它使得像Checker Framework这样的工具能够创建和使用更复杂的类型注解。
JSR 250: Common Annotations for the Java Platform
@Resource
:用来注入资源,比如DataSource等。
@PostConstruct
:标记一个方法,在依赖注入完成后执行初始化工作。
@PreDestroy
:标记一个方法,在Bean销毁之前执行清理工作。
JSR 330: Dependency Injection for Java
@Inject
:标记构造函数、字段或者方法为需要依赖注入。
@Named
:与@Inject
一起使用,允许通过名称指定bean。
@Qualifier
:用于区分多个相同类型的bean。
@Scope
:定义bean的作用域。
@Singleton
:表示bean是单例的。
JSR 349: Improved Reusability of JSR 330-based Dependency Injection APIs
增强了JSR 330定义的依赖注入API的可重用性,但没有引入新的注解。