Loading

注入依赖的常见方式

注入依赖除了使用 @Autowired ,还有哪些地方可以用到

在 Spring 框架中,除了 @Autowired 注解,还有多种依赖注入方式可供选择,这些方式在代码可维护性、灵活性和规范性上各有优势。以下是具体的替代方案及其应用场景:


一、构造函数注入(Constructor Injection)

实现方式:通过类的构造函数声明依赖项,Spring 自动注入对应的 Bean。
优点

  1. 依赖不可变性:强制依赖项在对象创建时必须注入,支持 final 字段,避免空指针异常。
  2. 明确依赖关系:构造函数清晰地展示类所需的依赖,提升可读性和可测试性。
  3. 避免循环依赖:Spring 在启动时检测循环依赖并抛出异常,而非运行时。
    代码示例
@Service
public class UserService {
    private final UserRepository userRepository;

    // Spring 4.3+ 可省略 @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

Lombok 简化:使用 @RequiredArgsConstructor 自动生成构造函数:

@RequiredArgsConstructor
@Service
public class UserService {
    private final UserRepository userRepository;
}

二、Setter 方法注入(Setter Injection)

实现方式:通过 Setter 方法注入依赖项,通常配合 @Autowired(或其他注解)使用。
适用场景

  • 可选依赖:依赖项非必需,可通过 @Autowired(required = false) 设置。
  • 动态更新依赖:允许运行时重新注入不同的实现。
    代码示例
@Service
public class PaymentService {
    private PaymentGateway paymentGateway;

    @Autowired
    public void setPaymentGateway(PaymentGateway paymentGateway) {
        this.paymentGateway = paymentGateway;
    }
}

三、其他标准注解

1. @Resource(JSR-250)

  • 按名称注入:默认根据字段名或 name 属性匹配 Bean,类型不匹配时按类型回退。
  • 无依赖:属于 Java EE 标准,无需额外依赖。
@Component
public class OrderService {
    @Resource(name = "mysqlOrderRepo")
    private OrderRepository orderRepository;
}

2. @Inject(JSR-330)

  • @Autowired 类似:按类型注入,但无 required 属性。
  • 需引入依赖:需添加 javax.inject 包。
@Inject
private Logger logger;

四、隐式参数注入(Java Config)

@Configuration 类中,通过 @Bean 方法的参数自动注入依赖,无需显式注解:

@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource(Environment env) {
        // 参数 env 自动注入
        return new HikariDataSource(...);
    }
}

五、@Qualifier 精确注入

解决歧义:当存在多个同类型 Bean 时,通过名称或自定义限定符明确指定目标 Bean:

@Service
public class ReportService {
    private final DataSource primaryDataSource;

    public ReportService(@Qualifier("primaryDataSource") DataSource dataSource) {
        this.primaryDataSource = dataSource;
    }
}

六、模块化配置与自动装配

Spring Boot Starter:通过 META-INF/spring.factories@AutoConfiguration 自动注册 Bean,开发者仅需引入依赖即可使用。例如引入 spring-boot-starter-data-jpa 后,DataSourceJpaTemplate 自动配置。


对比总结

方式 优点 缺点 适用场景
构造函数注入 依赖不可变,明确性强 参数较多时代码冗长 必需依赖,推荐默认使用
Setter 注入 支持可选依赖,灵活性高 依赖可变性可能引发问题 可选或需动态更新的依赖
@Resource 按名称注入,标准化 灵活性低于 @Autowired 需精确匹配 Bean 名称时
@Inject 标准化,跨框架兼容性好 required 属性 需要与 Guice 等框架兼容时
隐式参数注入 配置简洁,无需注解 仅适用于 @Configuration 手动配置复杂 Bean 时

最佳实践建议

  1. 优先构造函数注入:强制依赖项声明,提升代码安全性和可维护性。
  2. 慎用字段注入:仅在原型代码或遗留系统中使用,避免隐藏依赖和测试困难。
  3. 结合 Lombok:通过 @RequiredArgsConstructor 减少样板代码,保持代码简洁。
  4. 利用自动装配:通过 Starter 减少手动配置,遵循 Spring Boot 的约定优于配置原则。

通过合理选择依赖注入方式,可以显著提升代码质量,降低维护成本。

posted @ 2025-05-14 17:51  我不想学编丿程  阅读(124)  评论(0)    收藏  举报