[2024]Digital Global Overview Report 2024 Meltwater.pdf
Β
2012 04-09-v2-tdp-1167-cdi-bestpractices-final
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-1167
1
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.pdf
2 Session ID: TDP 1167
3. Agenda
ο§ Tour of CDI (Contextual Dependency Injection)
ο§ Common Pitfalls
ο§ New Programming Patterns
ο§ Best Practices
ο§ CDI Extension Programming
ο§ CDI Extensions
3 Session ID: TDP 1167
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
extensions
4 Session ID: TDP 1167
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 consumers
5 Session ID: TDP 1167
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 name
6 Session ID: TDP 1167
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 Factory
7 Session ID: TDP 1167
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.xsd
8 Session ID: TDP 1167
* Picture source Norman Richards
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
Bean Definition
Bean Type
Qualifier
Scope
EL Name
Interceptors
Implementation
10 Session ID: TDP 1167
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 BookShop
11 Session ID: TDP 1167
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 PaymentProcessor
12 Session ID: TDP 1167
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
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
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 Jsf2ScopesExtension
15 Session ID: TDP 1167
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 Qualifier
16 Session ID: TDP 1167
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
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
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 chaining
19 Session ID: TDP 1167
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 parent
20 Session ID: TDP 1167
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
@Stereotype
21 Session ID: TDP 1167
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
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 myPaymentService
23 Session ID: TDP 1167
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
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
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
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
configured
27 Session ID: TDP 1167
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. 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 types
29 Session ID: TDP 1167
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. 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 implementation
31 Session ID: TDP 1167
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 CODI
33 Session ID: TDP 1167
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. 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 metadata
35 Session ID: TDP 1167
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 flexibility
36 Session ID: TDP 1167
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 optional
37 Session ID: TDP 1167
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. 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 scopes
39 Session ID: TDP 1167
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. Best Practice - Integration CDI & JMS
ο§ Message Producer &
JMS Abstraction
41 Session ID: TDP 1167
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
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 source
43 Session ID: TDP 1167
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
stereotype
44 Session ID: TDP 1167
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 Seam3
47 Session ID: TDP 1167
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 specifications
48 Session ID: TDP 1167
Editor's Notes
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.
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.