2013-07-13 144 views
12

说我使用的是春天,我有以下策略......策略模式

接口

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

Cont转...

@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(原型)时遇到的问题是,这意味着cookeryDao调用策略会返回一个空指针,因为Dao不会被注入。

我将如何使用弹簧实现上述模式并且线程安全?我正在尝试什么?

+0

什么是你的问题?所有这一切对我有用 – morgano

+0

我想知道是否线程安全有一个像我已经完成的上下文 – david99world

+0

上述也不会工作,因为我已经做了'新'这是在春天的上下文之外? – david99world

回答

16

我会用简单的依赖注入。

@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预选赛,而不是文本名称赶上编译过程中的拼写错误时间。

参见:

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 { ... } 

然后注入所有这样的策略成在给定的控制装置的图(与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); 

    ... 
} 
+1

这个答案给出了一个更加真实的战略实施模式 – Cuga