CDI

CDI: Context and Dependency Injection

1. Java Components (how to evolve)

  • POJOs are just Java classes that run inside the Java Virtual Machine (JVM).
  • JavaBeans are just POJOs that follow certain patterns (e.g., a naming convention for accessors/mutators (getters/setters) for a property, a default constructor . . .) and are executed inside the JVM.
  • All the other Java EE components also follow certain patterns (e.g., an Enterprise JavaBean must have metadata, a default constructor can’t be final . . .) and are executed inside a container (e.g., the EJB container) that supplies some services (e.g., transaction, pooling, security . . .).
  • Managed Beans: Container-managed objects. Container provides basic services (resource injection, lifecycle management, interception)
  • Beans: CDI objects on Managed Bean Model with more services (in the following)

2. CDI services

2.1. Dependency Injection (DI)

Dependency Injection (DI) is a design pattern that decouples dependent components. Instead of an object looking up other objects, the container injects those dependent objects for you.

  • @Inject, @Resource @PersistenceContext, @PersistenceUnit, @EJB, @WebServiceRef)
  • @Inject (Injection point: property, setter, constructor)
  • Injection API

2.2. LifeCycle Management

(@PostContruct, PreDestroy)

The life cycle of a POJO is pretty simple: as a Java developer you create an instance of a class using the new keyword and wait for the Garbage Collector to get rid of it and free some memory. But if you want to run a CDI Bean inside a container, you are not allowed to use the new keyword. Instead, you need to inject the bean and the container does the rest, meaning, the container is the one responsible for managing the life cycle of the bean: it creates the instance; it gets rid of it. So how do you initialize a bean if you can’t call a constructor? Well, the container gives you a handle after constructing an instance and before destroying it.

Bean Lifesycle

The above shows the life cycle of a Managed Bean (and therefore, a CDI Bean). When you inject a bean, the container (EJB, Web, or CDI container) is the one responsible for creating the instance (using the new keyword). It then resolves the dependencies and invokes any method annotated with @PostConstruct before the first business method invocation on the bean. Then, the @PreDestroy callback notification signals that the instance is in the process of being removed by the container.

2.3. Beans in Expression Language (EL)

Integrates with EL to enable referencing objects in a given context (request, session, application, etc.) directly from Facelet or JSP pages 1) @Named(“MyBean”)  2) action=”#{MyBean,mymethod}”

2.4. Scopes and Context

  • @ApplicationScoped <= shared scope for all requests of all users of the same application
  • @SessionScoped <= user’s active session with the application
  • @RequestScoped <= particular HTTP request
  • @ConversationScoped  <= defined explicitly programmatically by the JSF application developer – can span over one or more requests with the same conversation Id (cid) (long running conversations), cannot cross the session boundaries
  • @Dependent <= default scope in which a new (unique) instances of injected beans are created for each injecting client, with the same scope as the client

2.5. Interception

Interceptors are automatically triggered by the container when a Managed Bean method is invoked.

  • @AroundConstruct
  • @AroundInvoke <= InvocationContext API
  • @AroundTimeout <= EJB Time Service
  • @PostConstruct
  • @PreDestroy

2.6. Loose Coupling and Strong Typing

Loose Coupling

  • Interceptors are a very powerful way to decouple technical concerns from business logic.
  • Contextual life-cycle management also decouples beans from managing their own life cycles. With injection a bean is not aware of the concrete implementation of any bean it interacts with. But there is more to loose coupling in CDI.
  • Beans can use event notifications to decouple event producers from event consumers or decorators to decouple business concerns.
    • @Produces: If jar doesn’t have beans.xml, use @Produces to inject data type / pojo.
    • @Disposes: destroy the corresponding @Produces
    • Event: One bean can define an event, the other can fire the event from the other package / tier. It use observed / observable design pattern (@Observes) 1) addStudent(@Observes Student student) {…} 2) @Inject private Events<Student> studentAddEvent; 3) studentAddEvent.fire(student);
    • @Decorator

Strong Typing

(use strongly typed annotations, minimize XML descriptors to wire beans together)

  • @Qualifier <= to define your own @XXX to choose multiple implementation at development time. By default, @Default is used. @Inject @XXXX or @Inject @Default
  • @Stereotype

2.7. Deployment Descriptor (beans.xml and is mandatory)

With CDI, the deployment descriptor is called beans.xml and is mandatory.

  • Configure certain functionalities (interceptors, decorators, alternatives, etc.)
    • @Alternatives <= to allow choose implementation at deployment time.
    • @Decorators <= Decorators must have a @Delegate injection point with the same type as the beans they decorated.
  • At deployment time (bean discovery): with beans.xml in your class path (under the META-INF or WEB-INF directory), POJOs into CDI Beans. CDI will not be able to use injection, interception, decoration, and so forth. Each jar will need its own beans.xml to trigger CDI and bean discovery for each jar.

3. Packages

javax.inject Contains the core Dependency Injection for Java APIs (JSR 330)

  • @Inject – Designates injectable constructors, methods, and fields
  • @Named – Allows to define EL names of the beans for JSF
  • @Qualifier – Designates qualifier annotations
  • @Singleton – Designates a type that the injector must instantiate only once

javax.enterprise.inject Core dependency injection APIs

  • @Alternative – Specifies that a bean is an alternative
  • @Any – Every bean has the qualifier @Any, except for the special @New qualified beans
  • @Default – Default qualifier type
  • @Disposes – Designates the disposed parameter of a disposer method
  • @Model = @Named + @RequestScoped (for use in JSF)
  • @New – Allows to obtain a new instance of a bean
  • @Produces – Designates a producer method or field
  • @Specializes – Indicates that a bean directly specializes another bean
  • @Stereotype – Specifies that an annotation type is a stereotype
  • @Typed – Restricts the bean types of a bean

javax.enterprise.context CDI scopes and contextual APIs
javax.enterprise.event CDI events and observers APIs
javax.enterprise.util CDI utility package
javax.interceptor Contains the Interceptor APIs (JSR 318)
javax.decorator CDI decorator APIs

4. Reference Implementation

The reference implementation of CDI is Weld from JBoss.

2.5. Examples

  • CDI01: A SIMPLE CDI SAMPLE USING WELD SE (Using @Inject, beans.xml, @Observes ContainerInitialized event, org.jboss.weld.environment.se.StartMain)
  • CDI02: ANOTHER CDI SAMPLE USING WELD SE BOOTSTRAP API (Using @PostConstruct, WELD SE Container bootstrap API)
  • Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s