> Markdown version of [Vaadin CDI contexts](https://vaadin.com/docs/v10/flow/cdi/tutorial-cdi-contexts). Section index: [llms.txt](https://vaadin.com/docs/v10/flow/llms.txt)

# Vaadin CDI Contexts

You can find a summary about contexts at [Vaadin Spring Scopes](https://vaadin.com/docs/v10/flow/spring/tutorial-spring-scopes.md). The concept is the same.

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.

> **Note:** Please refer to [Asynchronous Updates](https://vaadin.com/docs/v10/flow/advanced/tutorial-push-access.md#push.access) about push.

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.

## <a id="vaadinservicescoped"></a>`@VaadinServiceScoped`

`@VaadinServiceScoped` context manages the beans during Vaadin Service lifecycle. The lifecycle of the service is the same as the lifecycle of its Vaadin servlet.

> **Note:** Please refer to [Vaadin Servlet and Service](https://vaadin.com/docs/v10/flow/advanced/tutorial-application-lifecycle.md#application.lifecycle.servlet-service) section of [Application Lifecycle](https://vaadin.com/docs/v10/flow/advanced/tutorial-application-lifecycle.md) tutorial for details about the Vaadin Service.

For beans automatically picked up by VaadinService you need the `@VaadinServiceEnabled` annotation. It should be used together with `@VaadinServiceScoped`, see [Vaadin service interfaces as a CDI bean](https://vaadin.com/docs/v10/flow/cdi/tutorial-cdi-service-beans.md) for details.

## <a id="vaadinsessionscoped"></a>`@VaadinSessionScoped`

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

> **Note:** Please refer to [User Session](https://vaadin.com/docs/v10/flow/advanced/tutorial-application-lifecycle.md#application.lifecycle.session) section of [Application Lifecycle](https://vaadin.com/docs/v10/flow/advanced/tutorial-application-lifecycle.md) tutorial for details about the Vaadin Session lifecycle.

```java
@Route("")
public class MainLayout extends Div {
    @Inject
    public MainLayout(SessionService bean){
        setText(bean.getText());
    }
}

@Route("editor")
public class Editor extends Div {
    @Inject
    public Editor(SessionService bean){
        setText(bean.getText());
    }
}

@VaadinSessionScoped
public class SessionService {
    private String uid = UUID.randomUUID().toString();

    public String getText(){
        return "session "+uid;
    }
}
```

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.

## <a id="uiscoped-normaluiscoped"></a>`@UIScoped`, `@NormalUIScoped`

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 [Loading a UI](https://vaadin.com/docs/v10/flow/advanced/tutorial-application-lifecycle.md#application.lifecycle.ui) section of [Application Lifecycle](https://vaadin.com/docs/v10/flow/advanced/tutorial-application-lifecycle.md) tutorial for details about the `UI` lifecycle.

```java
@Route("")
public class MainLayout extends Div {
    @Inject
    public MainLayout(UIService bean){
        setText(bean.getText());
    }
}

@Route("editor")
public class Editor extends Div {
    @Inject
    public Editor(UIService bean){
        setText(bean.getText());
    }
}

@NormalUIScoped
public class UIService {
    private String uid = UUID.randomUUID().toString();

    public String getText(){
        return "ui " + uid;
    }
}
```

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.

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

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

## <a id="routescoped-normalroutescoped"></a>`@RouteScoped`, `@NormalRouteScoped`

`@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`.

> **Note:** Please refer to [Defining Routes With @Route](https://vaadin.com/docs/v10/flow/routing/tutorial-routing-annotation.md), and [Router Layouts and Nested Router Targets](https://vaadin.com/docs/v10/flow/routing/tutorial-router-layout.md) about the details of route targets, layouts, and chain.

```java
@Route("")
@RoutePrefix("parent")
public class ParentView extends Div implements RouterLayout {
    @Inject
    public ParentView(@RouteScopeOwner(ParentView.class) RouteService routeService) {
        setText(routeService.getText());
    }
}

@Route(value = "child-a", layout = ParentView.class)
public class ChildAView extends Div {
    @Inject
    public ChildAView(@RouteScopeOwner(ParentView.class) RouteService routeService) {
        setText(routeService.getText());
    }
}

@Route(value = "child-b", layout = ParentView.class)
public class ChildBView extends Div {
    @Inject
    public ChildBView(@RouteScopeOwner(ParentView.class) RouteService routeService) {
        setText(routeService.getText());
    }
}

@NormalRouteScoped
@RouteScopeOwner(ParentView.class)
public class RouteService {
    private String uid = UUID.randomUUID().toString();

    public String getText() {
        return "ui " + uid;
    }
}
```

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
@Route("scoped")
@RouteScoped
public class ScopedView extends Div {
    private void onMessage(@Observes(notifyObserver = IF_EXISTS) MessageEvent message) {
        setText(message.getText());
    }
}
```

In this example message is delivered to the `ScopedView` instance we already navigated to. If we are on an other view, there is no instance of this bean, and the message is not delivered to it.
