No Tier Enterprise Applications with CDI
Upcoming SlideShare
Loading in...5
×
 

No Tier Enterprise Applications with CDI

on

  • 638 views

 

Statistics

Views

Total Views
638
Views on SlideShare
595
Embed Views
43

Actions

Likes
0
Downloads
8
Comments
0

2 Embeds 43

http://www.openknowledge.de 29
https://www.openknowledge.de 14

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Typensicheres DI: Types, Qualifier Loose Koppelung: Events, Interceptors, Decorators Sichtbarkeiten: Context, Scopes, Lifecycle Awareness
  • Typensicheres DI: Types, Qualifier Loose Koppelung: Events, Interceptors, Decorators Sichtbarkeiten: Context, Scopes, Lifecycle Awareness
  • WICHTIG: Use case erläutern!
  • Erläutern wofür der CurrentUser benötigt wird.
  • Aufruf via: @Inject @Current User user;
  • Achtung: Scope ist Default dependent!
  • Zwei Steps: 1. Audit Logik aus dem View Controller rausziehen 2. (next Slide) aktuellen SystemUser über Producer bekommen.
  • Injection in EJB! war vorher nicht möglich, da authenticationController = JSF ManagedBean
  • Audit Info
  • Audit Info
  • Audit Info
  • Audit Info
  • Audit Info
  • Audit Info
  • Audit Info
  • Audit Info
  • Audit Info
  • Wie sieht das Event aus?
  • Wie fange ich es?
  • Und vor allem: Wie erzeuge ich es
  • Audit Info
  • Audit Info
  • Audit Info

No Tier Enterprise Applications with CDI No Tier Enterprise Applications with CDI Presentation Transcript

  • No-Tier Enterprise Applications with CDILars Röwekamp | open knowledge GmbH @mobileLarson @_openknowledge
  • > Cool! JavaEE bietet IoC/DI
  • > Aber was ändert sich?
  • > SCHICHT 1TX Grenze > SCHICHT 2 > SCHICHT 3
  • 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
  • > Was wäre wenn ...? A K T U E L LA U S G E W Ä H L T E R K U N D E
  • > Oder wenn ...? L I S T E M E I N E R E I N K Ä U F E
  • TX Grenze > „No-Tier“
  • J2EE 1.3 (JSR 58): Java EE v5 (JSR 244): September 2001 Mai 2006  Servlet 2.3  Servlet 2.5  JSP 1.2 Spring V1 Spring V3  JSP 2.1 / JSF 1.2  EJB 2.0 Juni 2003 Dezember 2009  EJB 3.001 / 02 03 / 04 05 / 06 07 / 08 09 / 10„Spring“ J2EE 1.4 (JSR 151): Java EE v6 (JSR 316):Oktober 2002 November 2003 Dezember 2009  Servlet 2.4  Servlet 3.0  JSP 2.0  JSP 2.1 MR / JSF 2.0 Spring V2  EJB 2.1  EJB 3.1 Oktober 2006  JPA 2.0  CDI 1.0
  • Enterprise JavaBeans Life Cycle Mmgt. Instance Pooling Concurrency Transaction Security Scoping ...EJBs:Schwergewichtig
  • CDI:Leichtegichtig CDI Beans Life Cycle Mmgt. Scoping ... AND ... *** Extensibility ***
  • CDI:Leichtegichtig CDI Konzepte Typensicher DI (Stereotypes, Qulifier) Loose Koopelung (Events, Interceptors) Sichtbarkeiten (Sopes, LifeCycle ) „FACHLICHE INJECTION“
  • > DI/IoC lite „Java EE without EJB“ > DI/IoC advanced LifeCyle Management und Scoping > DI/IoC eXtreme Typensicherheit und lose Koppelung > DI/IoC open Extension-MechanismusCDI Kickstart
  • Base Features
  • Base Features> @Inject> @Named> Sterotypes> Alternatives
  • Base Features > Sope Singleton > Cleanup > Request > Conversation > Session > Application > Dependant* > Singleton**Pseudo-Scope
  • Base Features
  • Base Features
  • Base Features> Events> Observer> Interceptors
  • Base Features> Qualifier> Stereotypes> Alternatives
  • > Was haben wir gewonnen?
  • > SCHICHT 1> SCHICHT 2> SCHICHT 3
  • > SCHICHT 1> SCHICHT 2> SCHICHT 3
  • CDI Managed Beanimport javax.inject.Named; „hello“ für ELimport javax.inject.Inject;import javax.enterprise.context.RequestScoped;@Named(“hello“)@RequestScoped gültig für Requestpublic class HelloBean {@Inject Greeter greeter; Injection Pointprivate String name;public String getGreeting() { return greeter.greet(name);}// getter and setter for name attribute...}
  • CDI Managed Bean Simple POJOpublic class Greeter {public String greet(Sting name) { if (name != null) { return “Hello, “ + name; } else { return “Hello, stranger!“; }}}
  • CDI Managed Bean Stateless EJB@Statelesspublic class GreeterEJB implements Greeter {private static final Log logger = ...@Inject @Current CrmUser crmUser;public String greet(Sting name) { logger.debug(“Who: “ + crmUser.getName()); if (name != null) { ... // create & return greeting }}}
  • CDI Cool, aber geht daMehrwert nicht mehr?
  • 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 AuthenticationController@Named@SessionScopedpublic class AuthenticationController implements Serializable { private User authenticatedUser; public String authenticate() {...} @Produces @Current public User getAuthenticatedUser() {...} ...}
  • eCustomer - CDI Current User@Named@SessionScopedpublic class AuthenticationController implements Serializable { private User authenticatedUser; public String authenticate() {...} @Produces @RequestScoped @Current public User getAuthenticatedUser() {...} ...} @Inject @Current User user;
  • eCustomer - CDI Current User Self-made Qualifierpackage de.openknowledge.qualifier;import ...@Qualifier@Target({TYPE, METHOD, PARAMETER, FIELD})@Retention(RUNTIME)public @interface Current{}
  • eCustomer - CDI Current User JSF CustomerBean@javax.inject.Named@javax.context.enterpise.SessionScopedpublic class CustomerBean implements Serializable { // @javax.inject.Inject // private AuthenticationController authController; @javax.inject.Inject private CustomerService customerService; public String update() { // User currentUser =authController.getAuthenticatedUser(); // currentCustomer.updateAuditInformation(currentUser); customerService.updateCustomer(currentCustomer); return Outcome.SUCCESS; Audit „Bereinigung“ } ...}
  • Use Case „Kunde bearbeiten“ CustomerService EJB@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); }}
  • 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 CustomerService CDI@Stateless// no annotation required!public class CustomerServiceBeanEJB 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); } ...}
  • eCustomer - CDI Beans only CustomerService CDI@Stateless// no annotation required!public class CustomerServiceBeanEJB implements CustomerService { @Inject @Current private User currentUser; @PersistenceContext Und Transaktionen?! private EntityManager em; // updates the customer - needs a transaction public Customer updateCustomer(Customer customer) { customer.updateAuditInformation(currentUser); return em.merge(customer); } Bauen wir uns selbst ... ...}
  • eCustomer - CDI Beans only CustomerService CDI// simple pojo// no annotation required!public class CustomerServicBean implements CustomerService { @Inject @Current private User currentUser; @PersistenceContext private EntityManager em; @Transactional public Customer updateCustomer(Customer customer) { customer.updateAuditInformation(currentUser); return em.merge(customer); } ...}
  • CDIInterceptors
  • eCustomer - CDI Beans only? @InterceptorBinding @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) public @interface Transactional { @Nonbinding public TransactionalType value() default TransactionalType.REQUIRED; } Transactional Annotation
  • eCustomer - CDI Beans only Transactional Interceptor*@Transactional@Interceptorpublic class TransactionAdvice { @Inject private UserTransaction utx; @AroundInvoke public 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
  • eCustomer - CDI Beans only Transactional Interceptor*@Transactional@Interceptorpublic class TransactionAdvice { @Inject private UserTransaction utx; @AroundInvoke public 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
  • eCustomer - CDI Beans only CustomerService CDI// no annotation required!public class CustomerServiceBean implements CustomerService { @Inject @Current private User currentUser; @PersistenceContext private EntityManager em; @de.openknowledge.qualifier.Transactional public Customer updateCustomer(Customer customer) { customer.updateAuditInformation(currentUser); return em.merge(customer); inkl. Transaktion } ...}
  • > SCHICHT 1TX Grenze > SCHICHT 2 > SCHICHT 3
  • TX Grenze > SCHICHT 1 > SCHICHT 2 > SCHICHT 3
  • eCustomer - CDI Beans only CustomerBean CDI@Named@SessionScopedpublic class CustomerBean implements Serializable { @Inject private CustomerService customerService; @de.openknowledge.qualifier.Transactional public String update() { customerService.updateCustomer(currentCustomer); ... // some additional use case “tx“ related work return Outcome.SUCCESS; } ... inkl. „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 Views CustomerBean (1/2)@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) { conversation.begin(); this.customer = customer; return ... ; } ...}
  • eCustomer - CDI Style Views CustomerBean (2/2)@javax.inject.Named@javax.context.enterpise.ConversationScopedpublic class CustomerBean implements Serializable { private Customer customer; @javax.inject.Inject private Conversation conversation; public String updateCustomer() { ... conversation.end(); return ... ; } Conversation endet mit Request ...}
  • eCustomer - CDI Style Views<html ...> Infrastructure in der View! <h:body> <h:form> Vorname: <h:inputText value=“#{customerBean.customer.firstname}"/> Name: <h:inputText value=“#{customerBean.customer.lastname}"/> </h:form> </h:body></html>
  • eCustomer - CDI Style Views<html ...> Fachlichkeit in der View! <h:body> <h:form> Vorname: <h:inputText value=“#{selectedCustomer.firstname}"/> Name: <h:inputText value=“#{selectedCustomer.lastname}"/> </h:form> </h:body></html>
  • eCustomer - CDI Style Views CustomerBean@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; } ...}
  • 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!“„Ah, interessant.“ „Und ich auch!“ „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 Customer Created Event (1/3) public class CustomerCreatedEvent { private Customer customer; public CustomerCreatedEvent(Customer customer) { this.customer = customer; } public Customer getCustomer() { ... }}„Wie sieht ein solches Event aus?“
  • eCustomer - CDI Events Customer Created Event (2/3) public void sendWelcomeMail( @Observes CustomerCreatedEvent event) { Customer customer = event.getCustomer(); ... }„Und wie fange ich es?“
  • eCustomer - CDI Events Customer Created Event (3/3) @Inject private Event<CustomerCreatedEvent> eventSource; public String createCustomer() { Customer customer = ...; eventSource.fire( new CustomerCreatedEvent(customer) ); ... }„Und vor allem: Wie löse ich es aus?“
  • eCustomer - CDI Events„Wird das Event Objecttatsächlich benötigt oder gibtes eventuell nochAlternativen?“ „Nicht unbedingt, man kann auch sehr gut mit eigenen Qualifiern arbeiten!“
  • eCustomer - CDI Events Qualified CDI Event (1/3)@Qualifier@Target({TYPE, METHOD, PARAMETER, FIELD})@Retention(RUNTIME)public @interface Created{}
  • eCustomer - CDI Events Qualified CDI Event - Alternative (2/3) public void sendWelcomeMail( @Observes CustomerCreatedEvent event @Created Customer customer) { Customer customer = event.getCustomer(); ... }„Und wie fange ich es?“
  • eCustomer - CDI Events Qualified CDI Event - Alternative (3/3) @Inject @Created private Event<Customer> eventSource; public String createCustomer() { Customer customer = ...; eventSource.fire(customer); ... }„Und vor allem: Wie löse ich es aus?“
  • eCustomer - CDI Events„Wow! Observer mit Qulifiern -das muss ich erst einmalsacken lassen!“ „Und das ist erst die Spitze des Eisberges - schau dir mal die CONDITIONAL OBSERVER METHODS hier an!“
  • eCustomer - CDI Events Conditional Observer Methods// 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) {...}
  • TX Grenze > „No-Tier“
  • Fazit:X
  • CDI FazitCDI ermöglicht ...“Java Enterprise Development without EJB -and without Spring“CDI bietet dafür ...typesafe und schichtenneutrales Injection„Framework für fachliche und technischeInjection sowie ein Rahmenwerk füreventgetriebene Entwicklung.“
  • @mobileLarson @_openknowledgefacebook.com/openknowledgeGibt es nochFragen?Dann los ...