Skip to content

Spring 自动装配的方式有哪些? ​

  • 标签:后端、Spring

🏛 业务架构师 ​

Spring 自动装配(依赖注入时找 Bean 的方式)有四种模式,按 @Autowired / XML autowire 语义:

  1. byType(按类型):@Autowired 默认。类型唯一即注入;多个候选时的裁决顺序:@Primary > @Priority > 字段/参数名匹配。最常用,配合面向接口编程;
  2. byName(按名称):@Resource(name 属性)或匹配变量名。适合同一接口多实现的路由场景,如多数据源、多渠道;
  3. constructor(构造器):Spring 4.3+ 单构造器自动注入,现在的主流推荐;
  4. autodetect / no:历史模式,no 即不自动装配,现在基本不用。

业务上真正的高频场景是**"一个接口多个实现怎么注得对"**,我的标准打法:

java
// 策略模式 + Map 注入,key 为 Bean 名称
private final Map<String, PayChannel> channelMap;
// 或 @Qualifier("alipayChannel") 指名注入

Map/List<接口> 注入配合策略模式,是多渠道支付、多租户差异逻辑的黄金组合——新增渠道加一个类,调用侧零修改。

治理提醒:靠 Bean 名称字符串路由(getBean("xxx"))是弱契约,重命名即断,且编译期不报错。我的规则:路由 key 显式化——让策略自带 String type() 方法建映射,把字符串魔法收敛到一处,规避静默故障。

🏗 系统架构师 ​

分两个层面回答:

XML 时代(机制层):autowire 属性五种——no(默认)、byName、byType、constructor、autodetect,本质是容器替你完成「找依赖」。

注解时代(现实层):

  • @Autowired:byType 优先,多候选时按名称或注解消歧,可配 @Primary/@Qualifier;
  • @Resource(JSR-250):byName 优先,找不到再 byType;
  • 构造器注入:4.3 起单构造器自动装配,现在的官方推荐。

架构演进判断:显式装配优于容器猜测——依赖关系可静态分析、启动即校验。「自动」在框架层有价值(自动配置是 Spring Boot 的基石),在业务层反倒是模糊依赖的温床:同类型多实现没有显式消歧,换个扫描顺序行为就变,这类问题在生产极难排查。我的规约:多实现出现即必须补 Primary/Qualifier 与装配冒烟测试。

💻 全栈开发专家 ​

两层含义都答:

传统 XML 时代的 autowire:byName(按属性名找 Bean)、byType(按类型,多候选报错)、constructor、no(默认)。现在基本淘汰,但面试官可能想听这个。

注解时代(现在的默认语境):

  • @Autowired:Spring 提供,先 byType,多候选时按字段名/参数名收敛,再看 @Primary/@Qualifier
  • @Resource:JSR-250 标准,先 byName 找不到再 byType
  • @Inject:JSR-330,语义同 @Autowired
  • 构造器注入:单构造器免注解自动装配

多实现冲突的标准解法:

java
@Service
@Primary                        // 默认首选
public class AlipayService implements PayService { }

@Service("wechatPay")
public class WechatPayService implements PayService { }

// 注入方
@Autowired
@Qualifier("wechatPay")         // 指名道姓
private PayService payService;

我更推荐无注解的策略路由:注入 Map<String, PayService>(key 是 Bean 名),运行时按渠道码取实现,新增渠道零改动——比散落各处的 @Qualifier 好维护。