在spring项目中,@Resource private List<IGoodsActuator> goodsActuators , goodsActuators 是 什么时候初始化的

在 Spring 项目中,当你这样声明:

@Resource
private List<IGoodsActuator> goodsActuators;

这个 goodsActuators 字段的初始化(即注入)发生在 Spring 容器创建该 Bean 的依赖注入阶段(population phase),具体来说是在 Bean 实例化之后、初始化回调(如 @PostConstruct)之前


📌 详细时机说明(Bean 生命周期视角)

假设你有一个被 Spring 管理的组件类:

@Service
public class GoodsService {

    @Resource
    private List<IGoodsActuator> goodsActuators;

    @PostConstruct
    public void init() {
        // 此时 goodsActuators 已经被注入
        System.out.println("Size: " + goodsActuators.size());
    }
}

Spring 创建 GoodsService Bean 的流程如下:

  1. 实例化:调用 GoodsService 的构造函数,创建对象(此时字段仍为 null)。
  2. 依赖注入(DI)
    • Spring 扫描所有字段和 setter 方法;
    • 发现 @Resource private List<IGoodsActuator> goodsActuators
    • 查找容器中所有类型为 IGoodsActuator 的 Bean(包括其实现类,如 DiscountActuator, StockActuator 等);
    • 将这些 Bean 组装成一个 List,并注入到 goodsActuators 字段中。
  3. 初始化回调
    • 调用 @PostConstruct 标注的方法(如 init());
    • 此时 goodsActuators 已经完成注入,可以安全使用

✅ 因此:goodsActuators@PostConstruct 方法执行前就已经初始化完毕。


🔍 关键行为细节

1. 自动收集所有匹配的 Bean

Spring 对 List<T> 类型的注入有特殊处理:

  • 不管你用的是 @Resource 还是 @Autowired
  • 只要字段类型是 List<SomeInterface>
  • Spring 就会自动将容器中 所有实现了 SomeInterface 的 Bean 注入到该列表中。

⚠️ 注意:虽然 @Resource 按 JSR-250 规范本应“按名称注入”,但 Spring 对集合类型(List/Map)做了扩展,此时它会忽略名称,转而按类型收集所有匹配 Bean。

2. 空列表而非 null

  • 如果没有 IGoodsActuator 的实现类被注册为 Bean,goodsActuators 会被注入为一个 空的 ArrayList不会是 null
  • 这避免了空指针异常(NPE),是 Spring 的安全设计。

3. 顺序可控

  • 默认顺序是 Bean 的注册顺序;
  • 可通过 @Order 注解或实现 Ordered 接口控制执行顺序:
    @Component
    @Order(1)
    public class FirstActuator implements IGoodsActuator { ... }
    

✅ 验证示例

@Component
public class A implements IGoodsActuator { }

@Component
public class B implements IGoodsActuator { }

@Service
public class MyService {
    @Resource
    private List<IGoodsActuator> goodsActuators; // 包含 A 和 B

    @PostConstruct
    public void check() {
        // 输出:2
        System.out.println(goodsActuators.size());
    }
}

🆚 与 @Autowired 的区别?

对于 List<T> 注入,在 Spring 中 @Resource@Autowired 行为几乎一致

@Autowired
private List<IGoodsActuator> goodsActuators; // 效果相同

因为 Spring 在解析集合类型时,会统一走“按类型收集所有 Bean”的逻辑,不再区分注解语义。


✅ 总结

问题 答案
何时初始化? 在当前 Bean 的 依赖注入阶段,早于 @PostConstruct
注入内容? 容器中所有 IGoodsActuator 类型的 Bean(实现类)。
为空怎么办? 注入空 List,永不为 null
顺序是否确定? 默认按注册顺序,可用 @Order 控制。
@Resource 是否按名注入? ❌ 对 List<T>,Spring 忽略名称,按类型自动收集。

💡 最佳实践:在 @PostConstruct 或业务方法中使用 goodsActuators 是安全的,无需判空(除非业务逻辑需要)。

posted @ 2025-11-11 09:02  chuangzhou  阅读(2)  评论(0)    收藏  举报