2013-07-13 4 views
12

Say Я использую весной, у меня есть следующие стратегии ...шаблона стратегии с пружинной фасолью

Интерфейс

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, что стратегия может быть, как и следовало ожидать. Должны ли все бобы быть такими компонентами, как указано выше, или мои аннотации неверны?

Мой самый большой запрос: вы можете использовать такой контекст в приложении Spring MVC? Проблема, которую я испытываю при использовании @Scope (прототип), также означает, что вызовы cookeryDao в стратегиях возвращают нулевой указатель, поскольку Дао не вводятся.

Как бы реализовать описанную выше модель с использованием пружины, а также быть безопасной в потоковом режиме? Является ли то, что я пытаюсь даже сделать возможным?

+0

В чем проблема? все это работает для меня – morgano

+0

Я хочу знать, если это потокобезопасно, чтобы иметь такой контекст, как я сделал – david99world

+0

, также это не сработало, потому что, поскольку я сделал «новый», это вне контекста Spring? – david99world

ответ

16

Я бы использовал простую инъекцию зависимостей.

@Component("burger") 
public class BurgerStrategy implements MealStrategy { ... } 

@Component("sausage") 
public class SausageStrategy implements MealStrategy { ... } 

Контроллер

Вариант А:

@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 отборочных вместо текстовых имен, чтобы поймать опечатки во время компиляции время.

Смотрите также:

How to efficiently implement a strategy pattern with spring?

@Resource vs @Autowired

20

Поскольку конкретная стратегия очень часто определяется во время выполнения на основе предоставленных параметров или около того, я хотел бы предложить что-то, как следует.

@Component 
public class BurgerStrategy implements MealStrategy { ... } 

@Component 
public class SausageStrategy implements MealStrategy { ... } 

Затем вводят все такие стратегии в карту (с именем боба в качестве ключа) в данном контроллере и выбрать соответствующую стратегию по запросу.

@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); 

    ... 
} 
+1

Этот ответ дает более правильную реализацию шаблона стратегии – Cuga

Смежные вопросы