The document discusses using dependency injection (DI) with Vaadin applications. It explains that DI allows defining abstractions and implementations as beans that can then be injected where needed. This loosens coupling and enables features like scopes. The event bus is presented as an example DI extension. Tips are provided like automatically setting up menus based on view bean annotations and internationalization support. Overall DI is said to decouple code and ensure best practices.
1. 5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N
@peter_lehto
D I Y O U R U I
4. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
5. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
• Instances and Scopes
6. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
• Instances and Scopes
• EventBus and other DI Extensions
7. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
• Instances and Scopes
• EventBus and other DI Extensions
• Tips and Tricks for Springifying your Vaadin app
8. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
• Instances and Scopes
• EventBus and other DI Extensions
• Tips and Tricks for Springifying your Vaadin app
9. W h a t D e p e n d e n c y I n j e c t i o n ?
18. Dependency Injection (DI) is a runtime mechanism
where dependency between the client object and the
dependent object does not occur directly.
19. Dependency Injection (DI) is a runtime mechanism
where dependency between the client object and the
dependent object does not occur directly.
With DI the client object does not necessarily
manage the lifecycle of the dependent object.
20. Dependency Injection (DI) is a runtime mechanism
where dependency between the client object and the
dependent object does not occur directly.
With DI the client object does not necessarily
manage the lifecycle of the dependent object.
Instead with DI a special DI container takes care of
the object lifecycle management
21. Dependency Injection (DI) is a runtime mechanism
where dependency between the client object and the
dependent object does not occur directly.
With DI the client object does not necessarily
manage the lifecycle of the dependent object.
Instead with DI a special DI container takes care of
the object lifecycle management where clients
reference managed and possibly shared objects.
47. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
• Instances and Scopes
• EventBus and other DI Extensions
• Tips and Tricks for Springifying your Vaadin app
55. Implement View and
annotate with
@SpringView
VIEW AS BEAN
@SpringView(name = "customers")
public class CustomerView extends VerticalLayout
implements View {
56. Wrapper for View
Component in UI
VIEWDISPLAY
@SpringViewDisplay
public class DevDayViewDisplay
extends VerticalSplitPanel
implements ViewDisplay {
57. S p r i n g V i e w P r o v i d e r
SPRING NAVIGATOR
63. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
• Instances and Scopes
• EventBus and other DI Extensions
• Tips and Tricks for Springifying your Vaadin app
64. H o w a r e t h e b e a n
i n s t a n c e s m a n a g e d ?
68. @ S e s s i o n S c o p e
@ Va a d i n S e s s i o n S c o p e
WITH SCOPES
69. @ S e s s i o n S c o p e
@ Va a d i n S e s s i o n S c o p e
@ U I S c o p e
WITH SCOPES
70. public interface MainMenu { … }
@Autowired
private MainMenu mainMenu;
@Component
@UIScope
public class DefaultMainMenu implements MainMenu { … }
@ U I S c o p e
71. @ S e s s i o n S c o p e
@ Va a d i n S e s s i o n S c o p e
@ U I S c o p e
@ V i e w S c o p e
WITH SCOPES
83. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
• Instances and Scopes
• EventBus and other DI Extensions
• Tips and Tricks for Springifying your Vaadin app
84. E v e n t B u s
@Component
@ViewScope
public class DataEditor<DTO> {
}
85. E v e n t B u s
@Component
@ViewScope
public class DataEditor<DTO> {
@Autowired
private EventBus.ViewEventBus eventBus;
…
}
86. E v e n t B u s
@Component
@ViewScope
public class DataEditor<DTO> {
@Autowired
private EventBus.ViewEventBus eventBus;
protected void onSaveClicked() {
eventBus.publish(this, new EditorSaveEvent());
}
…
}
91. Va a d i n I 1 8 N S u p p o r t
@EnableI18N
@Bean
I18N i18n() {
return new I18N(context);
}
92. Va a d i n I 1 8 N S u p p o r t
@EnableI18N
@Bean
I18N i18n() {
return new I18N(context);
}
@Bean
CompositeMessageSource messageSource() {
return new CompositeMessageSource(context);
}
93. Va a d i n I 1 8 N S u p p o r t
@Bean
MessageProvider provideTranslations() {
return new ResourceBundleMessageProvider
(“com.foo.path.to.bundle”, "UTF-8");
}
94. Session’s content
• What Dependency Injection, Why and How?
• Vaadin UI, View and components as Beans
• Instances and Scopes
• EventBus and other DI Extensions
• Tips and Tricks for Springifying your Vaadin app
95. S e t t i n g u p m e n u a u t o m a t i c a l l y
@MenuDefinition(icon=, name=, order=)
@SpringView(name=“customers”)
public class CustomerViewBean implements View… {
…
}
96. S e t t i n g u p m e n u a u t o m a t i c a l l y
private void findAndPopulateMenuItems() {
List<String> beanNames = Arrays.asList(context.
getBeanNamesForAnnotation(MenuDefinition.class));
}
97. S e t t i n g u p m e n u a u t o m a t i c a l l y
private void findAndPopulateMenuItems() {
List<String> beanNames = Arrays.asList(context.
getBeanNamesForAnnotation(MenuDefinition.class));
Map<String, MenuDefinition> definitionsToNames = beanNames.stream().
collect(Collectors.toMap(Function.identity(),
beanName -> context.findAnnotationOnBean(beanName, MenuDefinition.class)));
Map<String, SpringView> viewsToNames = beanNames.stream().
collect(Collectors.toMap(Function.identity(),
beanName -> context.findAnnotationOnBean(beanName, SpringView.class)));
}
98. S e t t i n g u p m e n u a u t o m a t i c a l l y
private void findAndPopulateMenuItems() {
List<String> beanNames = Arrays.asList(context.
getBeanNamesForAnnotation(MenuDefinition.class));
Map<String, MenuDefinition> definitionsToNames = beanNames.stream().
collect(Collectors.toMap(Function.identity(),
beanName -> context.findAnnotationOnBean(beanName, MenuDefinition.class)));
Map<String, SpringView> viewsToNames = beanNames.stream().
collect(Collectors.toMap(Function.identity(),
beanName -> context.findAnnotationOnBean(beanName, SpringView.class)));
beanNames.forEach(beanName -> {
MenuDefinition menuDefinition = definitionsToNames.get(beanName);
SpringView viewDefinition = viewsToNames.get(beanName);
addMenuItem(menuDefinition.name(), menuDefinition.icon(),
viewDefinition.name());
});
101. Lessons learned
• DI is a powerful mechanism to decouple code
• Following DI almost certainly guarantees that best practices
are followed
102. Lessons learned
• DI is a powerful mechanism to decouple code
• Following DI almost certainly guarantees that best practices
are followed
• Vaadin supports DI with Spring and CDI, both through their
own integration add-ons
103. Lessons learned
• DI is a powerful mechanism to decouple code
• Following DI almost certainly guarantees that best practices
are followed
• Vaadin supports DI with Spring and CDI, both through their
own integration add-ons
• Lot of Spring functionality is based on Beans
104. Lessons learned
• DI is a powerful mechanism to decouple code
• Following DI almost certainly guarantees that best practices
are followed
• Vaadin supports DI with Spring and CDI, both through their
own integration add-ons
• Lot of Spring functionality is based on Beans
• Structuring Vaadin app with Bean approach can provide
great flexibility and robustness