跳到正文
Elaine Blog
返回

构造器推断与依赖解析

Spring 生态与源码

依赖解析的核心是:先确定注入点需要什么,再从候选 Bean 中选出唯一结果。候选不唯一时,Spring 不会靠“碰巧的注册顺序”静默选择。

Table of contents

Open Table of contents

运行 Primary 选择实验

TimeGreetingPort下载使用 @Primary 表示同类型候选中的默认实现:

mvn -Dtest=SpringSourceLabTest#springResolvesPrimaryConstructorDependency test

测试上下文注册两个 GreetingPort,容器把带 @Primary 的实现注入 GreetingService

Spring 怎样选择构造器

只有一个构造器时,不需要写 @Autowired。存在多个构造器时,明确标注可注入构造器,或确保选择规则无歧义。为了读者和测试清晰,业务类通常只保留一个表达必需依赖的构造器。

解析每个参数时,Spring考虑类型、泛型、Qualifier、Primary、Fallback、优先级和注入点名称。参数名只应作为最后的消歧义线索,不应代替显式业务语义。

Primary 与 Qualifier 的职责

@Primary 表示全局默认候选;@Qualifier("billing") 表示该注入点需要某个语义分组。若不同调用方需要不同实现,Qualifier 比不断切换 Primary 更清楚。

注入 List<Handler> 会获得全部匹配 Bean,并按 @OrderOrdered 排序。注入 ObjectProvider<T> 可以延迟获取或迭代候选,但不要用它把 Service Locator 模式重新带回核心业务。

Optional 不应隐藏必需配置

Optional<T>ObjectProvider<T>@Autowired(required=false) 适合真正可选的扩展。支付客户端、数据源等必需能力缺失时,应让启动失败,而不是运行到第一笔请求才报空指针。

诊断 NoUniqueBeanDefinitionException 时列出所有候选及其来源配置;诊断 NoSuchBeanDefinitionException 时检查扫描范围、条件装配报告和泛型是否匹配。

下一步

阅读三级缓存能解决什么循环依赖,区分可暴露早期引用的属性循环和无法成立的构造器循环。


分享这篇文章:

上一篇
Bean 生命周期与后置处理器
下一篇
三级缓存能解决什么循环依赖