97
Java New School Enterprise Architecture Lars Röwekamp | open knowledge GmbH @mobileLarson @_openknowledge

New School Enterprise Architecture

Embed Size (px)

DESCRIPTION

Speaker: Lars Röwekamp JAX 2013 23.4.2013 | 16.15 - 17.15 Uhr Dank des aktuellen Java-EE-Stacks lassen sich heute Architekturen realisieren, von denen man zu Zeiten von J2EE nur träumen durfte. Nahezu losgelöst von technologischen und schichtenbedingten Restriktionen kommen völlig neue Patterns zum Tragen. Im Gegenzug dazu kann auf "lieb gewonnene" Workarounds - aka J2EE Pattern - verzichtet werden. Die Session gibt einen Einblick in die vielfältigen Möglichkeiten und möchte so zu neuen Denkmustern im Java-EE-Architekturdesign anregen.

Citation preview

Page 1: New School Enterprise Architecture

Java

New School Enterprise ArchitectureLars Röwekamp | open knowledge GmbH

@mobileLarson@_openknowledge

Page 2: New School Enterprise Architecture

„Fachlichkeit im Fokus!“

„Java EE 6 und 7 erlauben neben

Infrastructure Injection auch

Business Injection.“

Was sie mitnehmen sollten ...New School Enterprise Architecture

Page 3: New School Enterprise Architecture

„Fachlichkeit im Fokus!“

„Java EE 6 und 7 erlauben neben

Infrastructure Injection auch

Business Injection.“

Was sie mitnehmen sollten ...New School Enterprise Architecture

Page 4: New School Enterprise Architecture

Ok, was heißt das?

Page 5: New School Enterprise Architecture

New School

Call Center Anwendung

‣ Kunde neu erfassen und speichern‣ Call Center Agent als Audit Info mit speichern‣ Begrüßungs-EMail an Neukunden versenden

‣ Kunde löschen inkl. Sicherheitsabfrage‣ Call Center Agent als Audit Info mit speichern‣ EMail an ehemaligen Kunden versenden

Der Use CaseEnterprise Architecture

Page 6: New School Enterprise Architecture

New School

Call Center Anwendung

‣ Kunde neu erfassen und speichern‣ Call Center Agent als Audit Info mit speichern‣ Begrüßungs-EMail an Neukunden versenden

‣ Kunde löschen inkl. Sicherheitsabfrage‣ Call Center Agent als Audit Info mit speichern‣ EMail an ehemaligen Kunden versenden

Der Use CaseEnterprise Architecture

Page 7: New School Enterprise Architecture

Old School

Page 8: New School Enterprise Architecture

New School

Use Case: Kunde neu erfassen

‣ JSF View ruft UI Controller via U-EL‣ UI Controller ruft CustomerService EJB‣ UI Controller ruft MailService EJB

Enterprise ArchitectureOld School Ansatz

Page 9: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

UI

Service

Data

JSF View

CreateCustomer

Page 10: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

UI

Service

Data

JSF View

CreateCustomer

CustService MailService

Page 11: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

UI

Service

Data

JSF View

CreateCustomer

CustService MailService

Customer Mail

Page 12: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// JSF UI [email protected]@javax.faces.bean.ManagedBean(name=“createCustomerController“)public class CreateCustomerController {

@EJB private CustomerService customerService;

@EJB private MailService mailService; private Customer customer;

public String createCustomer() { customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED; }

// getter / setter for customer...

}

Page 13: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// JSF UI [email protected]@javax.faces.bean.ManagedBean(name=“createCustomerController“)public class CreateCustomerController {

@EJB private CustomerService customerService;

@EJB private MailService mailService; private Customer customer;

public String createCustomer() { customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED; }

// getter / setter for customer...

}

Und was ist mit dem Call Center Agent?

Page 14: New School Enterprise Architecture

New School

Use Case: Kunde neu erfassen

‣ JSF View ruft UI Controller via U-EL‣ UI Controller ruft CustomerService EJB‣ UI Controller ruft MailService EJB‣ UI Controller ruft AuthenticationController

Enterprise ArchitectureOld School Ansatz

Page 15: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

JSF View

CreateCustomer AuthController

Page 16: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

JSF View

CreateCustomer

CCAgent

AuthService

AuthController

Page 17: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

JSF View

CreateCustomer

CCAgent

AuthService

Customer

CustService

AuthController

Page 18: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

JSF View

CreateCustomer

CCAgent

AuthService

Mail

MailService

Customer

CustService

AuthController

Page 19: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// JSF UI [email protected]@javax.faces.bean.ManagedBean(name=“createCustomerController“)public class CreateCustomerController {

// inject CustomerService and MailService via @EJB

@ManagedProperty(value=“#{authenticationController}“) private AuthenticationController authController; ...

public String createCustomer() { CallCenterAgent currentCallCenterAgent; currentCallCenterAgent = authController.getLoggedInUser();

customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED;}

// getter / setter for customer...

}

Page 20: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// JSF UI [email protected]@javax.faces.bean.ManagedBean(name=“createCustomerController“)public class CreateCustomerController {

// inject CustomerService and MailService via @EJB

@ManagedProperty(value=“#{authenticationController}“) private AuthenticationController authController; ...

public String createCustomer() { CallCenterAgent currentCallCenterAgent; currentCallCenterAgent = authController.getLoggedInUser();

customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED;}

// getter / setter for customer...

}

Ok, aber wo wird die Transaktion aufgezogen?

Page 21: New School Enterprise Architecture

New School

Use Case: Kunde neu erfassen

‣ JSF View ruft UI Controller via U-EL‣ UI Controller ruft AuthenticationController‣ UI Controller ruft CustomerFacade EJB‣ Delegate EJB ruft CustomerService EJB‣ Delegate EJB ruft MailService EJB

Enterprise ArchitectureOld School Ansatz

Page 22: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

CreateCustomer

AuthService

CCAgent

AuthController

Page 23: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

CreateCustomer

CustFacade

AuthService

CCAgent

AuthController

Page 24: New School Enterprise Architecture

TX

New School Enterprise Architecture

Old School Ansatz

CreateCustomer

CustFacade

AuthService

CCAgent

AuthController

Page 25: New School Enterprise Architecture

TX

New School Enterprise Architecture

Old School Ansatz

CreateCustomer

CustFacade

AuthService

CCAgent

CustService MailService

Customer Mail

AuthController

Page 26: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// JSF UI [email protected]@javax.faces.ManagedBean(name=“createCustomerController“)public class CreateCustomerController {

@EJB private CustomerFacade customerFacade;

@ManagedProperty(value=“#{authenticationController}“) private AuthenticationController authController; private Customer customer;

public String createCustomer() { CallCenterAgent currentCallCenterAgent; currentCallCenterAgent = authController.getLoggedInUser(); customerFacade.create(customer, currentCallCenterAgent); return CUSTOMER_CREATED; }

...}

Page 27: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// EJB Service Facade@Statelesspublic class CustomerFacade {

@EJB private CustomerService customerService

@EJBprivate MailService mailService;

// Transactional by default public void createCustomer(Customer customer, CallCenterAgent currentCallCenterAgent) {

customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); } ...

}

Page 28: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// EJB Service Facade@Statelesspublic class CustomerFacade {

@EJB private CustomerService customerService

@EJBprivate MailService mailService;

// Transactional by default public void createCustomer(Customer customer, CallCenterAgent currentCallCenterAgent) {

customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); } ...

}

Fühlt sich nicht gut an!Alternativen sind aber

auch nicht viel schöner!

Page 29: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

JSF View

CreateCustomer

AuthService

CCAgent

AuthController

Page 30: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

JSF View

CustService

CreateCustomer

AuthService

CCAgent

AuthController

Page 31: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

JSF View

CustService

CreateCustomer

AuthService

CCAgent

MailService

Customer Mail

AuthController

Page 32: New School Enterprise Architecture

New School

Use Case: Kunde löschen

‣ JSF View ruft UI Controller via U-EL‣ UI Controller „merkt“ sich Kunde in Session‣ UI Controller navigiert zu Bestätigungsseite‣ UI Controller bekommt Bestätigung‣ UI Controller ruft CustomerService EJB‣ ...

Enterprise ArchitectureOld School Ansatz

Page 33: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

UI

Service

Data

JSF View 1

DeleteCustomer

Page 34: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

UI

Service

Data

JSF View 1

DeleteCustomer

JSF View 2

Page 35: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

UI

Service

Data

JSF View 1

DeleteCustomer

CustService MailService

Customer Mail

JSF View 2

Page 36: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// JSF UI [email protected]@javax.faces.bean.ManagedBean(name=“deleteCustomerController“)public class DeleteCustomerController implements Serializable {

// @EJB CustomerService, AuthenticationService and MailService

private Customer customerToDelete; public String askForDeletion(Customer customer) { customerToDelete = customer; return SHOW_DELETE_CONFIRMATION;

}

public String deleteCustomer() { ... // call backend services and delete customer return CUSTOMER_DELETED;

} ...

}

Page 37: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

// JSF UI [email protected]@javax.faces.bean.ManagedBean(name=“deleteCustomerController“)public class DeleteCustomerController implements Serializable {

// @EJB CustomerService, AuthenticationService and MailService

private Customer customerToDelete; public String askForDeletion(Customer customer) { customerToDelete = customer; return SHOW_DELETE_CONFIRMATION;

}

public String deleteCustomer() { ... // call backend services and delete customer return CUSTOMER_DELETED;

} ...

} Wann kommt der Datensatz aus der Session wieder raus?

Page 38: New School Enterprise Architecture

New School

Problemkind Schichtenmodell

‣ UI Controller via JSF Managed Beans‣ Service Facade und Services via EJBs‣ Persistenz via EntityManager und Entities

‣ Alles nur Infrastruktur!‣Wo steckt eigentlich die fachliche Domain?

Enterprise ArchitectureOld School Ansatz

Page 39: New School Enterprise Architecture

New School Enterprise Architecture

Old School Ansatz

UI

Service

Data

JSF View

@ManagedBean (JSF)

Session EJB Session EJB

EntityManager Entity

TX

Page 40: New School Enterprise Architecture

New School Enterprise Architecture

Alternativer Ansatz

UI

Domain

JSF View

UseCaseController

Business Object

Business Object

Business Object

TX

Page 41: New School Enterprise Architecture

New School Enterprise Architecture

Alternativer Ansatz

UI

Domain

JSF View

UseCaseController

Business Object

Business Object

Business Object

TX

Page 42: New School Enterprise Architecture

Migration Guide

Page 43: New School Enterprise Architecture

New School

Page 44: New School Enterprise Architecture

New School

Migration Steps:

‣ „Technology Independence“‣ „@Inject Business Objects“‣ „No more EJBs for Transactions only“ ‣ „No more pumped up Sessions“‣ „No more Infrastructure in Views“‣ „No more doAll( ) Business Methods“

Enterprise ArchitectureMigration Guide

Page 45: New School Enterprise Architecture

New School

Migration Steps:

‣ „Technology Independence“‣ „@Inject Business Objects“‣ „No more EJBs for Transactions only“ ‣ „No more pumped up Sessions“‣ „No more Infrastructure in Views“‣ „No more doAll( ) Business Methods“

Enterprise ArchitectureMigration Guide

Page 46: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.faces.bean.ManagedBean(name=“createCustomerController“)public class CreateCustomerController {

// inject CustomerService and MailService via @EJB

@EJB private AuthenticationService authenticationService; private Customer customer;

public String createCustomer() { currentCallCenterAgent = authenticationService.getLoggedInUser();

customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED;}

// getter / setter for customer...

}

Migration GuideTechnology Independence

Page 47: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.inject.Named(“createCustomerController“)public class CreateCustomerController {

// inject CustomerService and MailService via @Inject

@Inject private AuthenticationService authenticationService; private Customer customer;

public String createCustomer() { currentCallCenterAgent = authenticationService.getLoggedInUser();

customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED;}

// getter / setter for customer...

}

Migration GuideTechnology Independence

Page 48: New School Enterprise Architecture

New School

Migration Steps:

‣ „Technology Independence“‣ „@Inject Business Objects“‣ „No more EJBs for Transactions only“ ‣ „No more pumped up Sessions“‣ „No more Infrastructure in Views“‣ „No more doAll( ) Business Methods“

Enterprise ArchitectureMigration Guide

Page 49: New School Enterprise Architecture

New School

CDI Producer Methods & Fields

‣ Factory Method Pattern für Objekte‣ @Producer als Mittel zum Zweck‣ @Qualifier als Mittel zur Typ-Qualifizierung

‣ ermöglicht fachliche Injektion

@Inject @Current CallCenterAgentMigration Guide

Page 50: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.inject.Named(“createCustomerController“)public class CreateCustomerController {

// inject CustomerService and MailService via @Inject

@Inject private AuthenticationService authenticationService; private Customer customer;

public String createCustomer() { currentCallCenterAgent = authenticationService.getLoggedInUser();

customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED;}

// getter / setter for customer...

}

Migration Guide@Inject @Current CallCenterAgent

Page 51: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.inject.Named(“createCustomerController“)public class CreateCustomerController {

// inject CustomerService and MailService via @Inject

@Inject @Current private CallCenterAgent currentCallCenterAgent; private Customer customer;

public String createCustomer() { customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED;}

// getter / setter for customer...

}

Migration Guide@Inject @Current CallCenterAgent

Page 52: New School Enterprise Architecture

New School

// Authentication Controller@SessionScoped@Named(“authenticationController“)public class AuthenticationController implements Serializable {

private CallCenterAgent authenticatedCallCenterAgent;

public String authenticate() {...}

@Produces @Current public CallCenterAgent getAuthenticatedCallCenterAgent() {

return authenticatedCallCenterAgent;}

...}

Migration Guide@Inject @Current CallCenterAgent

Page 53: New School Enterprise Architecture

New School

// Authentication Controller@SessionScoped@Named(“authenticationController“)public class AuthenticationController implements Serializable {

private CallCenterAgent authenticatedCallCenterAgent;

public String authenticate() {...}

@Produces @Current public CallCenterAgent getAuthenticatedCallCenterAgent() {

return authenticatedCallCenterAgent;}

...}

Migration Guide@Inject @Current CallCenterAgent

@Inject @Current CallCenterAgent

Page 54: New School Enterprise Architecture

New School

// Authentication Controller@SessionScoped@Named(“authenticationController“)public class AuthenticationController implements Serializable {

private CallCenterAgent authenticatedCallCenterAgent;

public String authenticate() {...}

@Produces @Current public CallCenterAgent getAuthenticatedCallCenterAgent() {

return authenticatedCallCenterAgent;}

...}

Migration Guide@Inject @Current CallCenterAgent

@RequestScoped

@Inject @Current CallCenterAgent

Page 55: New School Enterprise Architecture

New School

package de.openknowldege.qualifier

import ...

// self-made qualifier to indicate current instance of something

@Qualifier@Target({TYPE, METHOD, PARAMETER, FIELD})@Retention(RUNTIME)public @interface Current{ }

Migration Guide@Inject @Current CallCenterAgent

Page 56: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.inject.Named(“createCustomerController“)public class CreateCustomerController {

// inject CustomerService and MailService via @Inject

@Inject @Current private CallCenterAgent currentCallCenterAgent; private Customer customer;

public String createCustomer() { customer.setAuditInformation(currentCallCenterAgent); customerService.create(customer); mailService.sendWelcomeMail(customer); return CUSTOMER_CREATED;}

// getter / setter for customer...

}

Migration Guide@Inject @Current CallCenterAgent

Page 57: New School Enterprise Architecture

New School

// Customer Service EJB@Statelesspublic class CustomerService {

@Inject @Current private CallCenterAgent currentCallCenterAgent; @PersistenceContext private EntityManager em;

// transactional by default public void createCustomer(Customer customer) {

customer.setAuditInformation(currentCallCenterAgent); em.persist(customer);}

...}

Migration Guide@Inject @Current CallCenterAgent

Page 58: New School Enterprise Architecture

New School

Migration Steps:

‣ „Technology Independence“‣ „@Inject Business Objects“‣ „No more EJBs for Transactions only“ ‣ „No more pumped up Sessions“‣ „No more Infrastructure in Views“‣ „No more doAll( ) Business Methods“

Enterprise ArchitectureMigration Guide

Page 59: New School Enterprise Architecture

New School

Injizierbare CDI Ressourcen

‣ normale Java Klassen - optional mit @Named und/oder @Qualifier markiert‣ EJBs - Stateless, Stateful, Singleton‣ sonstige Java EE Resources -

UserTransaction, PersistenceContext, ...

No more EJBsMigration Guide

Page 60: New School Enterprise Architecture

New School

// Customer Service EJB @Statelesspublic class CustomerService {

@Inject @Current private CallCenterAgent currentCallCenterAgent; @PersistenceContext private EntityManager em;

// transactional by default public void createCustomer(Customer customer) {

customer.setAuditInformation(currentCallCenterAgent); em.persist(customer);}

...}

Migration GuideNo more EJBs

Page 61: New School Enterprise Architecture

New School

// Customer Service EJB - no annotation required!@Statelesspublic class CustomerService {

@Inject @Current private CallCenterAgent currentCallCenterAgent; @PersistenceContext private EntityManager em;

// transactional by default public void createCustomer(Customer customer) {

customer.setAuditInformation(currentCallCenterAgent); em.persist(customer);}

...}

Migration GuideNo more EJBs

Page 62: New School Enterprise Architecture

New School

// Customer Service EJB - no annotation required!@Statelesspublic class CustomerService {

@Inject @Current private CallCenterAgent currentCallCenterAgent; @PersistenceContext private EntityManager em;

// transactional by default public void createCustomer(Customer customer) {

customer.setAuditInformation(currentCallCenterAgent); em.persist(customer);}

...}

Migration Guide

Ok, aber wo bekommen wie die Transaktion jetzt her?

No more EJBs

Page 63: New School Enterprise Architecture

New School

// Customer Service EJB - no annotation required!@Statelesspublic class CustomerService {

@Inject @Current private CallCenterAgent currentCallCenterAgent; @PersistenceContext private EntityManager em;

@Transactional public void createCustomer(Customer customer) {

customer.setAuditInformation(currentCallCenterAgent); em.persist(customer);}

...}

Migration GuideNo more EJBs

Page 64: New School Enterprise Architecture

New School

// Customer Service EJB - no annotation required!@Statelesspublic class CustomerService {

@Inject @Current private CallCenterAgent currentCallCenterAgent; @PersistenceContext private EntityManager em;

@Transactional public void createCustomer(Customer customer) {

customer.setAuditInformation(currentCallCenterAgent); em.persist(customer);}

...}

Migration Guide

JTA 1.2 oder DeltaSpike oder als Self-Made CDI-Interceptor

No more EJBs

Page 65: New School Enterprise Architecture

New School

@InterceptorBinding@Target({TYPE, METHOD})@Retention(RUNTIME)public @interface Transactional {

@Nonbinding public TransactionalType value()

default TransactionalType.REQUIRED;

}

Migration GuideNo more EJBs

Page 66: New School Enterprise Architecture

New School

@Transactional @Interceptorpublic class TransactionAdvice {

@Inject private UserTransaction utx;

@AroundInvoke public Object applyTransaction( InvocationContext ic) throws Throwable {

... // 1. implement utx.begin() ic.proceed(); // 2. call original method ... // 3. implement utx.commit()

}

Migration GuideNo more EJBs

*XML registration omitted

Page 67: New School Enterprise Architecture

New School

// Customer Service - no annotation required!public class CustomerService {

@Inject @Current private CallCenterAgent currentCallCenterAgent; @PersistenceContext private EntityManager em;

@Transactional public void createCustomer(Customer customer) {

customer.setAuditInformation(currentCallCenterAgent); em.persist(customer);}

...}

Migration GuideNo more EJBs

Page 68: New School Enterprise Architecture

New School

// Customer Service - no annotation required!public class CustomerService {

@Inject @Current private CallCenterAgent currentCallCenterAgent; @PersistenceContext private EntityManager em;

@Transactional public void createCustomer(Customer customer) {

customer.setAuditInformation(currentCallCenterAgent); em.persist(customer);}

...}

Migration GuideNo more EJBs

Page 69: New School Enterprise Architecture

New School Enterprise Architecture

UI

Service

Data

JSF View

UsecaseController

Service Service

EntityManager Entity

TX

No more EJBs

Page 70: New School Enterprise Architecture

New School Enterprise Architecture

UI

Service

Data

JSF View

UsecaseController

Service Service

EntityManager Entity

TX

No more EJBs

Page 71: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.inject.Named(“createCustomerController“)public class CreateCustomerController {

@Inject private CustomerService customerService;

private Customer customer;

@Transactional public String createCustomer() {

customerService.create(customer); ... // some additional use case “tx“ related work return CUSTOMER_CREATED;}

// getter / setter for customer...

}

Migration GuideNo more EJBs

Page 72: New School Enterprise Architecture

New School

Migration Steps:

‣ „Technology Independence“‣ „@Inject Business Objects“‣ „No more EJBs for Transactions only“ ‣ „No more pumped up Sessions“‣ „No more Infrastructure in Views“‣ „No more doAll( ) Business Methods“

Enterprise ArchitectureMigration Guide

Page 73: New School Enterprise Architecture

New School

Anti-Pattern „alles in die Session“

‣ RequestScoped ist leider zu kurz‣ ViewScoped irgendwie auch‣ SessionScoped aus Mangel an Alternativen

No more pumped up SessionMigration Guide

Page 74: New School Enterprise Architecture

New School Migration Guide

Old School Ansatz

// JSF UI [email protected]@javax.inject.Named(“deleteCustomerController“)public class DeleteCustomerController implements Serializable {

// @EJB CustomerService, AuthenticationService and MailService

private Customer customerToDelete; public String askForDeletion(Customer customer) { customerToDelete = customer; return SHOW_DELETE_CONFIRMATION;

}

public String deleteCustomer(Customer customer) { ... // call backend services return CUSTOMER_DELETED;

} ...

}

Page 75: New School Enterprise Architecture

New School Migration Guide

Old School Ansatz

// JSF UI [email protected]@javax.inject.Named(“deleteCustomerController“)public class DeleteCustomerController implements Serializable {

private Customer customerToDelete;

@Inject private Conversation conversation; public String askForDeletion(Customer customer) { conversation.begin(); customerToDelete = customer; return SHOW_DELETE_CONFIRMATION;

}

public String deleteCustomer(Customer customer) { conversation.end();

... // call backend services return CUSTOMER_DELETED;

} ...

}

Page 76: New School Enterprise Architecture

New School

Migration Steps:

‣ „Technology Independence“‣ „@Inject Business Objects“‣ „No more EJBs for Transactions only“ ‣ „No more pumped up Sessions“‣ „No more Infrastructure in Views“‣ „No more doAll( ) Business Methods“

Enterprise ArchitectureMigration Guide

Page 77: New School Enterprise Architecture

New School

Views sind nach wie vor ein Problem

‣ Injection via U-EL‣ Injection von UI Controllern

No more Infrastructure in ViewsMigration Guide

Page 78: New School Enterprise Architecture

New School Enterprise Architecture

<html ...> <h:body> <h:form>

Vorname: <h:inputText value=“#{createCustomerController.customer.firstname}"/> Name: <h:inputText value=“#{createCustomerController.customer.lastname}"/>

</h:form> </h:body></html>

No more Infrastructure in Views

Page 79: New School Enterprise Architecture

New School Enterprise Architecture

<html ...> <h:body> <h:form>

Vorname: <h:inputText value=“#{createCustomerController.customer.firstname}"/> Name: <h:inputText value=“#{createCustomerController.customer.lastname}"/>

</h:form> </h:body></html>

No more Infrastructure in Views

Infrastruture in der View

Page 80: New School Enterprise Architecture

New School Enterprise Architecture

<html ...> <h:body> <h:form>

Vorname: <h:inputText value=“#{customerToCreate.firstname}"/> Name: <h:inputText value=“#{customerToCreate.lastname}"/>

</h:form> </h:body></html>

No more Infrastructure in Views

Page 81: New School Enterprise Architecture

New School Enterprise Architecture

<html ...> <h:body> <h:form>

Vorname: <h:inputText value=“#{customerToCreate.firstname}"/> Name: <h:inputText value=“#{customerToCreate.lastname}"/>

</h:form> </h:body></html>

No more Infrastructure in Views

Fachlichkeit in der View

Page 82: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.inject.Named(“createCustomerController“)public class CreateCustomerController {

@Inject private CustomerService customerService;

private Customer customer;

// getter for [email protected]@javax.inject.Named(“customerToCreate“) public Customer getCustomer { return customer; }...

}

Migration GuideNo more Infrastructure in Views

Page 83: New School Enterprise Architecture

New School

Migration Steps:

‣ „Technology Independence“‣ @Inject Business Objects‣ „No more EJBs for Transactions only“ ‣ „No more pumped up Sessions“‣ „No more Infrastructure in Views“‣ „No more doAll( ) Business Methods“

Enterprise ArchitectureMigration Guide

Page 84: New School Enterprise Architecture

New School

Ein Use Case kommt selten allein

‣ Primärer Use Case - Create Customer

‣ Sekundärer Use Case - Send Welcome Mail‣ Sekundärer Use Case - ...‣ Sekundärer Use Case - ...

No more doAll() Business MethodsMigration Guide

Page 85: New School Enterprise Architecture

New School

CDI Events zur losen Kopplung, d.h Java EE Observer Patten inkl. ...

‣ Event Object & Event Producer‣ Observer Method

‣ schichtenneutral für POJOs‣ ggf. transaktionsgebunden‣ synchrone Interaktion

No more doAll() Business MethodsMigration Guide

Page 86: New School Enterprise Architecture

New School Migration Guide

Event/Message

Producer

CDI Bean Manager

Observer Method

Observer Method

Observer Method

No more doAll() Business Methods

Page 87: New School Enterprise Architecture

New School Migration Guide

Event/Message

Producer

CDI Bean Manager

Observer Method

Observer Method

Observer Method

No more doAll() Business Methods

USER CREATED

Page 88: New School Enterprise Architecture

New School Migration Guide

Event/Message

Producer

CDI Bean Manager

Observer Method

Observer Method

Observer Method

No more doAll() Business Methods

USER CREATED

interessant

ok, danke

gut zu wissen

Page 89: New School Enterprise Architecture

New School

OK, CDI Events - klingt super, aber ...

‣Wie sieht ein solches Event aus? ‣ Und wie fange ich es ab?

‣ Und vor allem: Wie löse ich es aus?

No more doAll() Business MethodsMigration Guide

Page 90: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.inject.Named(“createCustomerController“)public class CreateCustomerController {

@Inject private CustomerService customerService;

@Inject @Created private Event<Customer> eventSource;

private Customer customer;

@Transactional public String createCustomer() {

customerService.create(customer); eventSource.fire(customer); return CUSTOMER_CREATED;} ...

}

Migration GuideNo more doAll() Business Methods

Page 91: New School Enterprise Architecture

New School

// JSF UI [email protected]@javax.inject.Named(“createCustomerController“)public class CreateCustomerController {

@Inject private CustomerService customerService;

@Inject @Created private Event<Customer> eventSource;

private Customer customer;

@Transactional public String createCustomer() {

customerService.create(customer); eventSource.fire(customer); return CUSTOMER_CREATED;} ...

}

Migration GuideNo more doAll() Business Methods

Wow! Geht da noch mehr?

Page 92: New School Enterprise Architecture

New School Enterprise Architecture

@ApplicationScopedpublic class MailService implements Serializable {

public void sendWelcomeMail( @Observes @Created Customer customer) { // do some work with the customer object ... }

...}

‣Wie fange ich es?

No more doAll() Business Methods

Page 93: New School Enterprise Architecture

New School Enterprise Architecture

@ApplicationScopedpublic class MailService implements Serializable {

// Conditional Observer Method that takes // - Transaction status, e.g. AFTER_SUCCESS, AFTER_FAILURE // - Bean instance status, e.g. ALLWAYS // into account public void sendWelcomeMail( @Observes( receive=ALLWAYS, // bean during=AFTER_SUCCESS // tx ) @Created Customer customer) {

... }}

‣ Conditional Observer

No more doAll() Business Methods

Page 94: New School Enterprise Architecture

New School Enterprise Architecture

Alternativer Ansatz

UI

Domain

JSF View

UseCaseController

Business Object

Business Object

Business Object

TX

Page 95: New School Enterprise Architecture

New School Enterprise Architecture

Alternativer Ansatz

UI

Domain

JSF View

UseCaseController

Business Object

Business Object

Business Object

TX

Page 96: New School Enterprise Architecture

New School

New School Enterprise Architecture

‣mit CDI

‣ typensicher ‣schichtenneutral‣ fachliche und technologische Injection ‣ eventgetriebene Entwicklung

FazitEnterprise Architecture

Page 97: New School Enterprise Architecture

Java

New School Enterprise ArchitectureLars Röwekamp | open knowledge GmbH

@mobileLarson@_openknowledge