使用 spring 的工厂模式
factory pattern using spring
如何根据 SpringBoot 上的请求参数选择服务实现?我可以通过手动实例化服务来做到这一点,但这并没有利用 Spring 注入功能。
我也可以分别自动装配这两个服务,但我想如果我有更多的实现会污染 class.
这是一个粗略的例子:
@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;
}
}
您可以自动装配相同类型的 beans 列表。因此,假设您将 getType()
添加到 PizzaService
并将每种类型注册为 spring bean。
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();
}
}
另一种方法是按照约定使用您的 bean 名称,即 cheesePizza
、vegetablePizza
,然后使用 ApplicationContext#getBean(type + "Pizza")
,但我更喜欢第一种方法,因为它不那么神奇。
如何根据 SpringBoot 上的请求参数选择服务实现?我可以通过手动实例化服务来做到这一点,但这并没有利用 Spring 注入功能。 我也可以分别自动装配这两个服务,但我想如果我有更多的实现会污染 class.
这是一个粗略的例子:
@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;
}
}
您可以自动装配相同类型的 beans 列表。因此,假设您将 getType()
添加到 PizzaService
并将每种类型注册为 spring bean。
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();
}
}
另一种方法是按照约定使用您的 bean 名称,即 cheesePizza
、vegetablePizza
,然后使用 ApplicationContext#getBean(type + "Pizza")
,但我更喜欢第一种方法,因为它不那么神奇。