1 spring dependency-injection factory-method
如何根据 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;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以自动装配相同类型的 bean 列表。因此,假设您添加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();
}
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是按约定使用 ie 命名您的 bean cheesePizza
,vegetablePizza
然后使用ApplicationContext#getBean(type + "Pizza")
但我更喜欢第一种方法,因为它不那么神奇。
归档时间: |
|
查看次数: |
4674 次 |
最近记录: |