> Markdown version of [Appendix A - Vaadin Portlet CDI Support](https://vaadin.com/docs/v14/flow/integrations/portlet/cdi-support). Section index: [llms.txt](https://vaadin.com/docs/v14/flow/llms.txt)

# Vaadin Portlet CDI Support

> **Note:** Vaadin Portlet CDI features are not supported for Liferay 7. See [Dependency Injection in Liferay](https://help.liferay.com/hc/en-us/articles/360029045891-Introduction-to-Dependency-Injection/) if you need dependency injection in your project.

The Vaadin Portlet CDI (Contexts and Dependency Injection) extension allows development of Portlet 3.0 (JSR 362) portlets with Vaadin components and services as managed beans. With the Vaadin Portlet CDI extension, managed beans can be injected into any Vaadin component with the application container managing the initialization and destruction (lifecycle) of beans automatically.

## <a id="as-a-developer-when-would-i-want-to-use-cdi-for-my-vaadin-portlet-application"></a>As a Developer, When Would I Want to Use CDI for My Vaadin Portlet Application?

The primary use cases for Vaadin Portlet CDI are:

- If the business layer or other parts of your Portlet application is already using CDI, and you want to leverage CDI in your UI layer as well.

- You want to use portlet scopes, such as `@PortletRequestScoped` and `@PortletSessionScoped`, for portlet-specific lifecycle management of your UI or business objects.

- You want to access portlet predefined beans, as specified by JSR 362.

> **Note:** This tutorial assumes you are building Vaadin portlets for the Apache Pluto portal, which uses Tomcat and Weld as the application and CDI containers. Currently, Vaadin Portlet CDI has not been tested with other CDI implementations.

## <a id="how-do-i-use-the-vaadin-cdi-portlet-extension"></a>How Do I Use the Vaadin CDI Portlet extension?

Taking the CDI extension into use in your Vaadin Portlet project requires the following steps:

1. Add the `vaadin-portlet-cdi` dependency

2. Add an empty `beans.xml` configuration file

3. Use the `VaadinCdiPortlet` class as the base class for your portlet

4. Add `@Inject`, scope annotations and other CDI features in your code

The remainder of this chapter goes through each of these steps in detail.

> **Note:** The Vaadin CDI Portlet extension differs from the Vaadin CDI add-on ([Using Vaadin with CDI](https://vaadin.com/docs/v14/flow/integrations/cdi/tutorial-cdi-basic.md)) for servlet applications. In particular, the scopes introduced by the Vaadin CDI add-on (`@VaadinServiceScoped`, `@VaadinSessionScoped`, `@UIScoped`, `@RouteScoped`) should not be used for portlets, since the session and service concepts differ slightly, and there is no routing. Other than this, the standard CDI features work in exactly the same way.

> **Note:** This chapter is not a tutorial on CDI in general. For resources on CDI, visit <https://www.cdi-spec.org/>, and for using CDI with Vaadin servlet applications, see [Using Vaadin with CDI](https://vaadin.com/docs/v14/flow/integrations/cdi/tutorial-cdi-basic.md).

<!-- vale Vaadin.Headings = NO -->

<!-- vale Vale.Terms = NO -->

<!-- vale Vale.Spelling = NO -->

### <a id="add-the-vaadin-portlet-cdi-dependency"></a>Add the vaadin-portlet-cdi Dependency

<!-- vale Vale.Spelling = YES -->

<!-- vale Vale.Terms = YES -->

<!-- vale Vaadin.Headings = YES -->

To use CDI with Vaadin Portlets, the `vaadin-portlet-cdi` artifact, must be added as a dependency. Add the following to your portlet project’s `pom.xml`:

pom.xml excerpt

```xml
<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-portlet-cdi</artifactId>
    <version>${vaadin.portlet.version}</version>
</dependency>
```

In multi-portlet projects, the value of `vaadin.portlet.version` property should match the version of the `vaadin.portlet` dependency used.

## <a id="add-an-empty-beans-xml-configuration-file"></a>Add an Empty beans.xml Configuration File

The second step is to add the file `/src/main/webapp/WEB-INF/beans.xml` to your Vaadin Portlet application with the following contents:

beans.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                     http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="all">
</beans>
```

This file enables CDI for your portlet and ensures that the application container will scan your projects for bean annotations and injection points. For a quick overview of `bean.xml`, read "What is bean.xml and why do I need it?" in [CDI frequently asked questions](http://www.cdi-spec.org/faq).

## <a id="change-portlet-class"></a>Change Portlet Class

The first step in enabling CDI is to replace the base class of your Vaadin Portlet (`VaadinPortlet`) with `VaadinCdiPortlet`. For example, updating `BookListPortlet`:

```java
// old, non-CDI portlet:
public class NormalBookListPortlet extends VaadinPortlet<BookListView> {
    // ... contents
}

// new, CDI portlet:
public class CdiBookListVaadinPortlet extends CdiVaadinPortlet<BookListView> {
    // ... contents
}
```

After completing these initial steps, rebuild and deploy to ensure that everything is working as before. You are now ready to start using CDI features in your Vaadin Portlet application.

## <a id="scopes-and-injection-points"></a>Scopes and Injection Points

The CDI framework allows injection of objects with a well-defined, container-managed lifecycle (called **managed beans**) into any class (including Vaadin components) by simply annotating the corresponding field with `@Inject`. An injection point may get populated by an already existing bean or a new instance may be created, depending on the context of the object containing the bean (the **bean client** in CDI lingo). For example, the same instance of a bean with a longer lifecycle (such as `@PortletSessionRequestScoped` beans) is injected into multiple different beans with a shorter lifecycle (such as `@PortletRequestScoped` beans).

### <a id="injecting-vaadin-components"></a>Injecting Vaadin Components

The root Vaadin component of your Vaadin Portlet application is the one passed as a type parameter to the `CdiVaadinPortlet` when sub-classing it (`BookListView` in this example). One instance of this component is created for each browser window and each instance of the portlet in this window, and it may be destroyed on the server side when the window is closed. Beans injected into the root component that are not annotated with an explicit scope (corresponding to the implicit `@Dependent` scope) will share this lifecycle. This makes the default scope appropriate for objects that you want to be exclusively owned by the root component, such as child components. For example:

```java
public class BookListView extends Div {

    @Inject
    private BookGrid bookGrid;
    // ...

    @PostConstruct
    private void init() {
        add(bookGrid);
        // ...
    }
}

public class BookGrid extends Grid<Book> {

    @PostConstruct
    private void init() {
        // ...
    }
}
```

In this example, the child component of type `BookGrid` is injected into the root component `BookListView`. The default scope also guarantees that each injection point will get its own instance.

> **Note:** When using injection, make sure all concrete classes being injected have the default (no-arguments) constructor. Initialization code that depends on bean resolution should be placed in a `@PostConstruct`-annotated method, not in the constructor.

> **Note:** Be aware that before a managed bean is resolved, the injected field may be populated by a proxy object. If you are storing managed beans in a collection or perform other operations where the identity of the object may be of significance, make sure to perform them after the actual object has been resolved.

### <a id="session-and-request-scope-and-predefined-beans"></a>Session and Request Scope and Predefined Beans

JSR 362 defines the scopes `@PortletSessionScoped` and `@PortletRequestScoped` for beans that follow the portlet session and request lifecycle, respectively. Use `@PortletSessionScoped` when you want a bean that is persistent throughout the portlet session. Use `@PortletRequestScoped` for beans that should live only through the portlet request.

JSR 362 also defines a number of **predefined beans** that can be injected into your portlets. These predefined beans allow easy access to portlet state information, such as current request, current mode, window state, and more. For example, you could inject these into a Vaadin Portlet component:

MyPortletComponent.java

```java
public class MyPortletComponent extends Div {

    @Inject
    private PortletRequest portletRequest;

    @Inject
    private WindowState windowState;

    @Inject
    private PortletMode portletMode;

    // ...
}
```

As these beans are request-scoped, the values of the fields will be updated for each portlet request.

In the example case, the type of each field determines which predefined bean gets injected. Some predefined beans are of a basic type, in which case a qualifier is required to identify the desired bean. For instance, the following portlet view injects the portlet namespace and window identifier (both of type `String`):

MyPortletView\.java

```java
public class MyPortletView extends Div {

    @Inject
    @Namespace
    private String namespace;

    @Inject
    @WindowId
    private String windowId;

    // ...
}
```

For a full list of predefined beans and qualifiers, see Chapter 20 of JSR 362 (<https://jcp.org/en/jsr/detail?id=362>).

### <a id="i18provider"></a>I18Provider

`I18NProvider` is Vaadin’s mechanism for introducing a localization object into your application. You can have your own `I18NProvider` subclass automatically instantiated as a managed bean when using Vaadin Portlet CDI. This requires adding just two annotations to the class definition:

I18N.java

```java
@VaadinServiceEnabled
@ApplicationScoped
public static class I18N implements I18NProvider {

    @PostConstruct
    public void init() {
        // ...
    }

    @Override
    public List<Locale> getProvidedLocales() {
        // ...
    }

    @Override
    public String getTranslation(String key, Locale locale, Object... params) {
        // ...
    }
}
```

As with Vaadin CDI for servlet applications, the class also needs to be annotated with `@VaadinServiceEnabled` for the Vaadin service to pick it up. Unlike Vaadin CDI, use `@ApplicationScoped` instead of `@VaadinServiceScoped`. The scope ensures that there will be only one `I18NProvider` shared among all the views of your portlet application.

`C1FFFF77-8BC2-45CC-8F29-69B3B22ACA15`
