No Tier Enterprise Applications with CDI

76
No-Tier Enterprise Applications with CDI Lars Röwekamp | open knowledge GmbH @mobileLarson @_openknowledge

description

Der Einsatz von Java EE führt meist zu Anwendungen, die einer klassischen serviceorientierten Mehrschichtarchitektur entsprechen. Mit Java EE 6 und CDI (JSR 299 aka WebBeans) hält nun ein Entwicklungsparadigma Einzug, das diesen Designansatz zugunsten des fachlichen Domain-Modells grundlegend verändern kann. "Business Injection" statt "Infrastructure Injection" ist das zugehörige Zauberwort. Die Session zeigt, wie eine klassische Mehrschichtwebanwendung durch die Einführung von fachlicher Dependency Injection, asynchroner bzw. eventorientierter Kommunikation und Ansätzen der aspektorientierten Programmierung verbessert werden kann und dabei mit standardisierten Mitteln ein neues Zeitalter der effizienten, wartbaren und performanten Anwendungsarchitektur einläutet.Speaker: Lars Röwekamp17.04.2012 | 10:00 - 11:15 | JAX, Mainz

Transcript of No Tier Enterprise Applications with CDI

Page 1: No Tier Enterprise Applications with CDI

No-Tier EnterpriseApplications with CDI

Lars Röwekamp | open knowledge GmbH

@mobileLarson@_openknowledge

Page 2: No Tier Enterprise Applications with CDI

> Cool! JavaEE bietet IoC/DI > Cool! JavaEE bietet IoC/DI > Cool! JavaEE bietet IoC/DI > Cool! JavaEE bietet IoC/DI

Page 3: No Tier Enterprise Applications with CDI

> Aber was ändert sich?> Aber was ändert sich?

Page 4: No Tier Enterprise Applications with CDI

> SCHICHT 2

> SCHICHT 1TX Grenze

> SCHICHT 3

> SCHICHT 2

Page 5: No Tier Enterprise Applications with CDI

Einmal den Customer Controller, bitte ;-)

Und für mich den Customer Service, bitte!

Ok, dann brauch ich nen Customer Entity mit der internene ID 147122, aber flott!

> UseCase: ausgewählten Kunden bearbeiten

Page 6: No Tier Enterprise Applications with CDI

AA KK TT UU EE LL LL

AA UU SS GG EE WW ÄÄ HH LL TT EE

KK UU NN DD EE

RR

> Was wäre wenn ...? > Was wäre wenn ...? > Was wäre wenn ...? > Was wäre wenn ...?

KK UU NN DD EE

Page 7: No Tier Enterprise Applications with CDI

LL II SS TT EE

MM EE II NN EE RR

EE II NN KK ÄÄ UU

> Oder wenn ...? > Oder wenn ...? > Oder wenn ...? > Oder wenn ...?

FF EEEE II NN KK ÄÄ UU FF EE

Page 8: No Tier Enterprise Applications with CDI

> „No-Tier“

TX Grenze

> „No-Tier“

Page 9: No Tier Enterprise Applications with CDI

J2EE 1.3 (JSR 58):

September 2001

� Servlet 2.3

� JSP 1.2

� EJB 2.0

01 / 02 03 / 04 05 / 06 07 / 08 09 / 10

Spring V1

Juni 2003

Java EE v5 (JSR 244):

Mai 2006

� Servlet 2.5

� JSP 2.1 / JSF 1.2

� EJB 3.0

Spring V3

Dezember 2009

J2EE 1.4 (JSR 151):

November 2003

� Servlet 2.4

� JSP 2.0

� EJB 2.1

01 / 02 03 / 04 05 / 06 07 / 08 09 / 10

„Spring“

Oktober 2002

Java EE v6 (JSR 316):

Dezember 2009

� Servlet 3.0

� JSP 2.1 MR / JSF 2.0

� EJB 3.1

� JPA 2.0

� CDI 1.0

Spring V2

Oktober 2006

Page 10: No Tier Enterprise Applications with CDI

Enterprise JavaBeans

Life Cycle Mmgt.

Instance Pooling

Concurrency

TransactionTransaction

Security

Scoping

...

EJBs: Schwergewichtig

Page 11: No Tier Enterprise Applications with CDI

CDI:

Leichtegichtig CDI Beans

Life Cycle Mmgt.

Scoping

... AND ...

*** Extensibility ***

Page 12: No Tier Enterprise Applications with CDI

CDI Konzepte

Typensicher DI

(Stereotypes, Qulifier)

Loose Koopelung

CDI:

Leichtegichtig

(Events, Interceptors)

Sichtbarkeiten

(Sopes, LifeCycle )

„FACHLICHE INJECTION“

Page 13: No Tier Enterprise Applications with CDI

> DI/IoC lite„Java EE without EJB“

> DI/IoC advancedLifeCyle Managementund Scoping

CDI Kickstart

> DI/IoC eXtremeTypensicherheit undlose Koppelung

> DI/IoC openExtension-Mechanismus

Page 14: No Tier Enterprise Applications with CDI

Base Features

Page 15: No Tier Enterprise Applications with CDI

Base Features

> @Inject> @Named> Sterotypes> Sterotypes> Alternatives

Page 16: No Tier Enterprise Applications with CDI

Base Features

> Sope Singleton> Cleanup> Request> Conversation> Conversation> Session> Application> Dependant*> Singleton*

*Pseudo-Scope

Page 17: No Tier Enterprise Applications with CDI

Base Features

Page 18: No Tier Enterprise Applications with CDI

Base Features

Page 19: No Tier Enterprise Applications with CDI

Base Features

> Events> Events> Observer> Interceptors

Page 20: No Tier Enterprise Applications with CDI

Base Features

> Qualifier> Stereotypes> Alternatives

Page 21: No Tier Enterprise Applications with CDI

> Was haben wir gewonnen?> Was haben wir gewonnen?> Was haben wir gewonnen?> Was haben wir gewonnen?

Page 22: No Tier Enterprise Applications with CDI

> SCHICHT 2

> SCHICHT 1

> SCHICHT 3

> SCHICHT 2

Page 23: No Tier Enterprise Applications with CDI

> SCHICHT 2

> SCHICHT 1

> SCHICHT 3

> SCHICHT 2

Page 24: No Tier Enterprise Applications with CDI

import javax.inject.Named;import javax.inject.Inject;import javax.enterprise.context.RequestScoped;

@Named(“hello “)@RequestScopedpublic class HelloBean {

CDI Managed Bean

„hello“ für EL„hello“ für EL

gültig für Requestgültig für Requestpublic class HelloBean {

@Inject Greeter greeter ;

private String name;

public String getGreeting() {return greeter .greet( name);

}

// getter and setter for name attribute...}

Injection PointInjection Point

Page 25: No Tier Enterprise Applications with CDI

public class Greeter {

public String greet(Sting name) {

if ( name != null) {return “Hello, “ + name;

CDI Managed BeanSimple POJOSimple POJO

return “Hello, “ + name; } else {

return “Hello, stranger!“; }

}}

Page 26: No Tier Enterprise Applications with CDI

CDI Managed Bean

@Statelesspublic class GreeterEJB

implements Greeter {

private static final Log logger = ...

@Inject @Current CrmUser crmUser;

Stateless EJBStateless EJB

@Inject @Current CrmUser crmUser;

public String greet(Sting name) {

logger. debug(“Who: “ + crmUser.getName());

if ( name != null) {... // create & return greeting

}}}

Page 27: No Tier Enterprise Applications with CDI

Cool, aber geht da

nicht mehr?

CDIMehrwert

Page 28: No Tier Enterprise Applications with CDI

FACHLICHE Injektion statt „nur“

Infrastruture Injection

Page 29: No Tier Enterprise Applications with CDI

eCustomer - Beispiel

Page 30: No Tier Enterprise Applications with CDI
Page 31: No Tier Enterprise Applications with CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only> CDI Beans only

> CDI Style Views

> CDI Events

Page 32: No Tier Enterprise Applications with CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only> CDI Beans only

> CDI Style Views

> CDI Events

Page 33: No Tier Enterprise Applications with CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only> CDI Beans only

> CDI Style Views

> CDI Events

Page 34: No Tier Enterprise Applications with CDI

eCustomer - CDI Current User

> Producer Methods & Fields

> „Factory Method“ Pattern für Objekte

> @Produces als Mittel zum Zweck

> @Qualifier als Mittel zur Qualifizierung

> Ermöglicht nicht nur Infrastruktur

sondern vor allem auch fachliche

Injection.

Page 35: No Tier Enterprise Applications with CDI

eCustomer - CDI Current User

@Named@SessionScopedpublic class AuthenticationController

implements Serializable {

private User authenticatedUser;

AuthenticationControllerAuthenticationController

public String authenticate() {...}

public User getAuthenticatedUser() {...}

...}

@Produces @Current

Page 36: No Tier Enterprise Applications with CDI

eCustomer - CDI Current User

@Named@SessionScopedpublic class AuthenticationController

implements Serializable {

private User authenticatedUser;

public String authenticate() {...}

@Produces@Currentpublic User getAuthenticatedUser() {...}

...} @Inject @Current User user; @Inject @Current User user;

@RequestScoped

Page 37: No Tier Enterprise Applications with CDI

eCustomer - CDI Current User

package de.openknowledge.qualifier;

import ...

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

Self-made QualifierSelf-made Qualifier

@Retention(RUNTIME)public @interface Current {}

Page 38: No Tier Enterprise Applications with CDI

eCustomer - CDI Current User

@javax.inject. [email protected]. SessionScopedpublic class CustomerBean implements Serializable {

// @javax.inject. Inject // private AuthenticationController authController ;

JSF CustomerBean JSF CustomerBean

@javax.inject. Injectprivate CustomerService customerService ;

public String update () {// User currentUser =

authController .getAuthenticatedUser();// currentCustomer .updateAuditInformation(currentUser);

customerService .updateCustomer(currentCustomer);return Outcome.SUCCESS;

}...

}

Audit „Bereinigung“Audit „Bereinigung“

Page 39: No Tier Enterprise Applications with CDI

Use Case „Kunde bearbeiten“

@Statelesspublic class CustomerServiceEJB

implements CustomerService {

@Inject @Currentprivate User currentUser;

CustomerService EJBCustomerService EJB

@PersistenceContextprivate EntityManager em;

// updates the customer - needs a transactionpublic Customer updateCustomer(Customer customer)

{customer.updateAuditInformation(currentUser);return em.merge(customer);

}}

Page 40: No Tier Enterprise Applications with CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only> CDI Beans only

> CDI Style Views

> CDI Events

Page 41: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

> Injizierbare CDI Ressourcen

> „normale“ Java Klassen, optional mit

@Named oder @Qualifier markiert

> EJBs, wie Stateless, Stateful, Singleton

> Sonstige Java EE Ressourcen, wie

PersistenceContext, UserTransaction

Page 42: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

@Stateless// no annotation required!public class CustomerService BeanEJB

implements CustomerService {

@Inject @Currentprivate User currentUser;

CustomerService CDICustomerService CDI

private User currentUser;

@PersistenceContextprivate EntityManager em;

// updates the customer - needs a transactionpublic Customer updateCustomer(Customer customer)

{customer.updateAuditInformation(currentUser);return em.merge(customer);

}

...

}

Page 43: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

@Stateless// no annotation required!public class CustomerService BeanEJB

implements CustomerService {

@Inject @Currentprivate User currentUser;

CustomerService CDICustomerService CDI

private User currentUser;

@PersistenceContextprivate EntityManager em;

// updates the customer - needs a transactionpublic Customer updateCustomer(Customer customer)

{customer.updateAuditInformation(currentUser);return em.merge(customer);

}

...

}

Und Transaktionen?!Und Transaktionen?!

Bauen wir uns selbst ...Bauen wir uns selbst ...

Page 44: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

// simple pojo // no annotation required!public class CustomerServicBean

implements CustomerService {

@Inject @Currentprivate User currentUser;

CustomerService CDICustomerService CDI

private User currentUser;

@PersistenceContextprivate EntityManager em;

@Transactionalpublic Customer updateCustomer(Customer customer)

{customer.updateAuditInformation(currentUser);return em.merge(customer);

}

...

}

Page 45: No Tier Enterprise Applications with CDI

CDI Interceptors

Page 46: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

@InterceptorBinding@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD, ElementType.TYPE})

public @interface Transactional {

@Nonbinding

??@Nonbindingpublic TransactionalType value ()

default TransactionalType.REQUIRED;

}

Transactional AnnotationTransactional Annotation

Page 47: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

@Transactional @Interceptorpublic class TransactionAdvice {

@Injectprivate UserTransaction utx;

Transactional Interceptor*Transactional Interceptor*

@AroundInvokepublic Object applyTransaction(

InvocationContext ic ) throws Throwable {

... // 1. access @Transactional,// if needed

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

} } *XML registration omitted

Page 48: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

@Transactional @Interceptorpublic class TransactionAdvice {

@Injectprivate UserTransaction utx;

Transactional Interceptor*Transactional Interceptor*

@AroundInvokepublic Object applyTransaction(

InvocationContext ic ) throws Throwable {

Transactional tx = ic.getMethod(). getAnnotation(Transactional.class);

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

} } *XML registration omitted

Page 49: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

// no annotation required!public class CustomerServiceBean

implements CustomerService {

@Inject @Currentprivate User currentUser;

CustomerService CDICustomerService CDI

@PersistenceContextprivate EntityManager em;

@de.openknowledge.qualifier. Transactionalpublic Customer updateCustomer(Customer customer)

{customer.updateAuditInformation(currentUser);return em.merge(customer);

}...

}

inkl. Transaktioninkl. Transaktion

Page 50: No Tier Enterprise Applications with CDI

> SCHICHT 2

> SCHICHT 1TX Grenze

> SCHICHT 3

> SCHICHT 2

Page 51: No Tier Enterprise Applications with CDI

> SCHICHT 2

> SCHICHT 1

TX Grenze

> SCHICHT 3

> SCHICHT 2

Page 52: No Tier Enterprise Applications with CDI

eCustomer - CDI Beans only

@Named@SessionScopedpublic class CustomerBean implements Serializable {

@Injectprivate CustomerService customerService ;

CustomerBean CDICustomerBean CDI

@de.openknowledge.qualifier. Transactionalpublic String update () {

customerService .updateCustomer(currentCustomer);... // some additional use case “tx“ related

workreturn Outcome.SUCCESS;

}...

}

inkl. „fachliche“ Transaktioninkl. „fachliche“ Transaktion

Page 53: No Tier Enterprise Applications with CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only> CDI Beans only

> CDI Style Views

> CDI Events

Page 54: No Tier Enterprise Applications with CDI

eCustomer - CDI Style Views

> CDI Conversations

> @ConversationScoped

> conversation.begin() / .end()

> CDI „Backing Beans“

> @Produces in Kombination mit @Named

> „self-made“ Qualifier

Page 55: No Tier Enterprise Applications with CDI

eCustomer - CDI Style Views

@javax.inject. [email protected]. ConversationScopedpublic class CustomerBean implements Serializable {

private Customer customer;

@javax.inject .Inject

CustomerBean (1/2)CustomerBean (1/2)

@javax.inject .Inject private Conversation conversation ;

public String selectCustomer (Customer customer) {conversation.begin();this.customer = customer;return ... ;

}...

}

Page 56: No Tier Enterprise Applications with CDI

eCustomer - CDI Style Views

@javax.inject. [email protected]. ConversationScopedpublic class CustomerBean implements Serializable {

private Customer customer;

@javax.inject .Inject

CustomerBean (2/2)CustomerBean (2/2)

@javax.inject .Inject private Conversation conversation ;

public String updateCustomer () {...conversation.end(); return ... ;

}...

}

Conversation endet mit RequestConversation endet mit Request

Page 57: No Tier Enterprise Applications with CDI

eCustomer - CDI Style Views

<html ...><h:body>

<h:form>

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

Name: <h:inputText

Infrastructure in der View!Infrastructure in der View!

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

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

</html>

Page 58: No Tier Enterprise Applications with CDI

eCustomer - CDI Style Views

<html ...><h:body>

<h:form>

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

Name: <h:inputText

Fachlichkeit in der View!Fachlichkeit in der View!

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

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

</html>

Page 59: No Tier Enterprise Applications with CDI

eCustomer - CDI Style Views

@javax.inject. [email protected]. ConversationScopedpublic class CustomerBean implements Serializable {

private Customer customer ;

@javax.inject. Produces

CustomerBean CustomerBean

@javax.inject. [email protected]. Named(“ selectedCustomer “)@de.openknowledge.qualifier. Selectedpublic Customer getSelected {

return customer ; }...

}

Page 60: No Tier Enterprise Applications with CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only> CDI Beans only

> CDI Style Views

> CDI Events

Page 61: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

> Java EE Observer Pattern, inkl. ...

> Event Object & Event Producer

> Observer Method

> „besondere“ Eigenschaften

> schichtenneutral auch für POJOs

> (ggf.) transaktionsgebunden

> synchrone Interaktion

Page 62: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

„User created!“„User created!“

„Und ich auch!“„Und ich auch!“„Ah, interessant.“„Ah, interessant.“

„Finde ich!“„Finde ich!“

Page 63: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

> Ok, aber ...

> Wie sieht ein solches Event aus?

> Und wie fange ich es?

> Und vor allem: wie löse ich es aus?

Page 64: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

public class CustomerCreatedEvent {

private Customer customer;

public CustomerCreatedEvent (Customer customer) {

Customer Created Event (1/3)Customer Created Event (1/3)

public CustomerCreatedEvent (Customer customer) {this.customer = customer;

}

public Customer getCustomer() { ... }}

„Wie sieht ein solches Event aus?“

Page 65: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

public void sendWelcomeMail(@Observes CustomerCreatedEvent event ) {

Customer customer = event.getCustomer () ;

Customer Created Event (2/3)Customer Created Event (2/3)

Customer customer = event.getCustomer () ;...

}

„Und wie fange ich es?“

Page 66: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

@Injectprivate Event<CustomerCreatedEvent> eventSource ;

public String createCustomer() {

Customer Created Event (3/3)Customer Created Event (3/3)

Customer customer = ...;

eventSource.fire (new CustomerCreatedEvent( customer )

) ;

...}

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

Page 67: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

„Wird das Event Object tatsächlich benötigt oder gibt es eventuell noch Alternativen?“

„Nicht unbedingt, man kann auch sehr gut mit eigenen

Qualifiern arbeiten!“

Page 68: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

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

Qualified CDI Event (1/3)Qualified CDI Event (1/3)

Page 69: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

public void sendWelcomeMail(@Observes CustomerCreatedEvent event@CreatedCustomer customer ) {

Qualified CDI Event - Alternative (2/3)Qualified CDI Event - Alternative (2/3)

Customer customer ) {

Customer customer = event.getCustomer();...

}

„Und wie fange ich es?“

Page 70: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

@Inject @Createdprivate Event<Customer> eventSource;

public String createCustomer() {

Qualified CDI Event - Alternative (3/3)Qualified CDI Event - Alternative (3/3)

Customer customer = ...; eventSource.fire(customer);

...}

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

Page 71: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

„Wow! Observer mit Qulifiern -das muss ich erst einmal sacken lassen!“

„Und das ist erst die Spitze des Eisberges - schau dir mal die CONDITIONAL OBSERVER

METHODS hier an!“

Page 72: No Tier Enterprise Applications with CDI

eCustomer - CDI Events

// Conditional Observer Method that takes // - Transaction status , e.g. AFTER_SUCCESS, AFTER_FAILURE// - Bean instance status , e.g. ALLWAYS// into accountpublic void sendWelcomeMail(

Conditional Observer MethodsConditional Observer Methods

public void sendWelcomeMail(@Observes(

receive=ALLWAYS, // beanduring=AFTER_SUCCESS // tx

)@Created Customer customer) {

... }

Page 73: No Tier Enterprise Applications with CDI

> „No-Tier“

TX Grenze

> „No-Tier“

Page 74: No Tier Enterprise Applications with CDI

XFazit:

Page 75: No Tier Enterprise Applications with CDI

CDI Fazit

CDI ermöglicht ...

“Java Enterprise Development without EJB -and without Spring“

CDI bietet dafür ...

„typesafe und schichtenneutrales Injection Framework für fachliche und technische Injection sowie ein Rahmenwerk für eventgetriebene Entwicklung.“

Page 76: No Tier Enterprise Applications with CDI

@mobileLarson@_openknowledge

facebook.com/openknowledge

Gibt es noch Fragen?

Dann los ...