Date post: | 11-Jun-2015 |
Category: |
Technology |
Upload: | open-knowledge-gmbh |
View: | 1,311 times |
Download: | 8 times |
No-Tier EnterpriseApplications with CDI
Lars Röwekamp | open knowledge
GmbH @mobileLarson
@_openknowledge
> Cool! JavaEE bietet IoC/DI > Cool! JavaEE bietet IoC/DI > Cool! JavaEE bietet IoC/DI > Cool! JavaEE bietet IoC/DI
> Aber was ändert > Aber was ändert sich?sich?
> SCHICHT 3
> SCHICHT 2
> SCHICHT 1TX Grenze
> 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!
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 ...?
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
> „No-Tier“
TX Grenze
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
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
Teil 1: Base Features
Teil 1: Base Features
> @Inject> @Named> Sterotypes> Alternatives
Teil 1: Base Features
> Sope Singleton> Request> Conversation> Session> Application> Dependant*> Singleton*> Cleanup*Pseudo-Scope
Teil 1: Base Features
Teil 1: Base Features
> Events> Observer> Interceptors
Teil 1: Base Features
> Qualifier> Stereotypes> Alternatives
> Was haben wir > Was haben wir gewonnen?gewonnen?> Was haben wir > Was haben wir gewonnen?gewonnen?
> SCHICHT 3
> SCHICHT 2
> SCHICHT 1
> SCHICHT 3
> SCHICHT 2
> SCHICHT 1
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
Cool, aber geht da
nicht mehr?
CDI Mehrwert
FACHLICHE Injektion statt „nur“
Infrastruture Injection
eCustomer - Beispiel
CDI Refactoring
> CDI Wiring
> CDI Current User
> CDI Beans only
> CDI Style Views
> CDI Events
CDI Refactoring
> CDI Wiring
> CDI Current User
> CDI Beans only
> CDI Style Views
> CDI Events
CDI Refactoring
> CDI Wiring
> CDI Current User
> CDI Beans only
> CDI Style Views
> CDI Events
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.
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
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;
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
CDI Refactoring
> CDI Wiring
> CDI Current User
> CDI Beans only
> CDI Style Views
> CDI Events
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
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
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 ...
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
CDI Interceptor
s
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
??
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*
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
> SCHICHT 3
> SCHICHT 2
> SCHICHT 1TX Grenze
> SCHICHT 3
> SCHICHT 2
> SCHICHT 1
TX Grenze
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
CDI Refactoring
> CDI Wiring
> CDI Current User
> CDI Beans only
> CDI Style Views
> CDI Events
eCustomer - CDI Style Views
> CDI Conversations
> @ConversationScoped
> conversation.begin() / .end()
> CDI „Backing Beans“
> @Produces in Kombination mit @Named
> „self-made“ Qualifier
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)
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
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!
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
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!
CDI Refactoring
> CDI Wiring
> CDI Current User
> CDI Beans only
> CDI Style Views
> CDI Events
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
eCustomer - CDI Events
„User created!“„User created!“
„Und ich auch!“„Und ich auch!“„Ah, interessant.“„Ah, interessant.“
„Finde ich!“„Finde ich!“
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?
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?“
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?“
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?“
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?“
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?“
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!“
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
> „No-Tier“
TX Grenze
XFazit:
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.“
Gibt es noch Fragen?
Dann los ...
@mobileLarson@_openknowledg
efacebook.com/openknowledge