Transcript
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


Recommended