del.icio.us Digg DZone Reddit StumbleUpon
Session-Scoped Beans in Spring - Willie Wheeler
« Previous | 1 | 2

Spring Application Context

Here's our Spring config:

Code listing: front-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd"
    default-autowire="byName">
    
    <!-- Scan for controllers and services -->
    <context:component-scan base-package="ssbexample"/>
    
    <!-- Create a proxy to generate session-scoped shopping carts -->
    <bean id="shoppingCart" class="ssbexample.ShoppingCart" scope="session">
        <!-- This requires CGLIB -->
        <aop:scoped-proxy/>
    </bean>
    
    <!-- Maps a logical view name to a physical resource -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

As I noted at the outset, we're autowiring here, so I'll just point out that the shoppingCart bean is automatically injected into the service bean (identified by the @Service("service") annotation inside ssbexample.MyServiceImpl) since I have default-autowire="byName" set in the Spring config.

On the shoppingCart bean, we have the scope set to session, which is probably unsurprising. But that's not the whole story.

The interesting thing about the injection is that we're not injecting any particular shopping cart into the service bean. Rather we're injecting a web-aware proxy into the service bean. That's what <aop:scoped-proxy/> is for. The proxy, being web-aware, can see individual user sessions. So when any particular user asks for a shopping cart, the proxy grabs the shopping cart off the current session and returns it.

Note that in order to use session scope, you have to be using a web-aware Spring application context, such as XmlWebApplicationContext. Otherwise there's no way for the scoped proxy to reference a current session.

Discussion

I think that this is a pretty nice tool to have in your toolbox. Using this technique, you can move the creation of session-scoped beans into the Spring application context, instead of having to create those manually in the code, and then having to place them manually on the session. And it does make the service API cleaner, because you can avoid having to include important objects (like a shopping cart) in all the method signatures. So I like that about session-scoped beans.

The main reservation I have is that despite appearances, there's an important sense in which using session scoping ties the code to Spring, which goes against the whole Spring philosophy of being noninvasive. Usually service beans are designed and implemented such that a single service bean serves multiple clients, each with its own client session. And as long as we're able to inject a web-aware shopping cart proxy into the shopping cart slot, we haven't abandoned that. But that's the problem: if we decide to move away from Spring, we may find ourselves without easy access to a web-aware shopping cart proxy, and so we're forced to redesign the service bean in some way (such as changing the service methods to include a shopping cart parameter).

I don't think this concern invalidates the approach, but I do think that it's important to understand its ramifications.

Happy Springing.

Social bookmarks: del.icio.us Digg DZone Reddit StumbleUpon
« Previous | 1 | 2

Comments (18)

I'm curious as to what your take would be on using the @Scope annotation to define the session scoping.
By Adam Christensen on Jul 19, 2008 at 6:31 AM PDT
I haven't used that but I don't see why not.
By Willie Wheeler on Jul 21, 2008 at 5:24 PM PDT
i downloaded your zip file but i found there is an error. I can't fix it. Hope you can tell me why the problem occur. Thx
By fai on Sep 23, 2008 at 1:36 AM PDT
@fai: Help me out a bit here. :-) What was the error?
By Willie Wheeler on Sep 23, 2008 at 1:51 AM PDT
the view cart page doest not display the number of items added but is display the ${shoppingCart.numItems} in the viewcart.jsp page
By fai on Sep 23, 2008 at 2:31 AM PDT
Hi fai. You have a few different options:

1) If you are using Tomcat, upgrade to Tomcat 6.

2) If you don't want to upgrade, you can place the following line of code at the top of your JSP:

<%@ page isELIgnored="false" %>

This approach requires modifying each JSP that uses JSP EL.

3) If you want to handle this globally instead of on a page-by-page basic, try adding the following to web.xml:

<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>false</el-ignored>
</jsp-property-group>
</jsp-config>

Let me know if you continue to have trouble. Thanks!
By Willie Wheeler on Sep 23, 2008 at 8:09 AM PDT
The problem is solved after i paste the <%@ page isELIgnored="false" %> in the JSP page. But if use the globally method still the same problem. Thx a lot. =]
By fai on Sep 23, 2008 at 7:18 PM PDT
Hi Willie,

I am using Spring Web Flow and have spring session scoped bean (Shopping Cart)

How do I remove the scoped session variable(e.g shopping cart) after the customer finish the flow?

In MVC, we would do something like
request.getSession().removeAttribute("shoppingcart" );

Any hint?

Thanks,
By Gerald on Oct 16, 2008 at 8:49 AM PDT
I will be very curious if Spring 2.5 could remove a pre-configured session scoped bean on the fly from a given HTTP session, similar to the following in code:
request.getSession().removeAttribute("shoppingcart" );
By John on Oct 16, 2008 at 10:13 AM PDT

Very helpful article.

It took me some time to figure out that scoped beans need to be added to the model object to be visible on the JSP page tags through EL.

By en on Jan 15, 2009 at 12:01 AM PST

Is this thread safe? As you sad a bean serve more clients and I know that a bean is singleton...

By psw on Feb 22, 2009 at 4:22 PM PST

@psw: Session-scoping doesn't add any threadsafety guarantees. Usually you'll have only one request-processing thread working with your session at a time, and so for many practical purposes requests against the session-scoped bean will be isolated, but there are lots of situations in which this could fail to hold. So if you need actual threadsafety then it behooves you to use proper synchronization (for example on the bean itself).

By Willie Wheeler on Feb 22, 2009 at 4:33 PM PST

Another quick pair of comments:

  1. Session-scoped beans are not singletons in either the GoF design pattern sense or the Spring singleton bean sense.
  2. As a general rule, you have to be even more careful about threadsafety with singletons than you do with non-singletons, because singletons often involve data sharing across threads. I think this is what you were getting at with your post but just wanted to be sure.
By Willie Wheeler on Feb 22, 2009 at 4:39 PM PST

Thank you for the answer!

I know that session-scope is not singleton but I know that the service is. And for a shopping-bag, I think you need it thread safe.

By psw on Feb 24, 2009 at 9:09 AM PST

How do I access the session-scope bean from JSP, without putting into model explicitly from Controller?

By Ruban on May 15, 2009 at 9:48 AM PDT

This initially looked like a good idea, but the fact that you cant access them via the JSP pages without explicitly adding them to the model object prevents me from using this. If I could still use

<c:set value="${sessionScope['ShoppingCart']}" var="shoppingCart" />

then i would consider this.

By JaredTims on May 19, 2009 at 7:49 AM PDT

he myth of pandora is ancient, appears in several distinct Greek versions, pandora armbandand has been interpreted in many ways. In all literary versions, Neu Eingetroffen however, Pandora Armbänder the myth is a rosetta stone kind of theodicy, addressing the question pop information, web easy get, sports fashion, news-fashionof why there is evil in the world. In the seventh hot-winter century BC, Hesiod, both in his Theogony (briefly, without naming Pandora outright rosetta stone language, rosetta stone spanish, abercrombie and fitch, Abercrombie Fitch

By pandora schmuck on Aug 30, 2010 at 11:13 PM PDT

Post a comment

Your name:
Your e-mail address (won't be displayed):
Your web site (optional):
example: www.xyz.com
Your comment:
Preview:
By You
Please help us reduce comment spam:
Spring in Practice
My brother and I are writing Spring in Practice for Manning!

What's New?

2009-08-30 - Check out my two-part series on DZone: Spring Integration: A Hands-On Tutorial.
2009-03-25 - My new article Getting Started with Spring Batch 2.0 is available on DZone.
Home | Consulting | Tech Articles | Mailing List | Contact | Spring Blog
Copyright © 2008 Wheeler Software, LLC.