Spring中如何为不同实例注入同一接口的不同实现类
如何通过构造器注入为不同Shelter实例注入不同Animal实现类?
你当前的代码中,Shelter被标记为@Repository,默认是单例Bean,所以两次调用getBean(Shelter.class)得到的是同一个实例,无法直接注入不同的Animal实现。要实现一个Shelter用Dog、另一个用Cat的需求,完全可行,下面是两种常用实现方式:
方式一:通过配置类显式定义多个Shelter Bean
保持你的Animal接口及实现类不变,新增一个配置类,在里面分别创建绑定Dog和Cat的Shelter实例:
@Configuration public class ShelterConfig { // 创建绑定Dog的Shelter Bean,指定名称为dogShelter @Bean("dogShelter") public Shelter createDogShelter(Dog dog) { return new Shelter(dog); } // 创建绑定Cat的Shelter Bean,指定名称为catShelter @Bean("catShelter") public Shelter createCatShelter(Cat cat) { return new Shelter(cat); } }
然后修改Main类,通过Bean名称获取不同的实例:
@SpringBootApplication public class Main{ public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Main.class); Shelter dogShelter = context.getBean("dogShelter", Shelter.class); Shelter catShelter = context.getBean("catShelter", Shelter.class); dogShelter.doTheThing(); // 输出:Woof woof catShelter.doTheThing(); // 输出:Meow meow } }
方式二:结合@Qualifier与构造器注入
如果不想完全通过配置类创建Bean,可以给Animal的实现类指定Bean名称,再通过@Qualifier明确注入的实现类:
首先修改Animal实现类的注解,指定Bean名称:
@Component("dogAnimal") public class Dog implements Animal { @Override public void makeSound() { System.out.println("Woof woof"); } } @Component("catAnimal") public class Cat implements Animal { @Override public void makeSound() { System.out.println("Meow meow"); } }
然后在配置类中,通过@Qualifier指定要注入的Animal实例:
@Configuration public class ShelterConfig { @Bean("dogShelter") public Shelter createDogShelter(@Qualifier("dogAnimal") Animal animal) { return new Shelter(animal); } @Bean("catShelter") public Shelter createCatShelter(@Qualifier("catAnimal") Animal animal) { return new Shelter(animal); } }
Main类的调用逻辑和方式一完全一致,通过Bean名称获取对应实例即可。
注意点
- 原代码中
Shelter的@Repository注解可以保留,但此时它会成为一个默认的单例Bean(如果不指定@Primary或@Qualifier,Spring仍会因为Animal有多个实现而报错),建议直接移除Shelter上的@Repository注解,完全通过配置类管理这两个不同的Shelter实例,避免冲突。
内容的提问来源于stack exchange,提问作者jakub_k
相关产品推荐
相关产品推荐

