Spring Boot中泛型场景下如何注入同一类型的多个实现类?
解决Spring Boot多RssConsumer导致RssStrategy注入冲突的方案
问题根源:RssStrategy被标记为@Component后,Spring会尝试自动创建实例,但它的构造器依赖RssConsumer的实现类,而容器中存在多个RssConsumer Bean,Spring无法确定要注入哪一个,从而抛出"找到多个同类型Bean"的错误。同时你的场景需要由注入RssStrategy的服务来决定使用哪个RssConsumer实现,因此不能直接在RssStrategy上固定指定@Qualifier。
下面给出最直接可行的解决方法:
方法:手动注册对应泛型的RssStrategy Bean
1. 移除RssStrategy类上的@Component注解
因为我们要为每个RssConsumer实现手动创建绑定的RssStrategy实例,不需要Spring自动扫描生成:
public class RssStrategy<T extends RssConsumer> implements FetchDataStrategy{ private final T rssConsumer; public RssStrategy(T rssConsumer) { this.rssConsumer = rssConsumer; } @Override public void fetchData() { rssConsumer.consume(); } }
2. 创建配置类,注册不同泛型的RssStrategy Bean
新建一个配置类,为每个RssConsumer实现定义对应的RssStrategy Bean,确保每个Bean绑定唯一的RssConsumer实现:
@Configuration public class RssConfig { // 绑定RssConsumerA的RssStrategy实例 @Bean("rssStrategyA") public RssStrategy<RssConsumerA> rssStrategyA(RssConsumerA rssConsumerA) { return new RssStrategy<>(rssConsumerA); } // 绑定RssConsumerB的RssStrategy实例 @Bean("rssStrategyB") public RssStrategy<RssConsumerB> rssStrategyB(RssConsumerB rssConsumerB) { return new RssStrategy<>(rssConsumerB); } // 如有更多RssConsumer实现,按相同方式添加对应的Bean定义即可 }
3. 在服务中通过@Qualifier指定要注入的RssStrategy
在ServiceA和ServiceB的构造器中,使用@Qualifier注解指定对应的RssStrategy Bean名称,确保注入的是绑定了目标RssConsumer的实例:
@Service public class ServiceA extends MyAbstractService { public ServiceA(@Qualifier("rssStrategyA") RssStrategy<RssConsumerA> fetchDataStrategy) {} @Override public void run() { fetchDataStrategy.fetchData(); } } @Service public class ServiceB extends MyAbstractService { public ServiceB(@Qualifier("rssStrategyB") RssStrategy<RssConsumerB> fetchDataStrategy) {} @Override public void run() { fetchDataStrategy.fetchData(); } }
这种方式能明确控制每个RssStrategy实例对应的RssConsumer实现,完全避免了Spring随机选择Bean的问题,同时满足不同服务使用不同策略的需求。
内容的提问来源于stack exchange,提问作者M4V3N
相关产品推荐
相关产品推荐

