Techlunch - Dependency Injection with Vaadin

127
Dependency Injection with Programmatic Configuration Peter Lehto Senior Vaadin Expert @peter_lehto

Transcript of Techlunch - Dependency Injection with Vaadin

Page 1: Techlunch - Dependency Injection with Vaadin

Dependency Injection with Programmatic Configuration

Peter Lehto Senior Vaadin Expert

@peter_lehto

Page 2: Techlunch - Dependency Injection with Vaadin

Dependency Injection (DI) is a runtime mechanism

Page 3: Techlunch - Dependency Injection with Vaadin

Dependency Injection (DI) is a runtime mechanism

Page 4: Techlunch - Dependency Injection with Vaadin

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

Page 5: Techlunch - Dependency Injection with Vaadin

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

Page 6: Techlunch - Dependency Injection with Vaadin

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 7: Techlunch - Dependency Injection with Vaadin

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 8: Techlunch - Dependency Injection with Vaadin

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 9: Techlunch - Dependency Injection with Vaadin

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 10: Techlunch - Dependency Injection with Vaadin

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 11: Techlunch - Dependency Injection with Vaadin

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 12: Techlunch - Dependency Injection with Vaadin
Page 13: Techlunch - Dependency Injection with Vaadin
Page 14: Techlunch - Dependency Injection with Vaadin

Why…?

Page 15: Techlunch - Dependency Injection with Vaadin
Page 16: Techlunch - Dependency Injection with Vaadin

• Loose coupling

Page 17: Techlunch - Dependency Injection with Vaadin

• Loose coupling• Dependency inversion

Page 18: Techlunch - Dependency Injection with Vaadin

• Loose coupling• Dependency inversion• High Abstraction

Page 19: Techlunch - Dependency Injection with Vaadin

• Loose coupling• Dependency inversion• High Abstraction • Highly cohesive modules

Page 20: Techlunch - Dependency Injection with Vaadin

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

Page 21: Techlunch - Dependency Injection with Vaadin
Page 22: Techlunch - Dependency Injection with Vaadin

How…?

Page 23: Techlunch - Dependency Injection with Vaadin

CDI Context and Dependency Injection

Page 24: Techlunch - Dependency Injection with Vaadin

JSR-299 JavaEE specification

Page 25: Techlunch - Dependency Injection with Vaadin

Spring Framework

SpringBeans

Page 26: Techlunch - Dependency Injection with Vaadin
Page 27: Techlunch - Dependency Injection with Vaadin

• @Inject

Page 28: Techlunch - Dependency Injection with Vaadin

• @Inject• @Autowired

Page 29: Techlunch - Dependency Injection with Vaadin

• @Inject• @Autowired• @Qualifier

Page 30: Techlunch - Dependency Injection with Vaadin

• @Inject• @Autowired• @Qualifier• @Produces

Page 31: Techlunch - Dependency Injection with Vaadin

• @Inject• @Autowired• @Qualifier• @Produces• @Bean

Page 32: Techlunch - Dependency Injection with Vaadin

• @Inject• @Autowired• @Qualifier• @Produces• @Bean• @Component

Page 33: Techlunch - Dependency Injection with Vaadin
Page 34: Techlunch - Dependency Injection with Vaadin
Page 35: Techlunch - Dependency Injection with Vaadin

Example?

Page 36: Techlunch - Dependency Injection with Vaadin

public interface VehicleService {

void performService(Vehicle vehicle);

}

Page 37: Techlunch - Dependency Injection with Vaadin

@Named("Audi")public class AudiService implements VehicleService {

@Overridepublic void performService(Vehicle vehicle) {System.out.println("Performing Audi service");

}}

Page 38: Techlunch - Dependency Injection with Vaadin

@Named("BMW")public class BMWService implements VehicleService {

@Overridepublic void performService(Vehicle vehicle) {System.out.println("Performing BMW service");

}}

Page 39: Techlunch - Dependency Injection with Vaadin

@Named("VW")public class VWService implements VehicleService {

@Overridepublic void performService(Vehicle vehicle) {System.out.println("Performing VW service");

}}

Page 40: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

@Inject@Named("Audi")private VehicleService audiService;

}

Page 41: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

@Inject@Named("Audi")private VehicleService audiService;

@Inject@Named("BMW")private VehicleService bmwService;

}

Page 42: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

@Inject@Named("Audi")private VehicleService audiService;

@Inject@Named("BMW")private VehicleService bmwService;

@Inject@Named("VW")private VehicleService vwService;

}

Page 43: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

@Inject@Named("Audi")private VehicleService audiService;

@Inject@Named("BMW")private VehicleService bmwService;

@Inject@Named("VW")private VehicleService vwService;

public void operate(Vehicle vehicle) {audiService.performService(vehicle);

}}

Page 44: Techlunch - Dependency Injection with Vaadin

Setter Injection

For interfering purposes

Page 45: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

private VehicleService audiService;private VehicleService bmwService;private VehicleService vwService;

Page 46: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

private VehicleService audiService;private VehicleService bmwService;private VehicleService vwService;

@Injectpublic void setAudiService(@Named("Audi") VehicleService audiService) {

this.audiService = audiService;}

Page 47: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

private VehicleService audiService;private VehicleService bmwService;private VehicleService vwService;

@Injectpublic void setAudiService(@Named("Audi") VehicleService audiService) {

this.audiService = audiService;}

@Injectpublic void setBMWService(@Named("BMW") VehicleService bmwService) {

this.bmwService = bmwService;}

Page 48: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

private VehicleService audiService;private VehicleService bmwService;private VehicleService vwService;

@Injectpublic void setAudiService(@Named("Audi") VehicleService audiService) {

this.audiService = audiService;}

@Injectpublic void setBMWService(@Named("BMW") VehicleService bmwService) {

this.bmwService = bmwService;}

@Injectpublic void setVWService(@Named("VW") VehicleService vwService) {

this.vwService = vwService;}

Page 49: Techlunch - Dependency Injection with Vaadin

Constructor Injection

For injecting at initialisation time

Page 50: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

private VehicleService audiService;private VehicleService bmwService;private VehicleService vwService;

Page 51: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

private VehicleService audiService;private VehicleService bmwService;private VehicleService vwService;

@Injectpublic VehicleOperator(@Named("Audi") VehicleService audiService,

@Named("BMW") VehicleService bmwService, @Named("VW") VehicleService vwService) {

this.audiService = audiService;…

}

Page 52: Techlunch - Dependency Injection with Vaadin

Producer method

For programmatic bean manipulation

Page 53: Techlunch - Dependency Injection with Vaadin

public class VehicleServiceFactory {

}

Page 54: Techlunch - Dependency Injection with Vaadin

public class VehicleServiceFactory {

@Produces@Named("VW")protected VehicleService produceVWService() {

}

}

Page 55: Techlunch - Dependency Injection with Vaadin

public class VehicleServiceFactory {

@Produces@Named("VW")protected VehicleService produceVWService() {

VehicleService vwService = ServiceProvider.provideVWService();vwService.enableEmissionManipulation(true);return vwService;

}

}

Page 56: Techlunch - Dependency Injection with Vaadin

Avoid ambiguity

with @Vetoed, @Alternative or @Primary

Page 57: Techlunch - Dependency Injection with Vaadin

Programmatic Injection

With Instance<T>

Page 58: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

}

Page 59: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

@Inject@Named("BMW")private Instance<VehicleService> serviceInstantiator;

}

Page 60: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

@Inject@Named("BMW")private Instance<VehicleService> serviceInstantiator;

public void operate(Vehicle vehicle) {VehicleService service = serviceInstantiator.get();

}}

Page 61: Techlunch - Dependency Injection with Vaadin

public class VehicleOperator {

@Inject@Named("BMW")private Instance<VehicleService> serviceInstantiator;

public void operate(Vehicle vehicle) {VehicleService service = serviceInstantiator.get();service.performService(vehicle);

}}

Page 62: Techlunch - Dependency Injection with Vaadin

Programmatic Configuration!

As promised :)

Page 63: Techlunch - Dependency Injection with Vaadin

public class Vehicle {

public String getMake() {return "BMW";

}

}

Page 64: Techlunch - Dependency Injection with Vaadin

public class NamedLiteral extends AnnotationLiteral<Named> implements Named

Page 65: Techlunch - Dependency Injection with Vaadin

public class VehicleOperater {

Page 66: Techlunch - Dependency Injection with Vaadin

public class VehicleOperater {

@Inject@Anyprivate Instance<VehicleService> serviceInstantiator;

}

Page 67: Techlunch - Dependency Injection with Vaadin

public class VehicleOperater {

@Inject@Anyprivate Instance<VehicleService> serviceInstantiator;

public void operate(Vehicle vehicle) {NamedLiteral named = new NamedLiteral(vehicle.getMake());

}}

Page 68: Techlunch - Dependency Injection with Vaadin

public class VehicleOperater {

@Inject@Anyprivate Instance<VehicleService> serviceInstantiator;

public void operate(Vehicle vehicle) {NamedLiteral named = new NamedLiteral(vehicle.getMake());VehicleService service = serviceInstantiator.select(named).get();

}}

Page 69: Techlunch - Dependency Injection with Vaadin

public interface TaskProcessor {

void processTask(Task task);

}

Page 70: Techlunch - Dependency Injection with Vaadin

@AsynchronousProcessingpublic class ReportingTask implements Task {

}

Page 71: Techlunch - Dependency Injection with Vaadin

@AsynchronousProcessingpublic class ReportingTask implements Task {

}

@SynchronousProcessingpublic class SaveDataTask implements Task {

}

Page 72: Techlunch - Dependency Injection with Vaadin

@AsynchronousProcessingpublic class AsynchronousTaskProcessor implements TaskProcessor {

@Overridepublic void processTask(Task task) {

}}

Page 73: Techlunch - Dependency Injection with Vaadin

@AsynchronousProcessingpublic class AsynchronousTaskProcessor implements TaskProcessor {

@Overridepublic void processTask(Task task) {

}}

@SynchronousProcessingpublic class SynchronousTaskProcessor implements TaskProcessor {

@Overridepublic void processTask(Task task) {

}}

Page 74: Techlunch - Dependency Injection with Vaadin

public class TaskHandler {

@Inject@Anyprivate Instance<TaskProcessor> processorInstantiator;

}

Page 75: Techlunch - Dependency Injection with Vaadin

public class TaskHandler {

@Inject@Anyprivate Instance<TaskProcessor> processorInstantiator;

public void handleTasks(List<Task> tasks) {tasks.forEach(task -> {

processorInstantiator.select(task.getClass().getAnnotations()).get(). processTask(task);

});}

}

Page 76: Techlunch - Dependency Injection with Vaadin
Page 77: Techlunch - Dependency Injection with Vaadin

Vaadin with CDI

Page 78: Techlunch - Dependency Injection with Vaadin

public class MyVaadinUI extends UI {

}

Page 79: Techlunch - Dependency Injection with Vaadin

@CDIUI("")public class MyVaadinUI extends UI {

}

Page 80: Techlunch - Dependency Injection with Vaadin

@CDIUI("")public class MyVaadinUI extends UI {

@Injectprivate MainMenu mainMenu;

@Injectprivate ViewArea viewArea;

}

Page 81: Techlunch - Dependency Injection with Vaadin

@CDIUI("")public class MyVaadinUI extends UI {

@Injectprivate MainMenu mainMenu;

@Injectprivate ViewArea viewArea;

@Overrideprotected void init(VaadinRequest request) {

HorizontalLayout hl = new HorizontalLayout(mainMenu, viewArea);

…setContent(hl);

}}

Page 82: Techlunch - Dependency Injection with Vaadin

UI as managed bean

Page 83: Techlunch - Dependency Injection with Vaadin

Entry point

UI as managed bean

Page 84: Techlunch - Dependency Injection with Vaadin

Entry point

Context aware

UI as managed bean

Page 85: Techlunch - Dependency Injection with Vaadin

Entry point

Context aware

Accesible through URI

UI as managed bean

Page 86: Techlunch - Dependency Injection with Vaadin

@CDIUI("")public class MyVaadinUI extends UI {

@Injectprivate MainMenu mainMenu;

@Injectprivate ViewArea viewArea;

@Overrideprotected void init(VaadinRequest request) {

HorizontalLayout hl = new HorizontalLayout(mainMenu, viewArea);

…setContent(hl);

}}

Page 87: Techlunch - Dependency Injection with Vaadin

@CDIUI("anotherUI")public class MyVaadinUI extends UI {

@Injectprivate MainMenu mainMenu;

@Injectprivate ViewArea viewArea;

@Overrideprotected void init(VaadinRequest request) {

HorizontalLayout hl = new HorizontalLayout(mainMenu, viewArea);

…setContent(hl);

}}

Page 88: Techlunch - Dependency Injection with Vaadin

http://localhost:8080/app/

http://localhost:8080/app/anotherUI

app: contextanotherUI : UI name

Page 89: Techlunch - Dependency Injection with Vaadin

Scope UI specific beans with

@UIScoped

Page 90: Techlunch - Dependency Injection with Vaadin

@UIScopedpublic class MainMenuBean extends CssLayout implements MainMenu

Page 91: Techlunch - Dependency Injection with Vaadin

@UIScoped

Page 92: Techlunch - Dependency Injection with Vaadin

Bean associated with UI instance

@UIScoped

Page 93: Techlunch - Dependency Injection with Vaadin

Bean associated with UI instance

Bean associated with Web browser tab

@UIScoped

Page 94: Techlunch - Dependency Injection with Vaadin

Bean associated with UI instance

Bean associated with Web browser tab

@CDIUI is by default @UIScoped

@UIScoped

Page 95: Techlunch - Dependency Injection with Vaadin

@CDIUI MyVaadinUI

_____________________________

@Injectprivate MainMenu menu;

@Injectprivate User currentUser;

@UIScoped

MyVaadinUIMainMenu

@SessionScoped

User

Page 96: Techlunch - Dependency Injection with Vaadin

@CDIUI MyVaadinUI

_____________________________

@Injectprivate MainMenu menu;

@Injectprivate User currentUser;

@UIScoped

MyVaadinUIMainMenu

@SessionScoped

User

@CDIUI MyVaadinUI

_____________________________

@Injectprivate MainMenu menu;

@Injectprivate User currentUser;

@CDIUI MyVaadinUI

_____________________________

@Injectprivate MainMenu menu;

@Injectprivate User currentUser;

@UIScoped

MyVaadinUIMainMenu

@UIScoped

MyVaadinUIMainMenu

Page 97: Techlunch - Dependency Injection with Vaadin

What about Views?

Page 98: Techlunch - Dependency Injection with Vaadin

View

Page 99: Techlunch - Dependency Injection with Vaadin

Component composition

View

Page 100: Techlunch - Dependency Injection with Vaadin

Component composition

Active view switched by Navigator

View

Page 101: Techlunch - Dependency Injection with Vaadin

Component composition

Active view switched by Navigator

Positioned inside ViewDisplay

View

Page 102: Techlunch - Dependency Injection with Vaadin

HorizontalLayoutContentAreaMenu

View1

View2

View3

Page 103: Techlunch - Dependency Injection with Vaadin

HorizontalLayoutView1Menu

View1

View2

View3

Page 104: Techlunch - Dependency Injection with Vaadin

HorizontalLayoutView2Menu

View1

View2

View3

Page 105: Techlunch - Dependency Injection with Vaadin

HorizontalLayoutView3Menu

View1

View2

View3

Page 106: Techlunch - Dependency Injection with Vaadin

View as managed bean with

@CDIView

Page 107: Techlunch - Dependency Injection with Vaadin

public class CustomerViewBean

Page 108: Techlunch - Dependency Injection with Vaadin

public class CustomerViewBean extends VerticalLayout

Page 109: Techlunch - Dependency Injection with Vaadin

@CDIView("customers")public class CustomerViewBean extends VerticalLayout implements View

Page 110: Techlunch - Dependency Injection with Vaadin

http://localhost:8080/app/#!customers

#! : Navigator identifiercustomers : View name

Page 111: Techlunch - Dependency Injection with Vaadin

Scope View specific beans with

@ViewScoped

Page 112: Techlunch - Dependency Injection with Vaadin

@ViewScoped

Page 113: Techlunch - Dependency Injection with Vaadin

Beans associated with View

@ViewScoped

Page 114: Techlunch - Dependency Injection with Vaadin

Beans associated with View

@CDIView by default @ViewScoped

@ViewScoped

Page 115: Techlunch - Dependency Injection with Vaadin

@ApplicationScoped

Page 116: Techlunch - Dependency Injection with Vaadin

@ApplicationScoped@ApplicationScoped

@SessionScoped @SessionScoped @SessionScoped

Page 117: Techlunch - Dependency Injection with Vaadin

@ApplicationScoped

@SessionScoped @SessionScoped @SessionScoped

@UI Scoped

@UI Scoped

@UI Scoped

@UI Scoped

@UI Scoped

@UI Scoped

Page 118: Techlunch - Dependency Injection with Vaadin

@ApplicationScoped

@ View

@ View

@ View

@ View

@ View

@ View

@ View

@ View

@ View

@ View

@ View

@ View

@SessionScoped @SessionScoped @SessionScoped

@UI Scoped

@UI Scoped

@UI Scoped

@UI Scoped

@UI Scoped

@UI Scoped

Page 119: Techlunch - Dependency Injection with Vaadin

Lessons learned

Page 120: Techlunch - Dependency Injection with Vaadin

Lessons learned

1. Depend on abstractions through Dependency Inversion

Page 121: Techlunch - Dependency Injection with Vaadin

Lessons learned

1. Depend on abstractions through Dependency Inversion

2. Beans need to be managed by (CDI) container

Page 122: Techlunch - Dependency Injection with Vaadin

Lessons learned

1. Depend on abstractions through Dependency Inversion

2. Beans need to be managed by (CDI) container

3. Inject to Fields, Methods and Constructor

Page 123: Techlunch - Dependency Injection with Vaadin

Lessons learned

1. Depend on abstractions through Dependency Inversion

2. Beans need to be managed by (CDI) container

3. Inject to Fields, Methods and Constructor

4. Producer method allows programmatic bean creation and non-default constructor

Page 124: Techlunch - Dependency Injection with Vaadin

Lessons learned

1. Depend on abstractions through Dependency Inversion

2. Beans need to be managed by (CDI) container

3. Inject to Fields, Methods and Constructor

4. Producer method allows programmatic bean creation and non-default constructor

5. Instance<T> provides on-demand instantiation with candidate selection

Page 125: Techlunch - Dependency Injection with Vaadin

Lessons learned

1. Depend on abstractions through Dependency Inversion

2. Beans need to be managed by (CDI) container

3. Inject to Fields, Methods and Constructor

4. Producer method allows programmatic bean creation and non-default constructor

5. Instance<T> provides on-demand instantiation with candidate selection

6. Use CDIUI and CDIView for making core Vaadin concepts managed beans

Page 126: Techlunch - Dependency Injection with Vaadin

I would NOT start a single new Vaadin project without

Dependency Injection!

Page 127: Techlunch - Dependency Injection with Vaadin

Thank you!