spring boot 中实现条件分支工厂应避免手写 if-else 工厂,而是通过 @conditionalonproperty 实现配置驱动装配、map 键控自动注入、或自定义 condition 处理复杂逻辑,确保所有 bean 由 spring 管理以支持依赖注入与 aop。

Spring Boot 中实现“条件分支工厂注入不同服务”,核心不是写 if-else 工厂类,而是让 Spring 容器自己按需装配——把选择权交给配置和条件注解,而不是运行时手动判断。
用 @ConditionalOnProperty 实现配置驱动的服务切换
这是最轻量、最推荐的方式。你只需在每个实现类上加一个注解,指定配置项和期望值,Spring 启动时自动注册匹配的 Bean。
- 在 application.properties 中定义开关:
person.service.impl=file或person.service.impl=db - 两个实现类分别标注:
@Service @ConditionalOnProperty(name = "person.service.impl", havingValue = "file")@Service @ConditionalOnProperty(name = "person.service.impl", havingValue = "db") - 接口类型变量直接注入即可,Spring 保证容器里只有一个符合条件的实现:
@Autowired private IPersonService personService;
用 Map 实现键控自动装配
当你需要根据字符串(如任务类型、渠道编码)动态获取不同实现时,Spring 原生支持 Map 注入:容器会把所有该接口的实现类,以 @Service("key") 中的 key 为键,自动组装进 Map。
- 实现类加命名:
@Service("alipay") public class AlipayService implements PaymentService - 工厂类中声明:
@Autowired private Map<string paymentservice> paymentServiceMap;</string> - 使用时按需取:
PaymentService service = paymentServiceMap.get("alipay");
如果 key 不存在,返回 null;建议配合@ConditionalOnMissingBean提供默认兜底实现
自定义 Condition 实现复杂逻辑判断
当配置项之间存在组合关系(比如“仅在 prod 环境且启用缓存时才加载 RedisService”),内置注解不够用,可写自定义 Condition 类。
- 实现
Condition接口,重写matches()方法,从ConditionContext中读取环境、配置、类路径等上下文信息 - 在 Bean 上使用
@Conditional(YourCustomCondition.class) - 例如:检查
app.env=prod且cache.enabled=true同时成立才注册某个服务
避免传统 if-else 工厂的几个关键点
手写工厂类(比如用 switch 判断类型再 return new XxxService())在 Spring 环境下容易出问题:
- new 出来的对象不受 Spring 管理,其内部
@Autowired的依赖会是 null - 无法享受 AOP(事务、日志等切面失效)
- 破坏了 IoC 原则,耦合度高,测试困难
- 正确做法是:所有服务都交由 Spring 创建和管理,工厂只做“查找”(比如从 Map 或 ApplicationContext 中 getBean),不负责“构造”











