Bean的会话范围在Spring MVC应用程序中如何工作?
问题内容:
我在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
每个登录的用户部分都存在一个bean
HttpSession
?因此,此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的类类型,仅保留其接口。