Заводская модель с использованием пружины
Как выбрать реализацию службы в зависимости от параметра запроса на SpringBoot? Я могу сделать это путем создания экземпляра службы вручную, но при этом не используется функция Spring Injection. Я также могу автоматически связать два сервиса по отдельности, но я думаю, что если у меня будет больше реализаций, которые будут загрязнять класс.
Вот грубый пример:
@RestController
class RestControllerTest {
@Autowired
PizzaService pizzaService;
public void bakePizza(@RequestParam("type") String type,@RequestParam("extra") String extra) {
if (type.equals("cheese")) {
//set pizzaService Cheese Implementation
pizzaService = new CheezePizza();
} else {
//set PizzaService vegetable Impleentation;
pizzaService = new VegetablePizza();
}
pizzaService.prepareIngredients(extra);
pizzaService.bakePizza();
}
}
public abstract class PizzaService {
String ingredients;
public abstract void prepareIngredients(String exraIngredient);
public void bakePizza() {
System.out.println("baking pizza with " + ingredients);
}
}
class CheezePizza extends PizzaService {
@Override
public void prepareIngredients(String exraIngredient) {
ingredients = "Cheese " + exraIngredient;
}
}
class VegetablePizza extends PizzaService {
@Override
public void prepareIngredients(String exraIngredient) {
ingredients = "Vegetable " + exraIngredient;
}
}
1 ответ
Вы можете автоматически связать список бинов одного типа. Так скажем, вы добавляете getType()
на ваш PizzaService
и зарегистрируйте каждый тип как боб весны.
public abstract class PizzaService {
abstract String getType();
}
@Component
class CheezePizza extends PizzaService {
@Override
public String getType() {
return "cheese";
}
}
@Component
class VegetablePizza extends PizzaService {
@Override
public String getType() {
return "vegetable";
}
}
@RestController
class RestControllerTest {
private final Map<String, PizzaService> pizzaServices;
public RestControllerTest(List<PizzaService> services) {
pizzaServices = services.stream().collect(Collectors.toMap(PizzaService::getType, Function.identity()));
}
public void bakePizza(@RequestParam("type") String type, @RequestParam("extra") String extra) {
PizzaService pizzaService = pizzaServices.get(type); // remember of handling missing type
pizzaService.prepareIngredients(extra);
pizzaService.bakePizza();
}
}
Другой способ заключается в использовании названия ваших бобов по соглашению, т.е. cheesePizza
, vegetablePizza
а затем использовать ApplicationContext#getBean(type + "Pizza")
но мне больше нравится первый подход, потому что он менее волшебный.