Class SpringVaadinSessionListener

  • All Implemented Interfaces:
    SessionDestroyListener, SessionInitListener, Serializable

    public class SpringVaadinSessionListener
    extends Object
    implements SessionInitListener, SessionDestroyListener
    Manages an associated Spring WebApplicationContext with each VaadinSession (aka, "Vaadin application"). Typically created implicitly via SpringVaadinServlet.

    Overview

    In Vaadin 7, the VaadinSession object holds the state associated with each client browser connection to a Vaadin servlet. For consistency with older versions of Vaadin, we'll call this a "Vaadin application" instance. This class gives each Vaadin such "Vaadin application" instance its own Spring application context, and all such application contexts share the same parent context, which is the one associated with the overal servlet web context (i.e., the one created by Spring's ContextLoaderListener). This setup is analogous to how Spring's DispatcherServlet creates per-servlet application contexts that are children of the overall servlet web context.

    This class is implemented as a SessionInitListener and SessionDestroyListener on the servlet's VaadinService object. In turn, the Spring context is created when a new Vaadin application instance is initialized, and destroyed when it is closed. To use this class, use the SpringVaadinServlet in place of the usual VaadinServlet in web.xml.

    Accessing the Spring Context

    The getApplicationContext() method provides access to the application context. Alternately, use @VaadinConfigurable (see below) and implement ApplicationContextAware, etc. Invoking configureBean() at any time will configure a bean manually.

    Exposing the Vaadin Session

    The VaadinSession instance representing the "Vaadin application" can be exposed in the associated Spring application context and therefore made available for autowiring, etc. Simply add a bean definition that invokes VaadinUtil.getCurrentSession():

    
      <bean id="vaadinSession" class="org.dellroad.stuff.vaadin7.VaadinUtil" factory-method="getCurrentSession"/>
     
    This bean can then be autowired into application-specific "backend" beans, allowing them to use e.g. VaadinUtil.invoke(), which performs the locking necessary to avoid race conditions. But see also VaadinApplication for a convenience class that makes this process a little cleaner.

    @VaadinConfigurable Beans

    It is also possible to configure beans outside of this application context using AOP, so that any invocation of new FooBar(), where the class FooBar is marked @VaadinConfigurable, will automagically cause the new FooBar object to be configured by the application context associated with the currently running Vaadin application. In effect, this does for Vaadin application beans what Spring's @Configurable does for regular servlet context-wide beans.

    Note however that Spring destroy methods will not be invoked on application close for these beans, since their lifecycle is controlled outside of the Spring application context (this is also the case with @Configurable beans). Instead, these beans can themselves register as a SessionDestroyListener for shutdown notification; but see VaadinUtil.addSessionDestroyListener() for a memory-leak free method for doing this.

    Serialization and Clustering

    Instances are serializable; on deserialization the ConfigurableWebApplicationContext associated with the VaadinSession is refreshed; therefore, the ConfigurableWebApplicationContext is not itself stored in the HTTP session by this class. This is consistent with the way normal Spring application contexts ususally work across clustered servers.

    However, any session-scope beans should work as expected. So while this class associates an application context with each VaadinSession, when sessions are shared across multiple servers in a clustered environment, there will actually be a separate application contexts per server. Beans that must truly be "session wide" should be declared scope="session" as you normally would.

    Note: using scope="session" requires adding a <listener> clause registering Spring's RequestContextListener in your web.xml.

    See Also:
    VaadinConfigurable, SpringVaadinServlet, VaadinApplication, VaadinService, VaadinSession, Serialized Form