我想用 Spring 实现一个购物车,所以我需要Cart
在会话中保存一个对象(具有 products、paymentType 和 deliveryType 等属性)。我尝试使用 bean 和属性“范围”设置为“会话”来创建它,但它不起作用,我应该在我的控制器或Cart
类中使用一些额外的注释吗?任何示例用法都会非常有帮助:-) 在此先感谢。
4 回答
@Component
@Scope("session")
public class Cart { .. }
进而
@Inject
private Cart cart;
如果它在 Web 上下文中声明(dispatcher-servlet.xml),它应该可以工作。另一种选择是使用原始会话并将您的购物车对象放在那里:
@RequestMapping(..)
public String someControllerMethod(HttpSession session) {
session.setAttribute(Constants.CART, new Cart());
...
Cart cart = (Cart) session.getAttribute(Constants.CART);
}
如果您将购物车直接注入您的控制器,则可能会出现问题,因为您的控制器是单例范围的(默认情况下),它比您注入的 bean 范围更广。这篇出色的文章概述了您正在尝试做的四种方法:http ://richardchesterwood.blogspot.co.uk/2011/03/using-sessions-in-spring-mvc-include.html 。
以下是解决方案的快速摘要:
- 将控制器范围限定为会话范围(
@scope("session")
在控制器级别上使用),并且控制器中只有一个购物车实例。 - 将控制器范围限定为请求并注入会话范围的购物车。
- 只需直接使用会话 - 有点混乱,IMO。
- 使用 Spring 的注解
<aop:scoped-proxy/>
。
所有方法都有其优点和缺点。我通常选择选项 2 或 4。选项 4 实际上非常简单,并且是我见过的 Spring 记录的唯一方法。
您只需要使用会话和代理模式添加 Scope 注释,如下所示
@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class ShoppingCart implements Serializable{
}
无论您需要在哪里使用购物车对象,都可以自动装配它
@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {
Logger logger = LoggerFactory.getLogger(ShoppingCartServiceImpl.class);
@Autowired
ShoppingCart shoppingCart;
}
披露:我开发了一个示例项目,它使用 spring MVC、angularJS 和 bootstrap 来演示 Spring Session 范围 -
https://github.com/dpaani/springmvc-shoppingcart-sample
尝试自动连接 HttpSession 和 spring 将注入 HttpSession 的代理
@Autowired
private HttpSession httpSession;