Заводская модель с использованием пружины

Как выбрать реализацию службы в зависимости от параметра запроса на 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") но мне больше нравится первый подход, потому что он менее волшебный.

Другие вопросы по тегам