77
VAADIN WITH SPRING THINK WITH BEANS! @peter_lehto

Vaadin 8 with Spring Framework

Embed Size (px)

Citation preview

Page 1: Vaadin 8 with Spring Framework

VA A D I N W I T H S P R I N G

THINK WITH BEANS!

@peter_lehto

Page 2: Vaadin 8 with Spring Framework

Session’s content• Dependency Injection (DI) Briefly

• Setting up UI, ViewDisplay and Views as Beans

• Navigation, ViewAccessControl

• Securing with Spring Security

• EventBus and other DI Extensions

• Tips and Tricks for Springifying your Vaadin app

Page 3: Vaadin 8 with Spring Framework

Session’s content• Dependency Injection (DI) Briefly

• Setting up UI, ViewDisplay and Views as Beans

• Navigation, ViewAccessControl

• Securing with Spring Security

• EventBus and other DI Extensions

• Tips and Tricks for Springifying your Vaadin app

Page 4: Vaadin 8 with Spring Framework

W h a t D e p e n d e n c y I n j e c t i o n ?

Page 5: Vaadin 8 with Spring Framework

Dependency Injection (DI) is a runtime mechanism

Page 6: Vaadin 8 with Spring Framework

Dependency Injection (DI) is a runtime mechanism

Page 7: Vaadin 8 with Spring Framework

Dependency Injection (DI) is a runtime mechanism where dependency between the client object and the dependent object does not occur directly.

Page 8: Vaadin 8 with Spring Framework

Dependency Injection (DI) is a runtime mechanism where dependency between the client object and the dependent object does not occur directly.

Page 9: Vaadin 8 with Spring Framework

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.

Page 10: Vaadin 8 with Spring Framework

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.

Page 11: Vaadin 8 with Spring Framework

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

Page 12: Vaadin 8 with Spring Framework

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

Page 13: Vaadin 8 with Spring Framework

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.

Page 14: Vaadin 8 with Spring Framework

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.

Page 15: Vaadin 8 with Spring Framework

T L ; D R

public interface MainMenu { … }

Page 16: Vaadin 8 with Spring Framework

T L ; D R

public interface MainMenu { … }

public class DefaultMainMenu implements MainMenu { … }

Page 17: Vaadin 8 with Spring Framework

T L ; D R

public interface MainMenu { … }

public class DefaultMainMenu implements MainMenu { … }

public class ResponsiveMainMenu implements MainMenu { … }

Page 18: Vaadin 8 with Spring Framework

T L ; D R

public interface MainMenu { … }

public class DefaultMainMenu implements MainMenu { … }

public class ResponsiveMainMenu implements MainMenu { … }

@Autowiredprivate MainMenu mainMenu;

Page 19: Vaadin 8 with Spring Framework

W h y ?

Page 20: Vaadin 8 with Spring Framework

• Loose coupling• Dependency inversion• High Abstraction • Highly cohesive modules• Deployment time config

Page 21: Vaadin 8 with Spring Framework

H o w ?

Page 22: Vaadin 8 with Spring Framework

@SpringComponentpublic class DefaultMainMenu implements MainMenu { … }

D e f i n e B e a n

Page 23: Vaadin 8 with Spring Framework

@SpringComponent@UIScopepublic class DefaultMainMenu implements MainMenu { … }

D e f i n e B e a n

Page 24: Vaadin 8 with Spring Framework

@Configurationpublic class ComponentConfiguration {

@Bean @Primary public MainMenu provideDefaultMenu { return new DefaultMainMenu(); }

D e f i n e B e a n

Page 25: Vaadin 8 with Spring Framework

@Bean @Responsive public MainMenu provideResponsiveMenu { return new ResponsiveMainMenu(); }}

Page 26: Vaadin 8 with Spring Framework

W i t h @ A u t o w i r e d a n d

MANAGED BEANS

Page 27: Vaadin 8 with Spring Framework

Session’s content• Dependency Injection (DI) Briefly

• Setting up UI, ViewDisplay and Views a Beans

• Navigation, ViewAccessControl

• Securing with Spring Security

• EventBus and other DI Extensions

• Tips and Tricks for Springifying your Vaadin app

Page 28: Vaadin 8 with Spring Framework

Automatic discoveryand lookup

UI AS BEAN@SpringUIpublic class DevDayTestUI extends UI {

Page 29: Vaadin 8 with Spring Framework

path attribute forURL binding

UI AS BEAN

@SpringUI(path = "app")public class DevDayTestUI extends UI {

@SpringUIpublic class DevDayTestUI extends UI {

Page 30: Vaadin 8 with Spring Framework

localhost:8080/context

UI AS BEAN

localhost:8080/context/app @SpringUI(path = "app")public class DevDayTestUI extends UI {

@SpringUIpublic class DevDayTestUI extends UI {

Page 31: Vaadin 8 with Spring Framework

HorizontalLayoutContentAreaMenu

View1

View2

View3

Page 32: Vaadin 8 with Spring Framework

HorizontalLayoutView1Menu

View1

View2

View3

Page 33: Vaadin 8 with Spring Framework

HorizontalLayoutView2Menu

View1

View2

View3

Page 34: Vaadin 8 with Spring Framework

HorizontalLayoutView3Menu

View1

View2

View3

Page 35: Vaadin 8 with Spring Framework

Implement View andannotate with @SpringView

VIEW AS BEAN@SpringView(name = "customers")public class CustomerView extends VerticalLayout implements View {

Page 36: Vaadin 8 with Spring Framework

Wrapper for ViewComponent in UI

VIEWDISPLAY@SpringViewDisplaypublic class DevDayViewDisplay extends VerticalSplitPanel implements ViewDisplay {

Page 37: Vaadin 8 with Spring Framework

S p r i n g B o o t

AUTO CONFIGURATION

S e t s e v e r y t h i n g u p

Page 38: Vaadin 8 with Spring Framework

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 ?

Page 39: Vaadin 8 with Spring Framework

WITH SCOPES

Page 40: Vaadin 8 with Spring Framework

@ S e s s i o n S c o p e

WITH SCOPES

Page 41: Vaadin 8 with Spring Framework

@Autowiredprivate User currentUser;

@ S e s s i o n S c o p e

Page 42: Vaadin 8 with Spring Framework

@ S e s s i o n S c o p e@ U I S c o p e

WITH SCOPES

Page 43: Vaadin 8 with Spring Framework

public interface MainMenu { … }

@Autowiredprivate MainMenu mainMenu;

@SpringComponent@UIScopepublic class DefaultMainMenu implements MainMenu { … }

@ U I S c o p e

Page 44: Vaadin 8 with Spring Framework

@ 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

Page 45: Vaadin 8 with Spring Framework

@SpringComponent@ViewScopepublic class DataTable {

@Autowired private EventBus.ViewEventBus eventBus;

@ V i e w S c o p e

Page 46: Vaadin 8 with Spring Framework

@ 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@ R e q u e s t S c o p e

WITH SCOPES

Page 47: Vaadin 8 with Spring Framework

public interface HttpRequestStopWatch { … }

@ R e q u e s t S c o p e

Page 48: Vaadin 8 with Spring Framework

Session’s content• Dependency Injection (DI) Briefly

• Setting up UI, ViewDisplay and Views a Beans

• Navigation, ViewAccessControl

• Securing with Spring Security

• EventBus and other DI Extensions

• Tips and Tricks for Springifying your Vaadin app

Page 49: Vaadin 8 with Spring Framework

S p r i n g V i e w P r o v i d e r

SPRING NAVIGATOR

Page 50: Vaadin 8 with Spring Framework

@Autowiredprivate Navigator navigator;

navigator.navigateTo(“customers”);

N a v i g a t o r

Page 51: Vaadin 8 with Spring Framework

V i e w b e a n d i s c o v e r y b y @ S p r i n g V i e w

SPRING NAVIGATOR

Page 52: Vaadin 8 with Spring Framework

public interface ViewAccessControl;public interface ViewInstanceAccessControl;

C o n t r o l l i n g a c c e s s t o v i e w s

Page 53: Vaadin 8 with Spring Framework

public interface ViewAccessControl;public interface ViewInstanceAccessControl;

C o n t r o l l i n g a c c e s s t o v i e w s

WITHOUT SPRING SECURITY

Page 54: Vaadin 8 with Spring Framework

Session’s content• Dependency Injection (DI) Briefly

• Setting up UI, ViewDisplay and Views a Beans

• Navigation, ViewAccessControl

• Securing with Spring Security

• EventBus and other DI Extensions

• Tips and Tricks for Springifying your Vaadin app

Page 55: Vaadin 8 with Spring Framework

E n a b l i n g S p r i n g S e c u r i t yw i t h S p r i n g B o o t

@EnableVaadinManagedSecurity

Page 56: Vaadin 8 with Spring Framework

Va a d i n M a n a g e d S e c u r i t y

• Vaadin will manage Spring’s SecurityContext

• Disable auto configuration for SpringSecurity

• Vaadin app is the only web app secured

• Signing in and out takes place through Vaadin UI

• @PreAuthorize and @Secured

Page 57: Vaadin 8 with Spring Framework

E n a b l i n g S p r i n g S e c u r i t yw i t h S p r i n g B o o t

@EnableVaadinSharedSecurity

Page 58: Vaadin 8 with Spring Framework

Va a d i n S h a r e d S e c u r i t y

• Vaadin behaves as regular web app secured by Spring

• Signing in and out may take place outside Vaadin

• Manual Spring Security configuration needed

• Web Socket based @Push not available due to HTTP Filters

• @PreAuthorize and @Secured

Page 59: Vaadin 8 with Spring Framework

Session’s content• Dependency Injection (DI) Briefly

• Setting up UI, ViewDisplay and Views a Beans

• Navigation, ViewAccessControl

• Securing with Spring Security

• EventBus and other DI Extensions

• Tips and Tricks for Springifying your Vaadin app

Page 60: Vaadin 8 with Spring Framework

E v e n t B u s@SpringComponent@ViewScopepublic class DataEditor<DTO> {

}

Page 61: Vaadin 8 with Spring Framework

E v e n t B u s@SpringComponent@ViewScopepublic class DataEditor<DTO> {

@Autowiredprivate EventBus.ViewEventBus eventBus;

…}

Page 62: Vaadin 8 with Spring Framework

E v e n t B u s@SpringComponent@ViewScopepublic class DataEditor<DTO> {

@Autowiredprivate EventBus.ViewEventBus eventBus;

protected void onSaveClicked() {eventBus.publish(this, new EditorSaveEvent());

}…

}

Page 63: Vaadin 8 with Spring Framework

@SpringComponent@ViewScopepublic class DataTable<DTO> extends Grid<DTO> {

@Autowiredprivate EventBus.ViewEventBus eventBus;

}

Page 64: Vaadin 8 with Spring Framework

@SpringComponent@ViewScopepublic class DataTable<DTO> extends Grid<DTO> {

@Autowiredprivate EventBus.ViewEventBus eventBus;

@PostConstructprotected void initialize() {eventBus.subscribe(this);

}

}

Page 65: Vaadin 8 with Spring Framework

@SpringComponent@ViewScopepublic class DataTable<DTO> extends Grid<DTO> {

@Autowiredprivate EventBus.ViewEventBus eventBus;

@PostConstructprotected void initialize() {eventBus.subscribe(this);

}

@EventBusListenerMethodprotected void onSaveEvent(EditorSaveEvent e) {getDataProvider().refreshAll();

}}

Page 66: Vaadin 8 with Spring Framework

Session’s content• Dependency Injection (DI) Briefly

• Setting up UI, ViewDisplay and Views a Beans

• Navigation, ViewAccessControl

• Securing with Spring Security

• EventBus and other DI Extensions

• Tips and Tricks for Springifying your Vaadin app

Page 67: Vaadin 8 with Spring Framework

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… {

…}

Page 68: Vaadin 8 with Spring Framework

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));

}

Page 69: Vaadin 8 with Spring Framework

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)));

}

Page 70: Vaadin 8 with Spring Framework

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()); }); }

Page 71: Vaadin 8 with Spring Framework

Va a d i n I 1 8 N S u p p o r t

@EnableI18N

Page 72: Vaadin 8 with Spring Framework

Va a d i n I 1 8 N S u p p o r t

@EnableI18N

@BeanI18N i18n() { return new I18N(context);}

Page 73: Vaadin 8 with Spring Framework

Va a d i n I 1 8 N S u p p o r t

@EnableI18N

@BeanI18N i18n() { return new I18N(context);}

@BeanCompositeMessageSource messageSource() { return new CompositeMessageSource(context);}

Page 74: Vaadin 8 with Spring Framework

Va a d i n I 1 8 N S u p p o r t

@BeanMessageProvider provideTranslations() { return new ResourceBundleMessageProvider (“com.foo.path.to.bundle”, "UTF-8");}

Page 75: Vaadin 8 with Spring Framework

P r o g r a m m a t i c B e a n L o o k u p

@Componentpublic class GenericBeanResolver { … }

Page 76: Vaadin 8 with Spring Framework

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 addons

• Lot of Spring functionality is based on Beans

• Structuring Vaadin app with Bean approach can provide great flexibility and robustness

Page 77: Vaadin 8 with Spring Framework

T H A N K Y O U !

PLEASE RATE THE TALK @

FLIP CHART BY THE DOOR!

@peter_lehto