Trying to enhance current Flow OSGi integration, so that @Route
/@RouteAlias
annotated classes can be components (@Component
annotated classes) too in an OSGi container
Currently the efforts of Vaadin to make Flow (Vaadin 10+) OSGi compatible center around being able to run an existing Flow Application in an OSGi container. This is a great step forward, but might not be sufficient for people who do not want to port an existing Vaadin application into an OSGi container, but develop a Vaadin application as an OSGi enabled application, e.g., want to make use of OSGi's dependency injection mechanisms, i.e., Declarative Services.
Built on the premise, that one wants to develop a Flow application in OSGi I assume that this developer then wants to be able to define his @Route
/@RouteAlias
/(other?) annotated classes also to be a @Component
in OSGi.
You want to help making this work?
- PRs are highly welcome, just
and start coding/browsing/whatever ;)
- Any question/suggestion? -> Submit an issue
- I've also opened an issue at Flow in order to get feedback from Vaadin directly on this integration.
- Any other stuff? Write me on Twitter
The idea is as follows:
- Replace
ServletContainerInitializers
that are used in Flow to initialize aRouteRegistry
with a correspondingBundleTracker
that is able to track all the classes with@Route
/RouteAlias
/etc.. see FlowOsgiRouteTracker and FlowOsgiInitializer - As we want to use
@Route
annotated classes also as@Components
in OSGi we need to somehow bridge the Flow and OSGi world. This is done via two connection points, i.e.,RouteRegistry
andInstantiator
- FlowOsgiRouteRegistry is used to dynamically add and remove
Routes
if used within an OSGi container. This is done via FlowOsgiRouteTracker scanning all classes for a@Route
annotation and if present registering these classes as a services in OSGi so that they are dynamically injected to FlowOsgiRouteRegistry at runtime. - FlowOsgiInstantiator is used to create the route targets as OSGi
@Components
so that they can participate in OSGi' service lifecycle and reference other services that are registered in an Gi runtime. The instantiator is created within Flow viaServiceLoader
which can be used by us to inject ourInstantiator
into Flow
- FlowOsgiRouteRegistry is used to dynamically add and remove
- A developer that wants to create a
Route
for an OSGi application then only has to do something like the following:
@Route("")
@Component(factory="io.jatoms.example.MainView")
public class MainView extends VerticalLayout {
@Reference
GreeterService greeter;
public MainView() {
Button button = new Button("Click me",
event -> Notification.show(greeter.greet()));
add(button);
}
}
This is an abstract view of the the logic flow of the solution:
Created with plantuml in Markdown Preview Enhanced