Documentation

Documentation versions (currently viewingVaadin 23)
New Acceleration Kits: Kubernetes Kit and Azure Cloud Kit. Read the blog post.

Using CDI Beans in Instantiated Components

When using Vaadin CDI, most objects instantiated by the framework become managed beans. The framework uses the CDI BeanManager to get references to beans. This means that they are fully fledged CDI contextual instances.

The add-on looks up the CDI bean by type (component class) and @Any.

If the type isn’t found as a CDI bean – for example, because it’s ambiguous or doesn’t have a no-arguments public constructor – instantiation falls back to the default Vaadin behavior, and the component is instantiated as a plain-old Java object (POJO). Field injection is performed after the instance has been created using a no-args constructor, but constructor injection doesn’t work. Other CDI features don’t work either, since the instantiated component isn’t a contextual instance.

Note
Methods annotated with @PreDestroy in Dependent beans instantiated by the framework aren’t run.

Using Router Components

All route targets, router layouts, and exception targets become managed beans when the add-on is used. The components look and behave the same as without the add-on, but CDI features are available.

Example: Using the @Inject annotation on a basic route target.

@Route
public class MainView extends VerticalLayout {
    @Inject
    public MainView(Greeter greeter) {
        add(new Span(greeter.sayHello()));
    }
}
Note
Vaadin scans for router components on start-up and is unaware of CDI beans. Using producers or the @Typed annotation causes issues with this kind of bean.

Using Components Injected into Templates

Components injected into template classes using the @id annotation become managed beans when the add-on is used.

Example: Using the @Id annotation to inject the DependentLabel component into TestTemplate class.

public class TestTemplate
        extends LitTemplate {
    @Id
    private DependentLabel label;
}

Example: DependentLabel class.

@Dependent
@Tag("dependent-label")
public class DependentLabel extends Label {
    @Inject
    private Greeter greeter;

    @PostConstruct
    private void init() {
        setText(greeter.sayHello());
    }
}

Example: TestTemplate.html Polymer template.

import { html, LitElement } from 'lit';

class TestTemplate extends LitElement {
  render() {
    return html`
      <div>
        <dependent-label id="label"></dependent-label>
      </div>
    `;
  }
}

customElements.define(TestTemplate.is, TestTemplate);
Important
The managed bean injected into the template shouldn’t exist before the template is instantiated. If it does exist at this time, it may not bind to its element, and this may result in an incorrect component tree.

Using a Custom UI

It isn’t necessary to define a custom UI subclass for your application, but it’s possible to define one using the corresponding servlet parameter, if needed.

The custom UI subclass is instantiated by Vaadin as a plain-old Java object (POJO, not as a managed bean), but it’s still possible to achieve dependency injection. Use BeanManager in your overridden UI.init() method; for example, BeanProvider.injectFields(this) (in DeltaSpike).

4C1C4451-607C-4BFA-85AE-3ECD668C4FBB