私が春を使用しているとしましょう、私は以下の戦略を持っています...
インターフェース
public interface MealStrategy {
cook(Meat meat);
}
最初の戦略
@Component
public class BurgerStrategy implements
MealStrategy {
@Autowired CookerDao cookeryDao;
@Override
public void cook(Meat meat) {
cookeryDao.getBurger(meat);
}
}
次の戦略...
@Component
public class SausageStrategy implements
MealStrategy {
@Autowired CookerDao cookeryDao;
@Override
public cook(Meat meat) {
return cookeryDao.getSausage(meat);
}
}
環境...
@Component
@Scope("prototype")
public class MealContext {
private MealStrategy mealStrategy;
public void setMealStrategy(MealStrategy strategy) {
this.strategy = strategy;
}
public void cookMeal(Meat meat) {
mealStrategy.cook;
}
}
次に、このコンテキストがmvcコントローラーを介してアクセスされていたとします。
@Autowired
private MealContext mealContext;
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Something makeMeal(Meat meat) {
mealContext.setMealStrategy(new BurgerStrategy())
mealContext.cookMeal(meat);
}
コンテキストはコンポーネントである必要がありますか?そうすると、loadOnStartupと言うエラーが表示されます。予想通り、この戦略にはnonUniqueBeanがあります。すべてのBeanは上記のようなコンポーネントである必要がありますか、それとも注釈が正しくありませんか?
私の最大のクエリは本当に、Spring MVCアプリでそのようなコンテキストを使用できるかどうかです。 @Scope(prototype)を使用する際の問題も、Daoが挿入されないため、戦略のcookeryDao呼び出しがnullポインターを返すことを意味します。
スプリングを使用して上記のパターンをどのように実装し、スレッドセーフにすることができますか?私がやろうとしていることは可能ですか?
単純な依存性注入を使用します。
@Component("burger")
public class BurgerStrategy implements MealStrategy { ... }
@Component("sausage")
public class SausageStrategy implements MealStrategy { ... }
コントローラ
オプションA:
@Resource(name = "burger")
MealStrategy burger;
@Resource(name = "sausage")
MealStrategy sausage;
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Something makeMeal(Meat meat) {
burger.cookMeal(meat);
}
オプションB:
@Autowired
BeanFactory bf;
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Something makeMeal(Meat meat) {
bf.getBean("burger", MealStrategy.class).cookMeal(meat);
}
コンパイル時にスペルミスを検出するために、テキスト名の代わりにJSR-330修飾子を作成することを選択できます。
以下も参照してください。
具体的な戦略は、提供されたパラメータなどに基づいて実行時に決定されることが非常に多いため、次のように提案します。
@Component
public class BurgerStrategy implements MealStrategy { ... }
@Component
public class SausageStrategy implements MealStrategy { ... }
次に、そのような戦略をすべて、指定されたコントローラーのマップ(Bean名をキーとして)に挿入し、要求に応じてそれぞれの戦略を選択します。
@Autowired
Map<String, MealStrategy> mealStrategies = new HashMap<>;
@RequestMapping(method=RequestMethod.POST)
public @ResponseBody Something makeMeal(@RequestParam(value="mealStrategyId") String mealStrategyId, Meat meat) {
mealStrategies.get(mealStrategyId).cook(meat);
...
}