弹簧控制器中的策略模式

时间:2017-09-28 13:06:29

标签: spring spring-mvc spring-boot

在Spring启动应用程序中,在我的一个控制器中,我使用策略模式来提供一些数据。

@Component
public class SearchStrategy extends AbstractStrategy implements Strategy {

    //spring ui model
    private final Model model;

    public SearchStrategy(Model model) {
        super(model);
        this.model = model;
    }
    ..
}

public abstract class AbstractStrategy {

    @Autowired
    protected ApplicationContext ctx; //spring class

    public AbstractStrategy(Model model) {
        this.model = model;
    }
}

@Component
public class StrategyContext {

    private Strategy strategy;
    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
    ...
}

在我的休息控制器中,我做

@GetMapping("/")
public String getStrategy(final Model model, HttpServletRequest request) {
    ...
    StrategyContext sc = new StrategyContext();
    sc.setStrategy(new SearchStrategy(model));
    ...
}

实际上,我得到了

  

org.springframework.ui.Model'无法找到。

我不应该使用 new ,但我不知道如何通过模型。

尝试将StrategyContext置于我的控制器中自动装配,但我需要将模型传递给策略实现和抽象类

任何解决错误的想法,设计技巧?

修改,完成错误:

Parameter 0 of constructor in com.search.ui.SearchStrategy required a bean of type 'org.springframework.ui.Model' that could not be found.

2 个答案:

答案 0 :(得分:1)

它在启动时失败,因为没有Model(但是,在给定的上下文中 - 它将在Web调用上创建)。删除@Component注释。从您向我们展示的上下文中,Spring不需要为您管理SearchStrategy。控制器方法将按预期工作 - Model将为您自动处理。

答案 1 :(得分:1)

应从SearchStrategy类中删除Component注释。由于SearchStrategy类不包含默认构造函数,因此Spring尝试使用对象Model创建bean,但由于Model未定义为bean,因此无法创建bean。

1)请从SearchStrategy和AbstractStrategy类中删除@Component注释

2)您可以保留StrategyContext类的@Component注释

3)用Autowired对象替换新对象创建。请参阅以下示例代码: -

@Autowired
private StrategyContext strategyContext;

@GetMapping("/strategy")
public String getStrategy(final Model model, HttpServletRequest request) {
    System.out.println(model);

    /*StrategyContext sc = new StrategyContext();
    sc.setStrategy(new SearchStrategy(model));*/
    strategyContext.setStrategy(new SearchStrategy(model));

    System.out.println(strategyContext.getStrategy());

    return "Hello";
}

<强>更新: -

简单来说,从除StrategyContext之外的所有策略类中删除Component注释。因此,上下文应该能够创建所需的对象并将其返回。

只要删除组件注释,autowired就无法运行。换句话说,您将获得ApplicationContext的null。因此,您也不应该定义ApplicationContext(即从AbstractStrategy中删除它)。

所有对象创建逻辑都应该进入上下文类。 Context是唯一的Spring托管类。所有其他类都只是普通的Java类(即不是Spring bean)。