Get start with CDI

CDI Quick Start

CDI, or Welding is a mechanism to assemble components (classes, methods, properties). In other words, you don’t instantiate objects by yourself. It is done by the container, instead of doing new Foo(); manually. The general concepts of CDI are also adopted by other Java standards, such as EJB.

There are 2 steps to enable CDI:

  1. Specify where injectable objects are (and configure the container if not using default settings);
  2. Specify where to be injected.

Here is an example of injecting a repository class into a servlet class.

Step 1: Specify where injectable objects are

To specify your injectable object, in this case, your repository class, you need to make it a managed bean by specifying its scope.* There are several scopes for managed beans. They control the behaviors of the beans, such as life cycle, the numbers of instances, etc.
See the example code, you’ll notice the @RequestScoped annotation is placed on the class level.
* Explicitly put @default can also make a java class a managed bean.

Configuration Options

As mentioned, it’s possible to customize the bean configurations in order to change the detection scope of the container. It is an attribute in bean.xml file called bean-discovery-mode. You don’t need to create this file if you are using the default configuration, annotated. There are 2 other options: all and none.

  • annotated: all managed beans are looked up
  • all: all types (classes) are looked up
  • none: disable the look ups

Step 2: Specify where to be injected

To inject an object, you need to place the @inject annotation to the field, attribute etc.
See the example code, you’ll find that there is no manual instantiating needed anymore.

Lifecycle

Most CDI or EJB implementations manage those injectable objects or beans behind scene, e.g. pooling, passivation, activation (Stateful Session Bean), listening (Message-Driven Bean). Therefore, it is not common to manage lifecycle events in constructors. There are 2 lifecycle events wildly used with both CDI and EJB: @PostConstruct and @PreDestroy.

  • @PostConstruct: invoked before the first call
  • @PreDestroy: invoked before leaving the scope

See UserRepository. Since the scope is within a request, right before the first call is made in line 122 in the LoginServlet, @PostConstruct annotated method in UserRepository is invoked, and @PreDestroy annotated method will be invoked after the request is sent back to a JSP and written to the client.
Code stub around line 122:

private String authUser(final String username, final String password) {
    final User dbUser = userRepository.findUser(username);
    ...
}
Follow the link to find more information about lifecycle of CDI and EJB.

Deal with Ambiguous Derivations

In the real world, it is very unlikely to inject the actual concrete classes with CDI. A problem then comes out with ambiguous derivations. If an interface is derived by many subclasses, you need to tell the container which one you want to use when injecting the object.
There are two ways of dealing with it:

  1. Use @Named annotation to give the type a CDI name
  2. Override @Default annotation

@Named

@Named annotation can be placed on the injectable type to give it a name value. At the injecting point, you just need to annotate @Named with the particular name. The following is an example:

/* the interface used at injecting point */
public interface Boo{}

/* named class to be injected */
@Named("Foo")
public class Doo implements Boo{}

public class Goo{

    /* a field to inject Doo */
    @Named("Foo")
    @Inject
    Boo doo;

    /* a method to inject Doo */
    @Inject
    public void setDoo(@Named("Foo") Boo doo){}
}

@Default

@Default is a default qualifier for any injectable type, which means this annotation will be implicitly applied to managed beans. For example, the UserRepository class in the above sections has @Default annotation implicitly. However, since all the derivations have the same qualifier, it will confuse the container when injecting an interface with multiple derivations. To specify a particular class to inject with, you can define a customized qualifier, then use it at the injecting point.*
* The linked project for explaining how qualifier works is different to the one used in the above sections.

This blog may not be up to date. Please see the original post from Blogger http://ift.tt/2dTFHmp
via IFTTT.

Advertisements

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