Spring依赖注入中多态的核心体现是通过接口或抽象类声明依赖,实际注入多个实现类Bean,支持List/Map批量注入、@Qualifier或自定义注解精准选择,实现零成本替换、无侵入扩展与彻底解耦。

多态在 Spring 的依赖注入中,核心体现是用接口或抽象类声明依赖,而实际注入的是多个不同实现类的 Bean。Spring 容器不关心具体实现,只按类型(或带限定条件)匹配并注入,让业务代码完全面向抽象编程。
接口定义 + 多个实现类注入
这是最典型的应用方式。比如定义一个支付服务接口:
public interface PaymentService {
void pay(Order order);
String getChannel();
}
再提供微信、支付宝、银联等不同实现:
@Service
public class WechatPaymentServiceImpl implements PaymentService { ... }
@Service
public class AlipayPaymentServiceImpl implements PaymentService { ... }
@Service
public class UnionPayPaymentServiceImpl implements PaymentService { ... }
在业务类中,直接按接口类型注入:
立即学习“Java免费学习笔记(深入)”;
@Service
public class OrderService {
@Autowired
private PaymentService paymentService; // 注入哪个?Spring 自动选一个(默认按类型找单个)
}
此时 Spring 会报错——因为存在多个 PaymentService 实现。这就引出下一种更实用的方式。
通过 List 或 Map 批量注入实现类
当需要同时使用多个实现时,Spring 支持按类型收集所有匹配 Bean:
-
@Autowired private List<paymentservice> paymentServices;</paymentservice>→ 注入全部实现,顺序由注册先后或@Order控制 -
@Autowired private Map<string paymentservice> paymentServiceMap;</string>→ Key 默认为 Bean 名(如wechatPaymentServiceImpl),也可配合自定义注解统一提取标识(如getChannel()返回值)
这样就能在运行时根据订单渠道动态选择:
public void process(Order order) {
String channel = order.getChannel();
PaymentService service = paymentServiceMap.get(channel.toLowerCase() + "PaymentService");
if (service != null) {
service.pay(order);
}
}
结合 @Qualifier 或自定义限定注解精准选择
避免硬编码字符串,推荐用自定义注解提升可维护性:
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface PaymentChannel {
String value();
}
@Service
@PaymentChannel("wechat")
public class WechatPaymentServiceImpl implements PaymentService { ... }
注入时指定:
@Autowired
@PaymentChannel("alipay")
private PaymentService paymentService;
再配合 GenericBeanDefinition 或配置类,即可实现“声明即扩展”:新增一个支付渠道,只需加实现类+注解,无需改调用逻辑。
多态与 DI 协同带来的实际好处
-
替换零成本:测试时用
MockPaymentService替换真实实现,不改一行业务代码 -
扩展无侵入:接入新银行对账服务,只要实现
BankService接口并注册,调度逻辑不变 -
解耦容器与业务:Controller 只依赖
UserService接口,不管它是 JDBC 实现还是 Redis 缓存增强版


















