Bean的会话范围在Spring MVC应用程序中如何工作? - java

我在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类表示购物车,登录的用户在其中放入了想要购买的商品。这是否意味着每个登录到Cart的用户部分都存在一个HttpSession bean?因此,此bean进入了会话,用户可以在会话中添加或删除项目。这种解释是正确的还是我缺少什么?

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

参考方案

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

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

典型的用途是

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

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

注释属性和值

proxyMode = ScopedProxyMode.TARGET_CLASS

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

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

What is the difference between JDK dynamic proxy and CGLib?

这是有关请求范围的相关文章:

Inject HttpServletRequest into Controller

Java:“自动装配”继承与依赖注入 - java

Improve this question 我通常以常见的简单形式使用Spring框架: 控制器服务存储库通常,我会在CommonService类中放一个通用服务,并使所有其他服务扩展到类中。一个开发人员告诉我,最好在每个服务中插入CommonClass而不是使用继承。我的问题是,有一个方法比另一个更好吗? JVM或性能是否会受到另一个影响?更新资料Comm…

Spring Data Cassandra的事务管理 - java

我正在使用Spring和Cassandra作为基础数据库。曾提到过弹簧伞项目“ spring data cassandra”。与休眠不同,在这里无法找到如何管理事务。如果您中的某些人已经合并,请共享要包含的事务管理器的详细信息。 参考方案 Cassandra不支持传统(ACID)的事务。在某些特殊情况下,可以通过一些构造来实现事务原子性,例如原子批处理(请参…

Spring Boot:java.time.Duration的默认序列化从字符串更改为数字 - java

我们最近从Spring Boot 2.1.9升级到2.2.1,这导致我们的测试失败。调查导致结果,默认情况下java.time.Duration类型现在序列化为不同的序列。现在,我们将得到"PT15M",而不是在JSON消息中包含字符串"900.0"。 POJO定义如下所示@JsonProperty(required …

IntelliJ Spring MVC教程部署 - java

我尝试了tutorial,当我尝试部署webapp(IntelliJ 13.1.4 Ultimate)时,出现了一个奇怪的错误,如下面的屏幕快照所示。解决此错误的方法是什么? org.jdom.input.JDOMParseException: Error on line 742: The content of elements must consist o…

春季安全值得付出努力 - java

我一直在关注春季安全性,并注意到它是多么大的包装。我想知道是否值得花一些时间来加强这一点。Spring Security 2.0+为您节省了大量时间,还是以任何方式简化了您的项目? java参考方案 几年前,我考虑将其用于Spring项目,并选择了它,因为它是一个非常繁琐的框架,恕我直言,它提供的灵活性不是必需的。 (据我估计)减少我们自己的身份验证/授权的…