Spring中动态Bean注入的核心是将工厂逻辑内化为@Bean方法,通过环境、参数等条件返回不同实现,调用方仅@Autowired接口即可透明获取对应实例。

Spring 中结合工厂模式实现动态 Bean 注入,核心在于把工厂逻辑“内化”为 Spring 容器的 Bean 定义过程,而不是额外写一个工厂类再交给 Spring 管理。这样既能保留工厂的运行时决策能力(比如根据环境、参数、配置选不同实现),又不破坏依赖注入的透明性——调用方仍只需 @Autowired 接口,完全 unaware 工厂存在。
动态 Bean 注入的关键思路
不是让 Bean 去找工厂,而是让工厂逻辑直接变成 Bean 的创建源头。Spring 通过 @Bean 方法天然支持这一模式:方法体里写判断逻辑,返回具体实现,Spring 自动把它注册为接口类型的 Bean。
-
@Bean方法可访问 Spring 环境(Environment)、其他 Bean、配置属性,甚至能注入参数(如@Value、ObjectProvider) - 返回类型是接口(如
PaymentService),Spring 会按类型匹配注入,调用方无感知底层如何生成 - 方法名即 Bean 名(默认),也可用
@Bean("xxx")显式指定
具体实现方式(推荐 Java Config)
@Configuration
public class PaymentConfig {
@Bean
public PaymentService paymentService(Environment env) {
String profile = env.getProperty("spring.profiles.active", "dev");
if ("prod".equals(profile)) {
return new AlipayServiceImpl();
} else if ("test".equals(profile)) {
return new WechatPayMock();
} else {
return new MockPaymentService();
}
}
}此时,任何 @Autowired PaymentService 的地方,都会拿到对应环境下的实例,无需修改业务代码。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
支持更灵活的动态策略
如果需要根据运行时参数(比如用户等级、订单金额)选实现,可用 ObjectProvider 或 ObjectFactory 延迟获取:
@Service
public class OrderService {
private final ObjectProvider<PaymentStrategy> strategyProvider;
public OrderService(ObjectProvider<PaymentStrategy> strategyProvider) {
this.strategyProvider = strategyProvider;
}
public void process(Order order) {
PaymentStrategy strategy = strategyProvider.getObject(order.getLevel());
strategy.pay(order);
}
}配合 @Bean 方法中做多态路由,就能实现“一次定义,按需分发”。
注意事项
- 避免在
@Bean方法里做重资源初始化(如数据库连接),应封装到 Bean 内部生命周期中 - 条件逻辑尽量轻量,复杂分支建议提取为独立策略类,再由工厂方法组装
- 若多个地方需相同动态逻辑,可抽成
@ConfigurationProperties+@Bean组合,提升复用性
不复杂但容易忽略。

















