【问题标题】:How does the session scope of a bean work in a Spring MVC application?bean 的会话范围如何在 Spring MVC 应用程序中工作?
【发布时间】:2015-12-09 15:28:21
【问题描述】:

我是 Spring MVC 的新手,我对 bean 的 会话范围 有疑问。

进入一个项目我有一个Cart bean,这个:

@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Cart {


    private Map<Product, Integer> contents = new HashMap<>();

    public Map<Product, Integer> getContents() {
        return contents;
    }

    public Set<Product> getProducts() {
        return contents.keySet();
    }

    public void addProduct(Product product, int count) {

        if (contents.containsKey(product)) {
            contents.put(product, contents.get(product) + count);
        } 
        else {
            contents.put(product, count);
        }
    }


    public void removeProduct(Product product) {
        contents.remove(product);
    }

    public void clearCart() {
        contents.clear();
    }

    @Override
    public String toString() {
        return contents.toString();
    }

    public double getTotalCost() {
        double totalCost = 0;
        for (Product product : contents.keySet()) {
            totalCost += product.getPrice();
        }
        return totalCost;
    }

}

所以这个 bean 会被容器自动检测为组件,并通过以下方式将其设置为 会话 bean

@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)

因此,据我了解,这意味着它会为每个用户会话自动创建一个 bean。

在我的示例中,Cart 类表示一个购物车,登录的用户将想要购买的物品放入其中。这是否意味着在HttpSession 中的每个登录用户部分都存在一个Cart bean?所以这个 bean 进入了会话,用户可以从中添加或删除项目。这种解释是正确的还是我遗漏了什么?

另一个疑问与proxyMode = ScopedProxyMode.TARGET_CLASS 属性有关。这到底是什么意思呢?为什么要应用到这个 bean 上?

【问题讨论】:

标签: java spring spring-mvc spring-session


【解决方案1】:

所以,据我了解,这意味着它是自动的 为每个用户会话创建一个 bean。

会话 bean 将按用户创建,但仅在请求时创建。换句话说,如果对于给定的请求,您实际上并不需要该 bean,则容器不会为您创建它。从某种意义上说,它是“懒惰的”。

典型的用法是

@Controller
public class MyController {
    @Autowired
    private MySessionScopeBean myBean;
    // use it in handlers
}

在这里,您将会话范围的 bean 注入到单例范围的 bean 中。 Spring 将做的是注入一个 proxy bean,它在内部将能够为每个用户生成一个真正的 MySessionScopeBean 对象并将其存储在 HttpSession 中。

注解属性和值

proxyMode = ScopedProxyMode.TARGET_CLASS

定义 Spring 将如何代理您的 bean。在这种情况下,它将通过保留目标类来代理。它将为此目的使用 CGLIB。另一种选择是INTERFACES,其中 Spring 使用 JDK 代理。这些不保留目标 bean 的类类型,只保留其接口。

您可以在此处阅读有关代理的更多信息:

这是关于请求范围的相关帖子:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    • 2012-10-31
    • 2017-05-09
    相关资源
    最近更新 更多