Vaadin CDI Contexts

    In addition to standard CDI contexts the CDI add-on introduces some new contexts.

    Normal and Pseudo scopes

    Most scopes are normal scopes in CDI. It means a call to a managed bean is delegated by a client proxy to the active instance. The active instance is provided by the context. Vaadin component hierarchy does not work properly with CDI client proxies, so as a precaution the Vaadin CDI plugin will not deploy if any such beans are discovered. Normal scopes introduced by this add-on are @VaadinServiceScoped, @VaadinSessionScoped, @NormalUIScoped, @NormalRouteScoped.

    Any scope that is not a normal scope is called a pseudo-scope. Scopes of this kind are standard @Dependent, and @Singleton. Additionally @UIScoped, and @RouteScoped introduced by this add-on. Injection of a pseudo-scoped bean will create a direct reference to the object. There are some limitations when not using proxies. Circular referencing (that is, injecting A to B and B to A) will not work. Injecting into a larger scope will bind the instance from the currently active smaller scope, and will ignore smaller scope change. For example a @UIScoped bean after being injected into session scope will point to the same instance ( even its UI is closed ) regardless of current UI.

    About Push

    Vaadin contexts are usable inside the UI.access method with any push transport.

    An incoming websocket message does not count as a request in CDI. Need an http request to have request, session, and conversation context. So you should use WEBSOCKET_XHR (it is the default), or LONG_POLLING transport, otherwise you lost these standard contexts.

    In background threads contexts depending on http request are not active regardless of push.

    Note
    Please refer to Vaadin Servlet and Service section of tutorial for details about the Vaadin Service.

    For beans automatically picked up by VaadinService you need the annotation. It should be used together with @VaadinServiceScoped, see Vaadin service interfaces as a CDI bean for details.

    @VaadinSessionScoped context manages the beans during Vaadin Session lifecycle. It means that the same bean instance will be used within the whole Vaadin session.

    Java

    In this example the same instance of SessionService will be used as long as we access the application from the same Vaadin session since it’s session scoped. E.g. if you open the root target in one tab and the editor target in another tab, then the shown text will be the same for both. It happens because the session is the same even though the tabs (and UI instances) are different.

    The @UIScoped, and @NormalUIScoped context manages the beans during the UI lifecycle. Similar to the example above the UIService will be the same while we are in the same UI since it’s ui scoped now.

    For components use @UIScoped, for other beans you can use @NormalUIScoped.

    Note
    Please refer to section of Application Lifecycle tutorial for details about the UI lifecycle.

    Java

    Now if you open two browser tabs, the text in these will be different since the UI instances are different. But if you navigate to the Editor instance via the router (or the UI instance which delegates navigation to the router) then the text will be the same.

    So inside the same UI instance the same bean instance with @UIScoped, or @NormalUIScoped is used.

    @RouteScoped, and @NormalRouteScoped context’s lifecycle on its own is same as UI context’s. Together with the concept of @RouteScopeOwner it can be used to bind beans to router components (@Route, RouteLayout, HasErrorParameter).

    Until owner remains in the route chain, all beans owned by it remain in the scope.

    For Vaadin components use @RouteScoped, for other beans you can use @NormalRouteScoped.

    Java

    In this example ParentView, ChildAView, and ChildBView ( paths are /parent, /parent/child-a, and /parent/child-b) use the same RouteService instance, while you navigate between them. After navigating out of ParentView, RouteService is destroyed too.

    Note
    As you can see @RouteScopeOwner is redundant. It is a CDI qualifier, so you have to define it both on the bean, and on the injection point.

    Route components can be @RouteScoped too. In this case @RouteScopeOwner should point to a parent layout. Omitting it means owner is the class itself.

    Java