Vaadin Spring Scopes

Contexts and Scopes in Spring

  • Contexts in Spring are services that manage the lifecycle of objects and handle their injection. Generally, a context refers to a situation in which an instance is used with a unique identity. These objects are essentially "singletons" in the context.

  • Scopes are narrower than contexts. While conventional singletons are application-wide, objects managed by a Spring container are "singletons" in a narrower scope. Examples include a user session, a particular UI instance associated with the session, or even a single request. A scope defines the lifecycle of the object, that is its creation, use, and destruction.

Using Spring Scopes

In most programming languages, a variable name refers to a unique object within the scope of the variable. In Spring, an object has a unique identity within a scope, but instead of identifying the object by its variable name, it is identified by its type (object class) and qualifiers, if any.

In addition to standard Spring scopes, the Vaadin Spring add-on introduces two additional scopes: VaadinSessionScope and UIScope.

  • The @VaadinSessionScope annotation manages the Spring beans during the Vaadin session lifecycle. It ensures that the same bean instance is used during the whole Vaadin session.

    Example: Using the @VaadinSessionScope annotation.

    @Route("")
    public class MainLayout extends Div {
        public MainLayout(@Autowired SessionService bean) {
            setText(bean.getText());
        }
    }
    
    @Route("editor")
    public class Editor extends Div {
        public Editor(@Autowired SessionService bean) {
            setText(bean.getText());
        }
    }
    
    @Component
    @VaadinSessionScope
    public class SessionService {
        private String uid = UUID.randomUUID().toString();
    
        public String getText(){
            return "session " + uid;
        }
    }
    • Provided you access the application from the same Vaadin session, the same instance of SessionService is used. This is because it is session scoped.

    • If you open the root target in one tab and the editor target in another, the text in both is the same. This happens because the session is the same, even though the tabs (and UI instances) are different.

  • The @UIScope annotation manages the Spring beans during the UI lifecycle.

    Example: Using the @UIScope annotation.

    @Route("")
    public class MainLayout extends Div {
        public MainLayout(@Autowired UIService bean) {
            setText(bean.getText());
        }
    }
    
    @Route("editor")
    public class Editor extends Div {
        public Editor(@Autowired UIService bean) {
            setText(bean.getText());
        }
    }
    
    @Component
    @UIScope
    public class UIService {
        private String uid = UUID.randomUUID().toString();
    
        public String getText() {
            return "ui " + uid;
        }
    }
    • The UIService is now the same while in the same UI, because it is UI scoped. When using @UIScope, the same bean instance is used inside the same UI instance.

    • If you open the root target in one tab and the editor target in another, the text in each is different, because the UI instances are different. However, if you navigate to the Editor instance via the router (or a UI instance which delegates navigation to the router), the text is the same.

    • Example: Navigating to the editor target.

      public void edit() {
          getUI().get().navigate("editor");
      }