Here's our Spring config:
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.
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.