Introduce addon as a dependency, and start using @Inject in your route targets, or layouts.
If you do not customize Vaadin Servlet in your web.xml, a CDI enabled Vaadin servlet is deployed automatically.
As UI class CdiUI is configured. If you need a custom UI class, you have to extend this class. It is not a CDI contextual instance, but injects work.
Otherwise you can customize CdiVaadinServlet just like VaadinServlet.
Vaadin triggered instantiation happens in a CDI aware Vaadin Instantiator implementation. Components created by this API:
- @Route, RouteLayout, HasErrorParameter components
- component fields injected by @Id to polymer templates
By default instantiator looks up the CDI bean by type ( component class ), and gets a contextual reference from BeanManager. All the CDI features are usable like observer, interceptor, decorator.
When type is not found as a CDI bean ( for example ambiguous, or does not have a no-arg public constructor ), instantiation falls back to the default Vaadin behavior. On success, dependency injection is performed. Injects work, but other CDI features not. It is a not a contextual instance.
@VaadinServiceScoped is a normal ( proxied ) scope. Its purpose to define a scope for the beans used by VaadinService. Like an Instantiator, or a I18NProvider.
@VaadinSessionScoped is a normal ( proxied ) scope. Every VaadinSession have a separate Context.
Every UI have a separate Context. Practically it means there is just one instance per UI for the scoped class.
For components, use @UIScoped. It is a pseudo scope, so gives a direct reference. Vaadin component tree does not work properly with CDI client proxies.
For other beans you can use @NormalUIScoped. Given it is normal scoped, have some benefit. For example can handle cyclic dependency.
@RouteScoped context 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 (target/layout/exceptionhandlers). Until owner remains in the route, all beans owned by it remain in the scope.
Normal, and non-normal meaning can be found at UI scopes.
Some Vaadin service interfaces can be implemented as a CDI bean.
- I18NProvider
- Instantiator
- SystemMessagesProvider
- ErrorHandler
Beans have to be qualifed by @VaadinServiceEnabled to be picked up automatically.
Following events fired as a CDI event:
- ServiceInitEvent
- PollEvent
- BeforeEnterEvent
- BeforeLeaveEvent
- AfterNavigationEvent
- UIInitEvent
- SessionInitEvent
- SessionDestroyEvent
- ServiceDestroyEvent
You just need a CDI observer to handle them.
During application shutdown it is implementation specific, whether it works with CDI or not. But according to servlet specs, a servlet destroy ( it means a service destroy too ) can happen in other circumstances too.
An incoming websocket message does not count as a request in CDI. Need a 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 contexts in event handlers.
In background threads these contexts are not active regardless of push.
Vaadin scans router classes (targets, layouts) without any clue about CDI beans.
Using producers, or excluding the bean class from types with @Typed
causes issues with these kind of beans.
As you can see at component instantiation, beans looked up by bean type.
The API can not provide qualifiers, so lookup is done with @Any
.
- Many infrastructural knowledge, and behavior came from Flow Spring addon.
- Many code came form the official Vaadin CDI addon 3.0 ( some in turn from my AltCDI addon )