问题描述
我在Spring MVC中还很陌生,我对bean的会话范围有疑问.
I am pretty new in Spring MVC and I have a doubt about the session scope of a bean.
进入一个项目,我有一个Cart
bean,这个是:
Into a project I have a Cart
bean, this one:
@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 :
So this bean is automatically detected as component by the container and it is set as a session bean by:
@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
因此,据我了解,这意味着它会为每个用户会话自动创建一个bean.
So, from what I have understand it means that it is automatically created a single bean for each user session.
在我的示例中,Cart
类表示购物车,已登录的用户在其中放入了要购买的商品.这是否意味着对于每个登录到HttpSession
的用户节,都存在一个Cart
bean?因此,此bean进入了会话,用户可以在会话中添加或删除项目.这种解释正确吗?或者我缺少什么?
In my example the Cart
class represent a shopping cart in which a logged user put the items that want buy. Does it mean that there exists a single Cart
bean for each logged user section into the HttpSession
? So this bean is into the session and the user can add or delete item from it. Is this interpretation right or am I missing something?
另一个疑问与proxyMode = ScopedProxyMode.TARGET_CLASS
属性有关.这到底是什么意思呢?为什么将它应用于此bean?
Another doubt is related to the proxyMode = ScopedProxyMode.TARGET_CLASS
attribute. What exactly does that mean? Why is it applied to this bean?
推荐答案
将为每个用户创建会话bean,但仅在被请求时才创建.换句话说,如果对于给定的请求,您实际上并不需要该bean,那么容器将不会为您创建它.从某种意义上说,这是懒惰".
The session bean will be created per user, but only when requested. In other words, if, for a given request, you don't actually need that bean, the container will not create it for you. It's, in a sense, "lazy".
典型用途是
@Controller
public class MyController {
@Autowired
private MySessionScopeBean myBean;
// use it in handlers
}
在这里,您要将会话作用域的bean注入到单例作用域的bean中. Spring要做的是注入一个 proxy bean,该bean在内部可以为每个用户生成一个真正的MySessionScopeBean
对象,并将其存储在HttpSession
中.
Here, you're injecting a session scoped bean into a singleton scope bean. What Spring will do is inject a proxy bean, that, internally, will be able to generate a real MySessionScopeBean
object per user and store it in the HttpSession
.
注释属性和值
proxyMode = ScopedProxyMode.TARGET_CLASS
定义Spring将如何代理您的bean.在这种情况下,它将通过保留目标类进行代理.为此,它将使用CGLIB.另一种选择是INTERFACES
,其中Spring使用JDK代理.这些不保留目标bean的类类型,仅保留其接口.
defines how Spring will proxy your bean. In this case, it will proxy by retaining the target class. It will use CGLIB for this purpose. An alternative is INTERFACES
where Spring uses JDK proxies. These do not retain the class type of the target bean, only its interfaces.
您可以在此处了解有关代理的更多信息:
You can read more about proxies here:
这是有关请求范围的相关文章:
Here's a related post about the request scope:
这篇关于Bean的会话范围在Spring MVC应用程序中如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!