2012 04-09-v2-tdp-1167-cdi-bestpractices-final


Published on

  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • CDI brings Dependency Injection to a new level. Within the first two years of its existence, CDI quickly rose from anunknown little JSR to now being unanimously considered the star of Java EE 6.
  • Bean Type The bean type is the set of Java types that the bean provides. CDI injection always uses type as the primary identifier for determining the bean that will provide an instance. Unless otherwise restricted, a bean’s type includes all the superclasses and interfaces in the Java type hierarchy.
  • Sometimes, a bean type alone does not provide enough information for the container to know whichbean to inject. For instance, suppose we have two implementations of the PaymentProcessorinterface: CreditCardPaymentProcessor and DebitPaymentProcessor. Injecting a field of typePaymentProcessor introduces an ambiguous condition. In these cases, the client must specify some additionalquality of the implementation it is interested in. We model this kind of "quality" using a qualifier.A qualifier is a user-defined annotation that is itself annotated @Qualifer. A qualifier annotation is an extension ofthe type system. It lets us disambiguate a type without having to fall back to string-based names. Here's an exampleof a qualifier annotation:Qualifiers allow extra type information to be supplied whilekeeping the reference type generic● A Qualifier provides guidance to CDI about which bean classshould be used. ● An injection point can use multiple qualifiers. All qualifiersmust be present on the bean.@Qualifier@Target({TYPE, METHOD, PARAMETER, FIELD})@Retention(RUNTIME)public @interface CreditCard {}There may be multiple beans that implement a desired Java type. It is possible to distinguish between multiple types using qualifier annotations. Qualifiers are developer-defined and provide a type-safe way to distinguish between multiple beans implementations. qualifier type represents some client-visible semantic associated with a type that is satisfied by some implementations ofthe type (and not by others). For example, we could introduce qualifier types representing synchronicity and asynchronicity.In Java code, qualifier types are represented by annotations.
  • Java EE components such as servlets, EJBs and JavaBeans do not have a well-defined scope. These components are either:• singletons, such as EJB singleton beans, whose state is shared between all clients,• stateless objects, such as servlets and stateless session beans, which do not contain client-visible state, or• objects that must be explicitly created and destroyed by their client, such as JavaBeans and stateful session beans,whose state is shared by explicit reference passing between clients.Scoped objects, by contrast, exist in a well-defined lifecycle context:• they may be automatically created when needed and then automatically destroyed when the context in which they werecreated ends, and• their state is automatically shared by clients that execute in the same context.All beans have a scope. The scope of a bean determines the lifecycle of its instances, and which instances of the bean arevisible to instances of other beans, as defined in Chapter 6, Scopes and contexts. A scope type is represented by an annotationtype.For example, an object that represents the current user is represented by a session scoped object:All beans have a well-defined scope that determines the lifecycle and visibility of instances. The set of scopes is fully extensible, with built-in scopes including request scope, conversation scope, session scope and application scope. Beans can also be dependent and inherit the scope of their injection point An instance of a session-scoped bean is bound to a user session and is shared by all requests that execute in thecontext of that session
  • Java EE components such as servlets, EJBs and JavaBeans do not have a well-defined scope. These components are either:• singletons, such as EJB singleton beans, whose state is shared between all clients,• stateless objects, such as servlets and stateless session beans, which do not contain client-visible state, or• objects that must be explicitly created and destroyed by their client, such as JavaBeans and stateful session beans,whose state is shared by explicit reference passing between clients.Scoped objects, by contrast, exist in a well-defined lifecycle context:• they may be automatically created when needed and then automatically destroyed when the context in which they werecreated ends, and• their state is automatically shared by clients that execute in the same context.All beans have a scope. The scope of a bean determines the lifecycle of its instances, and which instances of the bean arevisible to instances of other beans, as defined in Chapter 6, Scopes and contexts. A scope type is represented by an annotationtype.For example, an object that represents the current user is represented by a session scoped object:All beans have a well-defined scope that determines the lifecycle and visibility of instances. The set of scopes is fully extensible, with built-in scopes including request scope, conversation scope, session scope and application scope. Beans can also be dependent and inherit the scope of their injection point An instance of a session-scoped bean is bound to a user session and is shared by all requests that execute in thecontext of that sessionScope DescriptionDependent A dependent reference is created each time it is injected and the reference isremoved when the injection target is removed. This is the default scope for CDIand makes sense for the majority of cases.ApplicationScoped An object reference is created only once for the duration of the application and theobject is discarded when the application is shut down. This scope makes sense forservice objects, helper APIs or objects that store data shared by the entireapplication.RequestScoped An object reference is created for the duration of the HTTP request and isdiscarded when the request ends. This makes sense for things like data transferobjects/models and JSF backing beans that are only needed for the duration of anHTTP request.SessionScoped An object reference is created for the duration of an HTTP session and isdiscarded when the session ends. This scope makes sense for objects that areneeded throughout the session such as maybe user login credentials.ConversationScoped A conversation is a new concept introduced by CDI. It will be familiar to Seamusers, but new to most others. A conversation is essentially a truncated sessionwith start and end points determined by the application, as opposed to the sessionwhich is controlled by the browser, server and session timeout. There are twotypes of conversations in CDI -- transient which basically corresponds to a JSFrequest cycle and long-running which is controlled by you via the Conversion.beginand Conversion.end calls. A transient conversation can be turned into along-running one as needed. Conversations are very useful for objects that areused across multiple pages as part of a multi-step workflow. An order or shoppingcart is a good example. Conversations deserve detailed discussion so we will takea much closer look at them in a later article in the series.
  • Although it’s completely optional, beans may define an EL name that can be used for non-type safe access. One common usage of EL name is for binding components to JavaServer Faces (JSF) views. used in places where CDI’s type-based lookup is not possible.
  • http://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export/home/httpd/javaworld/javaworld/jw-01-2006/jw-0130-proxy.html&pagename=/javaworld/jw-01-2006/jw-0130-proxy.html&pageurl=http://www.javaworld.com/javaworld/jw-01-2006/jw-0130-proxy.html&site=jw_corehttp://java.sys-con.com/node/38672
  • Alternatively, an alternative may be declared by annotating a bean, producer method or producer field with a stereotypethat declares an @Alternative annotation.If an interceptor or decorator is an alternative, non-portable behavior results.Qualifiers allow class selection but require modification tosource code and recompiling if they need to be changed● Alternatives allow CDI to alternate bean classes based onXML configuration data (beans.xml)● Alternative classes (annotated with @Alternative) aredisabled by default● An enabled (via beans.xml) alternative class takesprecedence over a non-alternative class● Two enabled alternative classes matching the samequalifiers on an injection point would result in an exception
  • Almost always use @Inject● Lets you use interceptors, delegates, scope based beans,qualifiers, etc● Can inject EJBs● @EJB is okay for remote session beans in some cases● Lets you specify a JNDI name● @Resource is seldom needed● Injecting a DataSource● Producers can be used to enable @Inject based injectionfor @EJB and @Resource dependencies if needed
  • Any calls to the delegate object that correspond to a decorated type will be called on the decorator, which may in turn invoke the method directly on the delegate object.
  • http://www.dzone.com/links/r/decoupling_event_producers_and_consumers_in_jee6.htmlhttp://www.adam-bien.com/roller/abien/entry/java_ee_6_observer_withEvent Producer -> Event Consumer(s) [foreground thread]Event Producer -> Event Sender -> JMS Queue [foreground thread]JMS Queue -> Event Dispatcher -> Event Consumer [background threadIf there are multiple observers for an event, the order that they are called in is not definedCDI will automagically wire EventProducer and EventConsumer so that when EventProducer fires the event, EventConsumer.afterMyEvent gets called
  • Strategy Pattern: there are already several implementations of an algorithm or conceptLayering: there is a clear need to hide e.g. an ugly implementation of a legacy frameworkAPI (not very common): you have to expose a API, which gets implemented by SPI (e.g. JDBC)
  • Many of the modules developed in Seam 3 demonstrate thissuch as ‘Mail’, ‘JMS’, ‘JCR’, ‘Reports’ and ‘Spring’-Integration.All of these modules came from the community as a holewas discovered while using the technologies and seeking amore unified and simpler approach for developers.
  • www.parleys.com/d/3097https://issues.jboss.org/sr/jira.issueviews:searchrequest-printable/temp/SearchRequest.html?jqlQuery=project+%3D+CDI+AND+fixVersion+%3D+%221.1+%28Proposed%29%22+AND+status+%3D+Open+ORDER+BY+priority+DESC&tempMax=100
  • 2012 04-09-v2-tdp-1167-cdi-bestpractices-final

    1. 1. Patterns and Best Practices for Contexts for Dependency Injection Rohit Kelapure WebSphere Application Server Caching Architect Apache OpenWebBeans Committer IBM http://wasdynacache.blogspot.com/ Session ID = TDP-11671
    2. 2. Contributions from Mark Struberg, Gerhard Petracek, Arne Limburg, Reza Rahman & Ryan Cuprak  http://www.slideshare.net/os890/  https://cwiki.apache.org/confluence/display/EXTCDI/External  http://people.apache.org/~struberg  http://www.openknowledge.de/?id=62#139  http://www.slideshare.net/os890/make-jsf-more-typesafe-with- cdi-and-myfaces-codi  http://www.slideshare.net/os890/myfaces-codi-conversations  http://people.apache.org/~struberg/jax2012/cdi- basics_jax2012.pdf  http://people.apache.org/~struberg/jax2011/JSR- 299_JAX_2011.pdf  http://www.rahmannet.net/downloads/cdi_best_practices.pdf2 Session ID: TDP 1167
    3. 3. Agenda  Tour of CDI (Contextual Dependency Injection)  Common Pitfalls  New Programming Patterns  Best Practices  CDI Extension Programming  CDI Extensions3 Session ID: TDP 1167
    4. 4. 4 Contextual Dependency Injection JSR299  Future of JEE  Loose Coupling – Server & Client, Components, Concerns & Events  Design pattern Specific type of IoC – Don’t call us, we will call you – No hard coded dependencies  Inspirations SEAM, Spring, Guice  Dramatic reduction in LOC  Goes far beyond what was possible with Java EE5  Not only an API but also a SPI  Spec compliant way to modify the EE platform via CDI extensions4 Session ID: TDP 1167
    5. 5. 5 CDI Services  Contextual State and lifecycle mgmt.  Typesafe dependency injection  Interceptors and decorators – extend behavior with typesafe interceptor bindings  SPI enables portable extensions – integrates cleanly with Java EE  Adds the Web conversation context – + to standard contexts (request, session, application)  Unified component model – Integration with the Unified EL • Enables use of EJB 3.0 components as JSF managed beans  Events decouple producers and consumers5 Session ID: TDP 1167
    6. 6. 6 Relationship to other Java EE Specs  Contextual lifecycle mgmt. for EJBs – Session bean instances obtained via DI are contextual • Bound to a lifecycle context • Available to others that execute in that context • Container creates instance when needed • Container Destroys instance when context ends  Contextual lifecycle mgmt. for Managed Beans  Associate Interceptors with beans using typesafe interceptor bindings  Enhances JSF with a sophisticated context & DI model – Allows any bean to be assigned an unique EL name6 Session ID: TDP 1167
    7. 7. 7 What is a CDI Managed Bean  Concrete POJO (exception for @Decorator) – Must have a no-argument constructor or constructor annotated @Inject – Cannot be a static inner class – Opt in with a beans.xml  Objects returned by producers  Additional types defined by CDI SPI  Defined to be a managed bean by its EE specification – EJB session beans (local or remote) – Message Driven Beans – JEE Resources (DataSources, JMS Destinations) – Persistent Unit, Persistent Contexts – Web Service References – Servlets, Filters, JSF Managed Beans, Tag Libraries …  Built-in Beans – JTA User Transaction – Security Principal representing caller identity – Bean Validator & Validation Factory7 Session ID: TDP 1167
    8. 8. 8 CDI Packaging  Bean classes packaged in a Bean Deployment Archive  To activate CDI create a beans.xml file (can be empty) – META-INF – WEB-INF/classes  Container searches for beans in all bean archives in application classpath  http://java.sun.com/xml/ns/javaee/beans_1_0.xsd8 Session ID: TDP 1167 * Picture source Norman Richards
    9. 9. 9 Types of CDI Injection  Field Injection  Parameter Injection – Observer, producer & disposer methods – Initializer methods @ConversationScoped public class Order { @Inject @Selected Product product; //Field injection @Inject //Initializer method void setProduct(@Selected Product product) { this.product = product; } }9 Session ID: TDP 1167
    10. 10. 10 Bean Definition Bean Type Qualifier Scope EL Name Interceptors Implementation10 Session ID: TDP 1167
    11. 11. 11 Bean Types public class BookShop extends Business implements Shop<Book>{ ... } Client visible Bean types – BookShop, Business, Shop<Book>, Object @Stateful public class BookShopBean extends Business implements BookShop, Auditable { ... } Bean types – BookShop, Auditable , Object Can be restricted using the @Typed annotation – @Typed(Shop.class) public class BookShop11 Session ID: TDP 1167
    12. 12. 12 Qualifiers  Distinguish between beans of the same Type @ASynchronous class AsynchronousPaymentProcessor implements PaymentProcessor { ... } @Synchronous class SynchronousPaymentProcessor implements PaymentProcessor { ... } //Qualifier type @Qualifier @Target({TYPE, METHOD, PARAMETER, FIELD}) @Retention(RUNTIME) public @interface Synchronous{}  Specifying qualifiers on an injected bean aka Client @Inject @Synchronous PaymentProcessor12 Session ID: TDP 1167
    13. 13. 13 Qualifiers Cont…  Bean can define multiple qualifier types – Injection Point only needs enough qualifiers to uniquely identify a bean  Every bean – Built-in qualifier @Any – Default qualifier @Default when one is not explicitly declared  Producer methods and fields can also use qualifiers @Produces @Asynchronous public PaymentProcessor createAsynchronousProcessor() { return new AsynchronousPaymentProcessor(); }  Qualifiers with members @Target({FIELD, PARAMETER}) @Retention(RUNTIME) @Qualifier public @interface Currency { public String code(); } // client @Inject @Currency(code=“USD”) PaymentProcessor processor;13 Session ID: TDP 1167
    14. 14. 14 Scope: Lifecycle & Visibility of Instances  Scoped Objects exist a lifecycle context – Each bean aka contextual instance is a singleton in that context – Contextual instance of the bean shared by all objects that execute in the same context // Session scoped bean shared by all requests // that execute in the context of that session public @SessionScoped class ShoppingCart implements Serializable { ... } @Produces @RequestScoped @Named("orders") List<Order> getOrderSearchResults() { ... } @ConversationScoped public class Order { ... } @Produces @SessionScoped User getCurrentUser() { ... }14 Session ID: TDP 1167
    15. 15. 15 Scope: Lifecycle & Visibility of Instances  Normal Scopes – @RequestScoped DTO/Models, JSF Backing beans – @ConversationScoped Multi-step workflow, Shopping Cart – @SessionScoped User login credentials – @ApplicationScoped Data shared by entire app, Cache  Pseudo scope – @Dependent (default scope) makes sense for majority • Bound to the lifecycle of the object they were injected  Qualifier – @New (new instance will be created) • Not bound to the declared scope • Has had DI performed  Custom scopes provided by Extensions – OpenWebBeans provides @ViewScoped through the Jsf2ScopesExtension15 Session ID: TDP 1167
    16. 16. 16 EL Name: Lookup beans in Unified EL  Binding components to JSF Views Specified using the @Named annotation public @SessionScoped @Named("cart“) class ShoppingCart implements Serializable { ... } Now we can easily use the bean in any JSF or JSP page <h:dataTable value="#{cart.lineItems}" var="item"> ... </h:dataTable>  Container derives default name in absence of @Named – Unqualified short class name of the bean class  @Named is a built-in Qualifier16 Session ID: TDP 1167
    17. 17. 17 Interceptors Separate cross-cutting concerns from business logic Associate Interceptors to beans using Interceptor Bindings @Inherited @InterceptorBinding //Interceptor Binding Type definition @Target({TYPE, METHOD}) @Retention(RUNTIME) public @interface Transactional {} //Declaring Interceptor Bindings of an Interceptor @Transactional @javax.interceptor.Interceptor public class TransactionInterceptor { @AroundInvoke public Object manageTransaction(InvocationContext ctx) throws Exception { ... } } //Binding Interceptor to Bean @Transactional public class ShoppingCart { ... } public class ShoppingCart { @Transactional public void placeOrder() { ... } }17 Session ID: TDP 1167
    18. 18. 18 Interceptors  Enabled manually in the beans.xml  Order defined in beans.xml  @Dependent object of the object it intercepts <beans> <interceptors> <class>org.mycompany.TransactionInterceptor</class> <class>org.mycompany.LoggingInterceptor</class> </interceptors> </beans>18 Session ID: TDP 1167
    19. 19. 19 Implementation Design Patterns  Bean Implementation provided by – Developer … Java class – Container … Java EE env. Resource beans  Contextual Singleton  All Normal scoped beans are proxied – Contextual Reference implies a proxy for a contextual instance  Dynamic Proxies – Passivation of contextual instances – Scope Management • Narrower scope injected into a wider scope  Chaining of Dynamic Proxies – Interceptor and Decorator chaining19 Session ID: TDP 1167
    20. 20. 20 Alternatives  Deploy time selection of bean implementation  Alternate implementation of bean – Explicitly enabled in the beans.xml – Overrides the original bean @Alternative // annotate bean class, producer method or field @Specializes public class MockOrder extends Order { ... // alternative implementation } <beans> <alternatives> <class>org.example.MockOrder</class> </alternatives> </beans>  @Specializes – Alternate inherits the metadata (name, qualifiers ) etc of the parent20 Session ID: TDP 1167
    21. 21. 21 Stereotypes  Stereotype bundles @Target(TYPE) @Retention(RUNTIME) – Scope public @interface Action {} – Interceptor Bindings – @Named – @Alternative  Built-in Stereotypes – @Model  Bean annotated with a stereotype inherits all – @Decorator annotations of the stereotype – @Interceptor @RequestScoped  @Alternative applied to a @Secure stereotype @Transactional – ALL beans with that stereotype are enabled/disabled as a group @Named @Stereotype21 Session ID: TDP 1167
    22. 22. 22 Producers  Application control of bean instance creation & destruction  Producer Fields public class Shop { @Produces @ApplicationScoped @Catalog @Named("catalog") List<Product> products = ....; }  Producer Methods public class Shop { @Produces @ApplicationScoped @Catalog @Named("catalog") List<Product> getProducts(CatalogID cID) { ... } }  Disposer Methods – Customized cleanup of object returned by a producer method public class Shop { public void close(@Disposes @Catalog List<Product> products) { products.clear(); } }22 Session ID: TDP 1167
    23. 23. 23 Injecting Java EE Resources  When injecting EJBs – Use @Inject to get Contextual Injection – Use @EJB ONLY for remote session beans  Define producers making EE types available for injection… non contextual injection @Produces @WebServiceRef(lookup="java:app/service/PaymentService") PaymentService paymentService; @Produces @PersistenceContext(unitName="CustomerDatabase") @CustomerDatabase EntityManager customerDatabasePersistenceContext;  Consume the Injected types in other CDI Beans @Inject @CustomerDatabase EntityManager myEntityManager @Inject PaymentService myPaymentService23 Session ID: TDP 1167
    24. 24. 24 Decorators  Implements one or more bean types – Can be abstract – Implements the interface it is decorating  Extend bean types with function specific to that type  Called after interceptors  Explicitly enabled in the beans.xml public interface Htmlable { String toHtml(); } //interface public class HtmlDate extends Date implements Htmlable { public String toHtml() { //date class that knows its HTML representation return toString(); } } @Decorator public class StrongDecorator implements Htmlable { @Inject @Delegate @Any private Htmlable html; public String toHtml() { //decorator that puts the HTML inside <strong> tags return "<strong>" + html.toHtml() + "</strong>"; } }24 Session ID: TDP 1167
    25. 25. 25 Events: Observer Pattern public class MyEvent { String data; Date eventTime; .... } // Event is a POJO // Event<MyEvent> is injected automatically by the container @Stateless @Named (“producer”) public class EventProducer { @Inject @My Event<MyEvent> event; //@My is a Qualifier public void doSomething() { event.fire(new MyEvent()); } } // Declare method that takes a parameter with @Observes annotation @Stateless // Transactional, Conditional observer public class EventConsumer { public void afterMyEvent( @Observes(during=AFTER_SUCCESS receive=IF_EXISTS) @My MyEvent event) { // .. Do something with MyEvent } } <h:form> // Fire the event from a JSF 2.0 Page <h:commandButton value="Fire!" action="#{producer.doSomething}"/> </h:form>25 Session ID: TDP 1167
    26. 26. 26 CDI Implementation in WAS  WAS CDI implementation is based on Apache OpenWebBeans – OpenWebBeans release 1.0.0 + fixes  Changes & additions on top of OpenWebBeans to support integration with the server run time – Integration with other Java EE containers like JSF, Servlet & EJB container that support injectable components. – Proprietary ScannerService implementation – Direct use of EJB metadata for determining EJB types. – Automatic registration of Servlet Listeners, Filters, Interceptors for CDI applications – WebSphere Application Server-specific implementations of many OpenWebBeans Service Programming Interfaces (SPI) • ResourceInjectionService, TransactionService, failover service…26 Session ID: TDP 1167
    27. 27. 27 CDI Bean Failover in WAS  WAS supports failover (activation & passivation) of CDI beans & enterprise beans, along with their interceptors and decorators  EJB failover support with CDI ONLY works for Stateful Session Beans and requires the same configuration as Stateful Session Bean failover  Configure EJB failover with web HTTP session failover  Except for abstract decorators, failover services are based on current WAS failover providers  Both Web session failover and EJB SFSB failover need to configured27 Session ID: TDP 1167
    28. 28. Pitfalls CDI Exception How to Fix AmbiguousResolutionException Add qualifiers or alternatives to @Inject to More than one bean eligible for injection. narrow bean resolution. Disable alternatives. Annotate class with @Typed UnproxyableResolutionException Ensure that bean types are legal. Check if class bean type cannot be proxied by the container is declared final, has final methods or private CTOR with no parameters UnsatisfiedResolutionException Remove qualifiers from injection point or add No bean eligible for injection qualifiers to existing types. Enable alternatives BusyConversationException Before starting a conversation check if one Rejected request b/c concurrent request is already exists using Conversation.isTransient() associated with the same conversation context. NonexistentConversationException Check if conversation is being propagated with Conversation context could not be restored the cid GET request parameter ContextNotActiveException Ensure that methods on the injected bean are Bean invocation in inactive context called in a context that is active as defined by the scope of the bean. ObserverException Fix observer method code that throws the Exception is thrown while handling event exception.28 Session ID: TDP 1167
    29. 29. Program pattern - @Typed  Defines the Java Type which should be used for that bean  Possible to disable a bean with @Typed() to prevent AmbiguousResolutionExceptions @Typed() // basically disables this Bean public class MenuItem implements Serializable { @ApplicationScoped public class TrackReadOnlyService { public Track readTrack(int id) {..} } @Typed(TrackReadWriteService.class) @ApplicationScoped public class TrackReadWriteService extends TrackReadOnlyService { public void writeTrack(Track t) {..} }  Handy for subclasses which should NOT conflict with their parent class types29 Session ID: TDP 1167
    30. 30. Program pattern - Cache Cleaning via Events  If user changes the language or logs in, then we need to change the menu @SessionScoped public class Menu { private @Inject MenutItem parentMenu; protected reloadMenu(@Observes UserSettingsChangedEvent uscE) { parentMenu = menuSvc.loadMenu(); } }30 Session ID: TDP 1167
    31. 31. Program Pattern – Type safe configuration  Configuration without properties or XML files  Just create an Interface or default config class – public interface MyConfig{ – String getJdbcUrl(); – }  Later just implement @Specializes, @Alternative, @ProjectStageActivated, @ExpressionActivated for your configuration implementation31 Session ID: TDP 1167
    32. 32. Program Pattern - Dynamic Resolution @Inject @Any private Instance<BusService> busSvcSource; private BusService busSvc; .. @PostConstruct protected init() { busSvc = busSvcSource.select( user.isAdmin() ? new AnnotationLiteral<Default>() {} : new AnnotationLiteral<Cached>() {} ).get(); } @Inject @Any Instance<ServiceX> svcXSource; .. @Produces @TenantSpecific @RequestScoped public ServiceX getSvcX(Tenant t) { return svcXSource.select(..).get(); }32 Session ID: TDP 1167
    33. 33. Best Practice- Scopes  Scopes – Components with appropriate scopes maximize memory usage.  Scopes remove boilerplate state maintenance code – especially at presentation tier.  Make judicious use of conversations  Leverage appropriate conversation scope from MyFaces CODI33 Session ID: TDP 1167
    34. 34. Best Practice - Qualifiers with enums @Qualifier @Qualifier @Retention(RUNTIME) @Retention(RUNTIME) @Target({ FIELD, TYPE }) @Target({ FIELD, TYPE }) public @interface MailSenderType { public @interface Admin {} MailSenderTypes value(); } @Qualifier public enum MailSenderTypes { @Retention(RUNTIME) ADMIN, SUPPORT @Target({ FIELD, TYPE }) } public @interface Support {} @Inject @MailSenderType(MailSenderTypes.SU @Inject @Support PPORT) private MailSender private MailSender mailSender; mailSender;34 Session ID: TDP 1167
    35. 35. Best Practice – Interceptors, Decorators, Naming  Interceptors are designed for system-level crosscutting concerns very decoupled from business logic.  Decorators intended for concerns that should be compartmentalized but are still very close to business logic.  Naming Only necessary to name components that are referenced outside of Java such as in JSF/Facelets via EL.  Naming Default names are good enough.  Naming Be careful of naming conflicts – name-based resolution not type-safe!  Naming Choose names that add to readability/API fluency  Stereotypes Encapsulate specialized behavior & component groups of recurring metadata35 Session ID: TDP 1167
    36. 36. Best Practice - Injection  Declarative, static injection sufficient for most cases  @Produces & @Disposes used when objects must be programmatically created/destroyed  Look-up using Instance used when dependencies need to be resolved at runtime  For dynamic resolution BeanManager.getBeans SPI can be used  Java EE 5 introduced limited, specialized, name-based resource injection via annotations - @Resource, @EJB, @PersistenceContext  CDI provides powerful, general purpose, type-safe injection  Favor CDI for greater flexibility36 Session ID: TDP 1167
    37. 37. Best Practice - Integration CDI & EJB  Use EJB for enterprise services – like transactions, security  Use CDI managed beans otherwise – EJB does have overhead  Avoid plain managed beans  EJBs most appropriate for service/business logic tier  CDI makes it possible to use EJBs as JSF managed beans – only good practice for RAD/prototyping  Using EJB services without EJB  Interfaces are optional37 Session ID: TDP 1167
    38. 38. Best Practice- How to deal with Interfaces  Interfaces are evil  In Java EE 6 interfaces are absolutely optional – Inject classes directly  Eliminate interfaces – Considerably reduce the number of files – Code becomes easier to understand & maintain  Not needed for decoupling purposes – EJB 3.1 / CDI bean be directly exposed over SOAP or REST  Should be used ONLY for – Strategy Pattern – Layering – APIs (not very common)38 Session ID: TDP 1167
    39. 39. Best Practice - Integration CDI & JSF  CDI more powerful replacement to JSF managed beans  Seam Faces and CODI MyFaces excellent enhancements  CDI naming, scopes, producers, qualifiers work in powerful ways with JSF  CDI designed with JSF in mind, but not limited to JSF  Wicket, Struts 2, Spring MVC have CDI extensions for integration.  Replace all JSF managed beans and scopes with corresponding CDI scopes39 Session ID: TDP 1167
    40. 40. Best Practice - Integration CDI & JPA  CDI/JPA bean life-cycle mismatch  Life-cycle mismatch bridged by CDI producers  Make judicious use of stateful session bean extended persistence context  Use the entitymanager-per-request design pattern by producing your EntityManager @RequestScoped public class EntityManagerProducer { private @PersistenceContext(unitName="Course") EntityManager entityManager; @Produces @RequestScoped @QCourse public EntityManager createEntityManager() { return entityManager; } public void dispose(@Disposes @QCourse EntityManager entityManager) { entityManager.close(); } } public class MyUserService { private @Inject @QCourse EntityManager em; public User getUser(long id) { return em.find(id, User.class); }40 Session ID: TDP 1167
    41. 41. Best Practice - Integration CDI & JMS  Message Producer & JMS Abstraction41 Session ID: TDP 1167
    42. 42. Best Practice - CDI as replacement for JMS  CDI provides simple lightweight local transactional publish- subscribe communication  Main goal of JMS 2.0 will be simplicity & tight integration with CDI  JMS pub-sub implementation is more powerful, flexible; however requires more code  CDI events are delivered synchronously  Events can be asynchronously consumed with an EJB 3.1 bean. @Stateless public class MessageListener { @Asynchronous public void onImportantMessage( @Observes @Importance(Importance.Degree.HIGH) String message){ System.out.println("+Important " + message); }42 Session ID: TDP 1167 }
    43. 43. 43 CDI Extensions  Portable – Activated by dropping jars on the application classpath – Loaded by the java.util.ServiceLoader – Tools/utilities, extending Java EE, integration with Java EE APIs & integrating with non- standard APIs, environments  Service provider of the service javax.enterprise.inject.spi.Extension declared in META- INF/services  Code to javax.enterprise.inject.spi .* interfaces  Integrate with container through container lifecycle events by – Providing its own beans, interceptors and decorators – Injecting dependencies into its own objects – Providing a context implementation for a custom scope – Augmenting or overriding the annotation-based metadata with other source43 Session ID: TDP 1167
    44. 44. CDI Extension code sample  My Faces CODI ProjectStageActivated Before Process Process After Process After Bean Bean Annotated Injection Deployment Beans Discovery Discovery Type Targets Validation • Add scope • Veto bean • Replace • Prepare • Add bean • Assessment • Add annotated candidate Injection target additional • Add context type • Replace beans • Add observer • Add annotated type method interceptor binding • Add stereotype44 Session ID: TDP 1167
    45. 45. Apache MyFaces CODI  JSF 1.2 and 2.x  Advanced I18n  Type-safety  Scripting Integration  Extensibility  And more!  Advanced Scopes  Modules  Various Events – –JSF Module (for 1.2 and 2.0 and 2.1)  View-Controller – –JPA Module  JSF 2 Scope Mappings – –BV Module  Type-safe View-Configs – –I18n-Message Module  Type-safe Navigation – –Scripting Module  JPA Integration – –Test Support Modules  Dependency Injection Support for Bean Validation45 Session ID: TDP 1167
    46. 46. Seam 3  Drools  Document Management  Faces (JSF)  Seam Application Framework  International  JMS  Security  JBoss ESB  XML Bean Config  Errai/GWT  Seam 2 Backwards  Remoting Compatiblity  Scheduling  Spring Intergration  Environment Configuration  jBPM  JAX-RS  Servlet  Transactions and Persistence46 Session ID: TDP 1167
    47. 47. Future of CDI Extensions – Apache DeltaSpike  Users have to look at several CDI extensions like JBoss, Seam 3 and Apache MyFaces CODI as well as smaller projects & blog entries  No out of- the-box optimization across different extension- projects  To combine them sometimes requires a detailed knowledge about the projects.  Goal: Add and/or merge most features in/into DeltaSpike  First releases - the community started to merge features of Apache My-Faces CODI-Core and JBoss Solder which is a central part of Seam347 Session ID: TDP 1167
    48. 48. 48 CDI 1.1 & Future  Globally enabled Interceptors and Alternatives  XML configuration  @Disposes for producer fields  Clarifies some AnnotatedType behavior  @Veto + optional beans  Relax Serialization rules  @EarApplicationScoped vs @WebApplicationScoped  https://issues.jboss.org/browse/CDI  Closer integration between other EE specs like EJB and CDI beans  Transactions, Security, Concurrency etc delivered as Interceptors that can be applied to any CDI bean  Popular CDI portable extensions rolled into DeltaSpike and future specifications48 Session ID: TDP 1167