How does the session scope of a bean work in a Spring MVC application?

user4296472 picture user4296472 · Sep 13, 2015 · Viewed 11.2k times · Source

I am pretty new in Spring MVC and I have a doubt about the session scope of a 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;
    }

}

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)

So, from what I have understand it means that it is automatically created a single bean for each user session.

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?

Another doubt is related to the proxyMode = ScopedProxyMode.TARGET_CLASS attribute. What exactly does that mean? Why is it applied to this bean?

Answer

Sotirios Delimanolis picture Sotirios Delimanolis · Sep 13, 2015

So, from what I have understand it means that it is automatically created a single bean for each user session.

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".

The typical use is

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

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.

The annotation attribute and value

proxyMode = ScopedProxyMode.TARGET_CLASS

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: