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

No-Tier Enterprise Application mit CDI

Embed Size (px)

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.

Citation preview

Page 1: No-Tier Enterprise Application mit CDI

No-Tier EnterpriseApplications with CDI

Lars Röwekamp | open knowledge

GmbH @mobileLarson

@_openknowledge

Page 2: No-Tier Enterprise Application mit 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 Application mit CDI

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

Page 4: No-Tier Enterprise Application mit CDI

> SCHICHT 3

> SCHICHT 2

> SCHICHT 1TX Grenze

Page 5: No-Tier Enterprise Application mit CDI

> UseCase: ausgewählten Kunden bearbeiten

Einmal den CustomerController, bitte ;-) Und für mich den

CustomerService, bitte!

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

Page 6: No-Tier Enterprise Application mit 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 ...?

Page 7: No-Tier Enterprise Application mit 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 EE

Page 8: No-Tier Enterprise Application mit CDI

> „No-Tier“

TX Grenze

Page 9: No-Tier Enterprise Application mit CDI

J2EE 1.3 (JSR 58):

September 2001 Servlet 2.3 JSP 1.2 EJB 2.0

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 V1

Juni 2003

„Spring“

Oktober 2002

Java EE v5 (JSR 244):

Mai 2006 Servlet 2.5 JSP 2.1 / JSF 1.2 EJB 3.0

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 V3

Dezember 2009

Spring V2

Oktober 2006

Page 10: No-Tier Enterprise Application mit CDI

CDI Konzepte > DI/IoC lite „Java EE without EJB“

> DI/IoC advanced LiceCyle Management und Scoping

> DI/IoC eXtreme Typensicherheit und lose Koppelung

> DI/IoC openExtension-Mechanismus

Page 11: No-Tier Enterprise Application mit CDI

Teil 1: Base Features

Page 12: No-Tier Enterprise Application mit CDI

Teil 1: Base Features

> @Inject> @Named> Sterotypes> Alternatives

Page 13: No-Tier Enterprise Application mit CDI

Teil 1: Base Features

> Sope Singleton> Request> Conversation> Session> Application> Dependant*> Singleton*> Cleanup*Pseudo-Scope

Page 14: No-Tier Enterprise Application mit CDI

Teil 1: Base Features

Page 15: No-Tier Enterprise Application mit CDI

Teil 1: Base Features

> Events> Observer> Interceptors

Page 16: No-Tier Enterprise Application mit CDI

Teil 1: Base Features

> Qualifier> Stereotypes> Alternatives

Page 17: No-Tier Enterprise Application mit CDI

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

Page 18: No-Tier Enterprise Application mit CDI

> SCHICHT 3

> SCHICHT 2

> SCHICHT 1

Page 19: No-Tier Enterprise Application mit CDI

> SCHICHT 3

> SCHICHT 2

> SCHICHT 1

Page 20: No-Tier Enterprise Application mit CDI

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

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

@Inject Greeter greeter;

private String name;

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

}

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

CDI Managed Bean

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

gültig für Requestgültig für Request

Injection PointInjection Point

Page 21: No-Tier Enterprise Application mit CDI

Cool, aber geht da

nicht mehr?

CDI Mehrwert

Page 22: No-Tier Enterprise Application mit CDI

FACHLICHE Injektion statt „nur“

Infrastruture Injection

Page 23: No-Tier Enterprise Application mit CDI

eCustomer - Beispiel

Page 24: No-Tier Enterprise Application mit CDI
Page 25: No-Tier Enterprise Application mit CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only

> CDI Style Views

> CDI Events

Page 26: No-Tier Enterprise Application mit CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only

> CDI Style Views

> CDI Events

Page 27: No-Tier Enterprise Application mit CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only

> CDI Style Views

> CDI Events

Page 28: No-Tier Enterprise Application mit 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 29: No-Tier Enterprise Application mit CDI

eCustomer - CDI Current User

package de.openknowledge.qualifier;

import ...

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

Self-made QualifierSelf-made Qualifier

Page 30: No-Tier Enterprise Application mit CDI

eCustomer - CDI Current User

@Named@SessionScopedpublic class AuthenticationController implements Serializable {

private User authenticatedUser; public String authenticate() {...}

@Produces @Current public User getAuthenticatedUser() {...}

...}

AuthenticationControllerAuthenticationController

@Inject @Current User user; @Inject @Current User user;

Page 31: No-Tier Enterprise Application mit CDI

Use Case „Kunde bearbeiten“

@Statelesspublic class CustomerServiceEJB

implements CustomerService {

@Inject @Current private User currentUser;

@PersistenceContext private EntityManager em;

// updates the customer - needs a transaction public Customer updateCustomer(Customer customer) { customer.updateAuditInformation(currentUser); return em.merge(customer); }}

CustomerService EJBCustomerService EJB

Page 32: No-Tier Enterprise Application mit CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only

> CDI Style Views

> CDI Events

Page 33: No-Tier Enterprise Application mit 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 34: No-Tier Enterprise Application mit CDI

eCustomer - CDI Beans only

@Stateless// no annotation required!public class CustomerServiceBeanEJB

implements CustomerService {

@PersistenceContext private EntityManager em;

// updates the customer - needs a transaction public Customer updateCustomer(Customer customer) { return em.merge(customer); }

...

}

CustomerService CDICustomerService CDI

Page 35: No-Tier Enterprise Application mit CDI

eCustomer - CDI Beans only

@Stateless// no annotation required!public class CustomerServiceBeanEJB

implements CustomerService {

@PersistenceContext private EntityManager em;

// updates the customer - needs a transaction public Customer updateCustomer(Customer customer) { return em.merge(customer); }

...

}

CustomerService CDICustomerService CDI

Und Transaktionen?!Und Transaktionen?!

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

Page 36: No-Tier Enterprise Application mit CDI

eCustomer - CDI Beans only

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

implements CustomerService {

@PersistenceContext private EntityManager em;

@Transactional public Customer updateCustomer(Customer customer) { return em.merge(customer); }

...

}

CustomerService CDICustomerService CDI

Page 37: No-Tier Enterprise Application mit CDI

CDI Interceptor

s

Page 38: No-Tier Enterprise Application mit CDI

eCustomer - CDI Beans only

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

public @interface Transactional { public TransactionalType value()

default TransactionalType.REQUIRED; }

Transactional AnnotationTransactional Annotation

??

Page 39: No-Tier Enterprise Application mit CDI

eCustomer - CDI Beans only

@Transactional @Interceptorpublic class TransactionInterceptor {

@Inject private UserTransaction utx;

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

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

} }

*XML registration omitted

Transactional Interceptor*Transactional Interceptor*

Page 40: No-Tier Enterprise Application mit CDI

eCustomer - CDI Beans only

// no annotation required!public class CustomerServiceBean

implements CustomerService {

@PersistenceContext private EntityManager em; @de.openknowledge.qualifier.Transactional public Customer updateCustomer(Customer customer) { return em.merge(customer); }

...

}

CustomerService CDICustomerService CDI

inkl. Transaktioninkl. Transaktion

Page 41: No-Tier Enterprise Application mit CDI

> SCHICHT 3

> SCHICHT 2

> SCHICHT 1TX Grenze

Page 42: No-Tier Enterprise Application mit CDI

> SCHICHT 3

> SCHICHT 2

> SCHICHT 1

TX Grenze

Page 43: No-Tier Enterprise Application mit CDI

eCustomer - CDI Beans only

@Named@SessionScopedpublic class CustomerBean implements Serializable {

@Inject private CustomerService customerService;

@de.openknowledge.qualifier.Transactional public String update() { customerService.updateCustomer(currentCustomer); return Outcome.SUCCESS; } ...}

CustomerBean CDICustomerBean CDI

inkl. „fachliche“ Transaktioninkl. „fachliche“ Transaktion

Page 44: No-Tier Enterprise Application mit CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only

> CDI Style Views

> CDI Events

Page 45: No-Tier Enterprise Application mit CDI

eCustomer - CDI Style Views

> CDI Conversations

> @ConversationScoped

> conversation.begin() / .end()

> CDI „Backing Beans“

> @Produces in Kombination mit @Named

> „self-made“ Qualifier

Page 46: No-Tier Enterprise Application mit CDI

eCustomer - CDI Style Formulare

@javax.inject.Named@javax.context.enterpise.ConversationScopedpublic class CustomerBean implements Serializable {

private Customer customer;

@javax.inject.Inject private Conversation conversation;

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

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

Page 47: No-Tier Enterprise Application mit CDI

eCustomer - CDI Style Formulare

@javax.inject.Named@javax.context.enterpise.ConversationScopedpublic class CustomerBean implements Serializable {

...

public String update() { conversation.end(); ... } ...

}

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

endet mit aktuellen Requestendet mit aktuellen Request

Page 48: No-Tier Enterprise Application mit CDI

eCustomer - CDI Style Formulare

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

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

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

Infrastructure in der View!Infrastructure in der View!

Page 49: No-Tier Enterprise Application mit CDI

eCustomer - CDI Style Formulare

@javax.inject.Named@javax.context.enterpise.ConversationScopedpublic class CustomerBean implements Serializable {

private Customer customer;

@javax.inject.Produces @javax.inject.Named(“selectedCustomer“) @de.openknowledge.qualifier.Selected public Customer getSelected { return customer; } ... }

CustomerBean CustomerBean

Page 50: No-Tier Enterprise Application mit CDI

eCustomer - CDI Style Formulare

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

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

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

Fachlichkeit in der View!Fachlichkeit in der View!

Page 51: No-Tier Enterprise Application mit CDI

CDI Refactoring

> CDI Wiring

> CDI Current User

> CDI Beans only

> CDI Style Views

> CDI Events

Page 52: No-Tier Enterprise Application mit 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 53: No-Tier Enterprise Application mit CDI

eCustomer - CDI Events

„User created!“„User created!“

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

„Finde ich!“„Finde ich!“

Page 54: No-Tier Enterprise Application mit 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 55: No-Tier Enterprise Application mit CDI

eCustomer - CDI Events

public class CustomerCreatedEvent {

private Customer customer;

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

public Customer getCustomer() { ... }}

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

„Wie sieht ein solches Event aus?“

Page 56: No-Tier Enterprise Application mit CDI

eCustomer - CDI Events

public void sendWelcomeMail( @Observes CustomerCreatedEvent event) { Customer customer = event.getCustomer(); ...}

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

„Und wie fange ich es?“

Page 57: No-Tier Enterprise Application mit CDI

eCustomer - CDI Events

@Injectprivate Event<CustomerCreatedEvent> eventSource;

public String createCustomer() {

Customer customer = ...; eventSource.fire( new CustomerCreatedEvent(customer) ); ... }

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

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

Page 58: No-Tier Enterprise Application mit CDI

eCustomer - CDI Events

public void sendWelcomeMail( @Observes CustomerCreatedEvent event @Created Customer customer) { Customer customer = event.getCustomer(); ...}

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

„Und wie fange ich es?“

Page 59: No-Tier Enterprise Application mit CDI

eCustomer - CDI Events

@Inject @Created private Event<Customer> eventSource;

public String createCustomer() { Customer customer = ...; eventSource.fire(customer); ... }

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

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

Page 60: No-Tier Enterprise Application mit 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 61: No-Tier Enterprise Application mit 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( @Observes( receive=ALLWAYS, // bean during=AFTER_SUCCESS // tx ) @Created Customer customer) { ... }

Conditional Observer MethodsConditional Observer Methods

Page 62: No-Tier Enterprise Application mit CDI

> „No-Tier“

TX Grenze

Page 63: No-Tier Enterprise Application mit CDI

XFazit:

Page 64: No-Tier Enterprise Application mit 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 65: No-Tier Enterprise Application mit CDI

Gibt es noch Fragen?

Dann los ...

@mobileLarson@_openknowledg

efacebook.com/openknowledge