如何在不将其作为方法参数传递的情况下向 POJO class 提供转换器服务
How to provide converter service to POJO class without passing it as method argument
我有 ShoppingList
服务负责生成购物清单,还有一个 IngredientConverter
服务是转换对象的帮助工具。我当前的实现如下所示
@Service
@AllArgsConstructor
public class ShoppingListService {
private final RecipeService recipeService;
private final IngredientConverter ingredientConverter;
public ShoppingList generateShoppingList(List<UUID> uuidsOfRecipes) {
List<Recipe> recipes = recipeService.getAllByIDIn(uuidsOfRecipes);
ShoppingList shoppingList = ShoppingList.empty();
for (Recipe recipe : recipes) {
shoppingList.addIngredients(recipe.getIngredients());
}
shoppingList.finishAddition(ingredientConverter);
return shoppingList;
}
}
@RequiredArgsConstructor
public class ShoppingList {
@Getter
private final List<IngredientQuantity> optimizedList;
private final Map<Ingredient, Integer> ingredientAmountMap;
public static ShoppingList empty() {
return new ShoppingList(new ArrayList<>(), new HashMap<>());
}
public void addIngredients(List<IngredientQuantity> ingredients) { ... }
public void addIngredient(IngredientQuantity ingredientQuantity) { ... }
public void finishAddition(IngredientConverter ingredientConverter) {
for (Ingredient ingredient : ingredientAmountMap.keySet()) {
IngredientQuantity ingredientQuantity = ingredientConverter.convertWithAmount(
ingredient.getName(),
ingredientAmountMap.get(ingredient),
ingredient.getUnit());
optimizedList.add(ingredientQuantity);
}
}
}
@Service
public class IngredientConverter {
public IngredientQuantity convertWithAmount(String name, int amount, Unit unit) { ... }
}
是否有更好的策略为这个 class 提供 IngredientConverter
服务?尽管 ShoppingList
是 POJO class,我能以某种方式自动装配它吗? ShoppingList
是否应该标记为组件?不确定什么是最好的方法。
您不能将服务 class 自动装配到 POJO 中。 Autowire 只能在 spring 托管 classes 内完成。我可以看到 ShoppingList 不是 spring 管理的 class。添加 @Component 也不是理想的解决方案。 AFAIK,此处使用的最佳解决方案是 mapStruct。 mapStruct 可用于在实体和 POJO 之间映射字段。如果任何字段必须单独计算,您可以编写自定义逻辑和自动装配服务。以下是步骤
- 将 mapStruct 库添加到 pom.xml
- 将下面的映射器 class 添加到您的项目中。 componentModel="spring" 告诉系统这个映射器由 spring.
管理
- 将自动映射所有具有相同名称的字段。
- 对于需要转换的字段,可以写@BeforeMapping
Mapper(componentModel="spring")
public abstract class ShoppingListMapper
{
@Autowired
IngredientConverter ingredientConverter; //autowire method you use.
public abstract shoppingListToShoppingListDTO(ShoppingList shoppingList) throws Exception;
public abstract List<ShoppingList> mapShoppingListsToDTOs(List<ShoppingList> shoppingLists) throws Exception;
@BeforeMapping
public void convertLogic(ShoppingList la, @MappingTarget ShoppingListDTO slDto) throws Exception
{
//your logic to set required shoppinglist field using converter
}
}
如果这个例子不清楚,可以参考web各种mapstruct的例子。如果您需要进一步的帮助,请告诉我
我有 ShoppingList
服务负责生成购物清单,还有一个 IngredientConverter
服务是转换对象的帮助工具。我当前的实现如下所示
@Service
@AllArgsConstructor
public class ShoppingListService {
private final RecipeService recipeService;
private final IngredientConverter ingredientConverter;
public ShoppingList generateShoppingList(List<UUID> uuidsOfRecipes) {
List<Recipe> recipes = recipeService.getAllByIDIn(uuidsOfRecipes);
ShoppingList shoppingList = ShoppingList.empty();
for (Recipe recipe : recipes) {
shoppingList.addIngredients(recipe.getIngredients());
}
shoppingList.finishAddition(ingredientConverter);
return shoppingList;
}
}
@RequiredArgsConstructor
public class ShoppingList {
@Getter
private final List<IngredientQuantity> optimizedList;
private final Map<Ingredient, Integer> ingredientAmountMap;
public static ShoppingList empty() {
return new ShoppingList(new ArrayList<>(), new HashMap<>());
}
public void addIngredients(List<IngredientQuantity> ingredients) { ... }
public void addIngredient(IngredientQuantity ingredientQuantity) { ... }
public void finishAddition(IngredientConverter ingredientConverter) {
for (Ingredient ingredient : ingredientAmountMap.keySet()) {
IngredientQuantity ingredientQuantity = ingredientConverter.convertWithAmount(
ingredient.getName(),
ingredientAmountMap.get(ingredient),
ingredient.getUnit());
optimizedList.add(ingredientQuantity);
}
}
}
@Service
public class IngredientConverter {
public IngredientQuantity convertWithAmount(String name, int amount, Unit unit) { ... }
}
是否有更好的策略为这个 class 提供 IngredientConverter
服务?尽管 ShoppingList
是 POJO class,我能以某种方式自动装配它吗? ShoppingList
是否应该标记为组件?不确定什么是最好的方法。
您不能将服务 class 自动装配到 POJO 中。 Autowire 只能在 spring 托管 classes 内完成。我可以看到 ShoppingList 不是 spring 管理的 class。添加 @Component 也不是理想的解决方案。 AFAIK,此处使用的最佳解决方案是 mapStruct。 mapStruct 可用于在实体和 POJO 之间映射字段。如果任何字段必须单独计算,您可以编写自定义逻辑和自动装配服务。以下是步骤
- 将 mapStruct 库添加到 pom.xml
- 将下面的映射器 class 添加到您的项目中。 componentModel="spring" 告诉系统这个映射器由 spring. 管理
- 将自动映射所有具有相同名称的字段。
- 对于需要转换的字段,可以写@BeforeMapping
Mapper(componentModel="spring")
public abstract class ShoppingListMapper
{
@Autowired
IngredientConverter ingredientConverter; //autowire method you use.
public abstract shoppingListToShoppingListDTO(ShoppingList shoppingList) throws Exception;
public abstract List<ShoppingList> mapShoppingListsToDTOs(List<ShoppingList> shoppingLists) throws Exception;
@BeforeMapping
public void convertLogic(ShoppingList la, @MappingTarget ShoppingListDTO slDto) throws Exception
{
//your logic to set required shoppinglist field using converter
}
}
如果这个例子不清楚,可以参考web各种mapstruct的例子。如果您需要进一步的帮助,请告诉我