Java 是否可以根据@Autowire的路径变量来决定使用哪个bean?

Java 是否可以根据@Autowire的路径变量来决定使用哪个bean?,java,spring,spring-boot,Java,Spring,Spring Boot,这些天我一直在玩Spring,在HTTP请求生命周期中,我一直在尝试自动连接bean 我有一个名为Animal的接口和两个实现,Dog和Cat,如下所示: Animal.java 公共界面动物{ 公共弦乐; } Dog.java 公营狗具动物{ @凌驾 公共弦音{回音呜呜!;} } Cat.java 公营猫科动物{ @凌驾 公共字符串声音{返回喵喵…:3;} } 我的控制器如下所示: AnimalController.java @RestController @RequestMappingval

这些天我一直在玩Spring,在HTTP请求生命周期中,我一直在尝试自动连接bean

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

Animal.java

公共界面动物{ 公共弦乐; } Dog.java

公营狗具动物{ @凌驾 公共弦音{回音呜呜!;} } Cat.java

公营猫科动物{ @凌驾 公共字符串声音{返回喵喵…:3;} } 我的控制器如下所示:

AnimalController.java

@RestController @RequestMappingvalue=/animal 公共级动物控制员{ 私人最终动物服务动物服务; @自动连线 公共动物控制服务{ 动物服务=服务; } @GetMappingvalue=/{animal}/sound 公共字符串animalSound@PathVariable弦乐动物{ 返回animalService.doSound; } } AnimalService.java此处我无法自动连接我的动物:

@服务 公共级动物服务{ /* 我的IDE提示: '无法自动连线。存在多个'Animal'类型的bean。' */ @自动连线 私人动物; 公共字符串文件{ 返回动物声音; } } } 此外:

Configuration.java

@配置 公共类配置{ @豆子 公犬{ 归还新狗; } @豆子 公猫{ 归还新猫; } }
是否有可能根据路径变量决定使用哪个bean?我试着阅读Spring的核心文档,但我理解不了太多。非常感谢您的帮助。

您可以使用spring.profiles.active来完成此操作。一个侧面加载狗,另一个加载猫

  @Configuration
public class Configuration {

@Profile("dog")
  @Bean
  public Dog createDog() {
    return new Dog();
  }

@Profile("cat")
  @Bean
  public Cat createCat() {
    return new Cat();
  }
}
你可以像java-jarmyapp.jar-spring.profiles.active=dog那样启动你的应用程序

您可以尝试的另一个选项是限定bean并使用带有属性变量的限定符,spring可能会解析它

@Service
public class AnimalService {

  @Qualifier("${choosen.animal}")
  @Autowired
  private Animal animal; 

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


您可以使用spring.profiles.active来执行此操作。一个侧面加载狗,另一个加载猫

  @Configuration
public class Configuration {

@Profile("dog")
  @Bean
  public Dog createDog() {
    return new Dog();
  }

@Profile("cat")
  @Bean
  public Cat createCat() {
    return new Cat();
  }
}
你可以像java-jarmyapp.jar-spring.profiles.active=dog那样启动你的应用程序

您可以尝试的另一个选项是限定bean并使用带有属性变量的限定符,spring可能会解析它

@Service
public class AnimalService {

  @Qualifier("${choosen.animal}")
  @Autowired
  private Animal animal; 

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


您可以通过创建一个列表来实例化Animal类型的所有bean。 例:

这将自动连接所有动物,你可以通过迭代来决定你需要哪一个


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

您可以通过将所有Bean类型的Bean创建一个列表来实例化它们。 例:

这将自动连接所有动物,你可以通过迭代来决定你需要哪一个


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

通过beanName从容器中获取动物豆

@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(animal);
  }

} 
AnimalService.java

public class AnimalService implements ApplicationContextAware {

private ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
}


public String doSound(String animalName) {
    Animal animal = applicationContext.getBean(animalName);
return animal.sound();
 }

}

用豆名从容器中取出动物豆

@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(animal);
  }

} 
AnimalService.java

public class AnimalService implements ApplicationContextAware {

private ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
}


public String doSound(String animalName) {
    Animal animal = applicationContext.getBean(animalName);
return animal.sound();
 }

}

关键的是,我想在某人执行以下请求时决定使用哪个bean:GET/animal/{animal}/sound decising with The animal path变量。关键的是我想在某人执行以下请求时决定使用哪个bean:GET/animal/{animal}/声音由动物路径变量决定。我正在考虑它。我以前的解决方案是由供应商决定使用哪种动物,但有人让我尝试使用Spring IoC。我想在这种情况下我做不到。请注意:我错过了,但@jin在他的回答中已经涵盖了这一点。如果你不需要工厂,只需要一个特定的bean,通过它的类或名称,你可以从ApplicationContext分别通过它们的名称或类型来获取bean。我以前的解决方案是由供应商决定使用哪种动物,但有人让我尝试使用Spring IoC。我想在这种情况下我做不到。请注意:我错过了,但@jin在他的回答中已经涵盖了这一点。如果您不需要工厂,只需要使用某个bean的类或名称,那么可以分别通过名称或类型从ApplicationContext获取bean