首页 > 解决方案 > 是否可以根据 @Autowire 的路径变量来决定使用哪个 bean?

问题描述

这些天我在玩 Spring,在 HTTP 请求的生命周期内尝试自动装配 bean 时遇到了困难。

我有一个名为的接口Animal和两个实现,Dog如下Cat所示:

动物.java

public interface Animal {
  public String sound();
}

狗.java

public class Dog implements Animal {
  @Override
  public String sound() {return "Woof!";}
}

猫.java

public class Cat implements Animal {
  @Override
  public String sound() {return "Meow... :3";}
}

我的控制器如下所示:

AnimalController.java _

@RestController
@RequestMapping(value="/animal")
public class AnimalController {
  private final AnimalService animalService;

  @Autowired
  public AnimalController(AnimalService service) {
    animalService = service;
  }

  @GetMapping(value = "/{animal}/sound")
  public String animalSound(@PathVariable String animal) {
    return animalService.doSound();
  }
}

AnimalService.java(在这里我不能自动装配我的动物):

@Service
public class AnimalService {

/* 
 My IDE prompts:  
 'Could not autowire. There is more than one bean of `Animal` type.'
*/
  @Autowired
  private Animal animal; 

  public String doSound() {
    return animal.sound();
  }
}    
}

还:

配置.java

@Configuration
public class Configuration {
  @Bean
  public Dog createDog() {
    return new Dog();
  }

  @Bean
  public Cat createCat() {
    return new Cat();
  }
}

是否可以根据路径变量来决定使用哪个 bean?我尝试阅读Spring的核心文档,但我无法理解太多。我会很感激帮助。

标签: javaspringspring-boot

解决方案


Animal您可以通过使它们成为一个列表来实例化所有类型的 bean 。前任:

@Autowired
List<Animal> animals;

这将自动连接所有动物,您可以遍历它们并以编程方式决定您需要哪一个。

虽然,我可能错了,但对于您的用例,我相信工厂设计模式更适合。您可以创建一个抽象AnimalFactory并自动装配列表中的所有工厂,然后应用某种策略模式以编程方式决定您将使用哪个工厂并返回该类型的新对象。


推荐阅读